<?xml version="1.0"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>JBake</title>
    <link>https://tedneward.github.io/Research</link>
    <atom:link href="https://tedneward.github.io/Research/feed.xml" rel="self" type="application/rss+xml" />
    <description>JBake Bootstrap Template</description>
    <language>en-gb</language>
    <pubDate>Mon, 13 Apr 2026 14:06:08 +0000</pubDate>
    <lastBuildDate>Mon, 13 Apr 2026 14:06:08 +0000</lastBuildDate>

    <item>
      <title>Writing Tools</title>
      <link>https://tedneward.github.io/Research/writing/writing-tools/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">writing/writing-tools/index.html</guid>
      	<description>
	&lt;p&gt;&lt;em&gt;(by Roy Peter Clark)&lt;/em&gt;&lt;/p&gt; 
&lt;h3&gt;Part One: Nuts and Bolts&lt;/h3&gt; 
&lt;h4&gt;Tool 1: Begin sentences with subjects and verbs. Make meaning early, then let weaker elements branch to the right.&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;Subject and verb are often separated in prose, usually because we want to tell the reader something about the subject before we get to the verb. This delay, even for good reasons, risks confusing the reader.&lt;/li&gt; 
 &lt;li&gt;To create suspense, or build tension, or make the reader wait and wonder, or join a journey of discovery, or hold on for dear life, he can save subject and verb of the main clause until later.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Tool 2: Order words for emphasis. Place strong words at the beginning and at the end.&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;The period acts as a stop sign. That slight pause in reading magnifies the final word, an effect intensified at the end of a paragraph, where final words often adjoin white space.&lt;/li&gt; 
 &lt;li&gt;Putting strong stuff at the beginning and end helps writers hide weaker stuff in the middle.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Tool 3: Activate your verbs. Strong verbs create action, save words, and reveal the players.&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;Verbs are either active, passive, or a linking verb, which is a form of the verb &lt;em&gt;to be&lt;/em&gt;.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Tool 4: Be passive-aggressive. Use passive verbs to showcase the “victim” of action.&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;A strong active verb can add dimension to the cloud created by some uses of the verb to be, such as replacing &quot;there were leaves all over the ground&quot; with &quot;leaves cover the ground.&quot;&lt;/li&gt; 
 &lt;li&gt;Active verbs move the action and reveal the actors. Passive verbs emphasize the receiver, the victim. The verb &lt;em&gt;to be&lt;/em&gt; links word and ideas.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Tool 5: Watch those adverbs. Use them to change the meaning of the verb.&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;At their best, adverbs spice up a verb or adjective. At their worst, they express a meaning already contained in it.&lt;/li&gt; 
 &lt;li&gt;A bad adverb is repetitive: &quot;She smiled happily.&quot; A good adverb can change the meaning: &quot;She smiled sadly.&quot;&lt;/li&gt; 
 &lt;li&gt;Look for weak verb-adverb combinations that you can revise with stronger verbs.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Tool 6: Take it easy on the -ings. Prefer the simple present or past.&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;Add -ing to a verb, and it takes on a progressive sense, or a happening.&lt;/li&gt; 
 &lt;li&gt;&quot;Wish and hope and think and pray&quot; is stronger than &quot;Wishing and hoping and thinking and praying.&quot;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Tool 7: Fear not the long sentence. Take the reader on a journey of language and meaning.&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;While length makes a bad sentence worse, it can make a good sentence better.&lt;/li&gt; 
 &lt;li&gt;Some strategies to achieve mastery of the long sentence: It helps if subject and verb of the main clause come early in the sentence. Use the long sentence to describe something long. Let form follow function. It helps if the long sentence is written in chronological order. Use the long sentence in variation with sentences of short and medium length.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Tool 8: Establish a pattern, then give it a twist. Build parallel constructions, but cut across the grain.&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;If two or more ideas are parallel, they are easier to grasp when expressed in parallel grammatical form. Single words should be balanced with single words, phrases with phrases, clauses with clauses.&lt;/li&gt; 
 &lt;li&gt;A pure parallel construction would be &quot;Boom, boom, boom.&quot; Parallelism with a twist gives us &quot;Boom, boom, bang,&quot; like &quot;hither, thither, and yon,&quot; &quot;Peter, Paul, and Mary,&quot; or &quot;sex, drugs, and rock n roll.&quot;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Tool 9: Let punctuation control pace and space. Learn the rules, but realize you have more options than you think.&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;A well-placed comma points to where the writer would pause if he read the passage aloud.&lt;/li&gt; 
 &lt;li&gt;More muscular than the comma, the semicolon is most useful for dividing and organizing big chunks of information.&lt;/li&gt; 
 &lt;li&gt;The dash has become the default mark for writers who never mastered the formal rules. But the dash has two brilliant uses: a pair of dashes can set off an idea contained within a sentence, and a dash near the end can deliver a punch line.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Tool 10: Cut big, then small. Prune the big limbs, then shake out the dead leaves.&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;Brevity comes from selection, not compression, a lesson that requires lifting blocks from the work.&lt;/li&gt; 
 &lt;li&gt;Cut any passage that does not support your focus. Don&apos;t invite others to cut. You know the work better. Mark optional trims. Then decide whether they should become actual cuts.&lt;/li&gt; 
 &lt;li&gt;Targets for cuts include: Adverbs that intensify rather than modify, prepositional phrases that repeat the obvious, phrases that grow on verbs, abstract nouns that hide active verbs, and restatements.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Part Two: Special Effects&lt;/h3&gt; 
&lt;h4&gt;Tool 11: Prefer the simple over the technical. Use shorter words, sentences, and paragraphs at points of complexity.&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;Familiarization takes the strange or opaque or complex and, through the power of explanation, makes it comprehensible, even familiar.&lt;/li&gt; 
 &lt;li&gt;Readers benefit from shorter words and phrases, and simpler sentences, at the points of greatest complexity.&lt;/li&gt; 
 &lt;li&gt;Clear prose is not just a product of sentence length and word choice. It derives first from a sense of purpose -- a determination to inform.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Tool 12: Give key words their space. Do not repeat a distinctive word unless you intend a specific effect.&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;Repeat words or phrases for emphasis or rhythm.&lt;/li&gt; 
 &lt;li&gt;Some words act as building blocks and can be repeated to good effect, while distinctive words deserve their own space.&lt;/li&gt; 
 &lt;li&gt;Leave &lt;em&gt;said&lt;/em&gt; alone. Don&apos;t be tempted by the muse of variation to permit characters to opine, elaborate, cajole, or chortle.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Tool 13: Play with words, even in serious stories. Choose words the average writer avoids but the average reader understands.&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;Too often, writers suppress their vocabularies in a misguided attempt to lower the level of language for a general audience.&lt;/li&gt; 
 &lt;li&gt;A rich writing vocabulary does not require big or fancy words.&lt;/li&gt; 
 &lt;li&gt;All of us possess a reading vocabulary as big as a lake but draw from a writing vocabulary as small as a pond.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Tool 14: Get the name of the dog. Dig for the concrete and specific, details that appeal to the senses.&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;When details of character and setting appeal to the senses, they create an experience for the reader that leads to understanding.&lt;/li&gt; 
 &lt;li&gt;The good writer uses telling details not only to inform, but to persuade.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Tool 15: Pay attention to names. Interesting names attract the writer— and the reader.&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;The best reporters recognize and take advantage of coincidence between name and circumstance.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Tool 16: Seek original images. Reject clichés and first-level creativity.&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;Using metaphors, similes, or other figures of speech which you are used to seeing in print is a substitute for thinking, a form of automatic writing.&lt;/li&gt; 
 &lt;li&gt;If brianstorming does not lead you to an inspired image, write it straight.&lt;/li&gt; 
 &lt;li&gt;Worse than clichés of language are &quot;clichés of vision,&quot; or the narrow frames through which writers learn to see the world. E.g. victims are innocent, politicians are corrupt, and it&apos;s lonely at the top.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Tool 17: Riff on the creative language of others. Make word lists, free-associate, be surprised by language.&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;Writers collect sharp phrases and colorful metaphors, sometimes for their conversations and sometimes for their prose, but this risks plagiarism.&lt;/li&gt; 
 &lt;li&gt;The notion that new knowledge derives from old wisdom should liberate the writer from a scrupulous fear of snatching the words of others.&lt;/li&gt; 
 &lt;li&gt;Always take credit for good writing you did not intend because you&apos;ll be getting plenty of criticism for bad writing you did not mean either.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Tool 18: Set the pace with sentence length. Vary sentences to influence the reader&apos;s speed.&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;Long sentences create a flow that carries the reader down a stream of understanding, creating an effect called &quot;steady advance.&quot; Short ones slam on the brakes.&lt;/li&gt; 
 &lt;li&gt;Writers slow the pace of a story for three reasons: To simplify the complex, to create suspense, and to focus on the emotional truth.&lt;/li&gt; 
 &lt;li&gt;Radical clarity eases the reader into a story with short sentences and paragraphs, where the stopping points give the reader time and space to comprehend, but there is enough variation to imitate the patterns of normal conversation.&lt;/li&gt; 
 &lt;li&gt;Short sentences can achieve not only clarity, but also suspense and emotional power. Some call this the &quot;Jesus wept&quot; effect.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Tool 19: Vary the lengths of paragraphs. Go short or long— or make a turn— to match your intent.&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;When the big parts fit, we call that good feeling coherence; when sentences connect, we call it cohesion.&lt;/li&gt; 
 &lt;li&gt;The paragraph is essentially a unit of thought, not of length. All sentences in a paragraph should be about the same thing and move in a sequence.&lt;/li&gt; 
 &lt;li&gt;While a writer can break a long paragraph into parts, they should not paste together paragraphs that are short and disconnected.&lt;/li&gt; 
 &lt;li&gt;A short paragraph, especially after a long one, to bring the reader to a sudden, dramatic stop.&lt;/li&gt; 
 &lt;li&gt;A solid, unified paragraph can take a turn in the middle, or demonstrate the logic of cause and effect.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Tool 20: Choose the number of elements with a purpose in mind. One, two, three, or four: each sends a secret message to the reader.&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;If a writer wants the reader to think something the absolute truth, the writer should render it in the shortest possible sentence.&lt;/li&gt; 
 &lt;li&gt;Telling two characteristics invites the reader to balance them, weigh them against each other, compare and contrast them.&lt;/li&gt; 
 &lt;li&gt;Three characteristics allows us to triangulate further characteristics, and provides a sense of the whole, such as &quot;beginning, middle, and end.&quot;&lt;/li&gt; 
 &lt;li&gt;Listing four characteristics can list and expand, but can also twist the wholeness of three: &quot;That girl is smart, sweet, determined, and neurotic.&quot;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Tool 21: Know when to back off and when to show off. When the topic is most serious, understate; when least serious, exaggerate.&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;If the subject is serious or dramatic, let the story tell itself. If the topic is playful or inconsequential, then the writer can show off.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Tool 22: Climb up and down the ladder of abstraction. Learn when to show, when to tell, and when to do both.&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;At the top of the ladder is general and abstract language; at the bottom is concrete evidence. Beware of the middle rungs.&lt;/li&gt; 
 &lt;li&gt;Metaphors and similes help us understand abstractions through comparison with concrete things, working both ends of the ladder.&lt;/li&gt; 
 &lt;li&gt;&quot;Can you give me an example?&quot; will drive the speaker down the ladder. But &quot;What does that mean?&quot; will carry him aloft.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Tool 23: Tune your voice. Read stories aloud.&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;Voice is the sum of all the strategies used by the author to create the illusion that the writer is speaking directly to the reader from the page. No effect is more important or elusive.&lt;/li&gt; 
 &lt;li&gt;Voice is influenced by: The level of language, the &quot;person&quot; or point of view, the range and source of allusions, the frequency of metaphors and figures of speech, sentence length and structure, degree of neutrality, and framing of material.&lt;/li&gt; 
 &lt;li&gt;To test your writing voice, read your story aloud to hear if it sounds like you. Do this to test what the deletion of an unnecessary phrase does to the rhythm of the sentence.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Part Three: Blueprints&lt;/h3&gt; 
&lt;h4&gt;Tool 24: Work from a plan. Index the big parts of your work.&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;Good work has parts, and the reader who sees the big parts is more likely to remember the whole story.&lt;/li&gt; 
 &lt;li&gt;If you cannot write the outline from a story, then you cannot discern the parts from the whole, and this is a problem of organization.&lt;/li&gt; 
 &lt;li&gt;An outline, or even subtitles, reveal a movement of theme, logic, and chronology that readers can perceive and remember.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Tool 25: Learn the difference between reports and stories. Use one to render information, the other to render experience.&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;Readers read for two reasons: information and experience. Reports convey information, stories create experience. Reports transfer knowledge, stories transport the reader. Reports point us there, stories put us there.&lt;/li&gt; 
 &lt;li&gt;Transforming information to a narrative, who becomes character, what becomes action, where becomes setting, when becomes chronology, why becomes cause or motive, and how becomes process.&lt;/li&gt; 
 &lt;li&gt;By combining story and report, the writer can speak to both our hearts and our heads, creating sympathy and understanding.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Tool 26: Use dialogue as a form of action. Dialogue advances narrative; quotes delay it.&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;In many ways dialogue defines a story because its power drags us to the scene and sets our ears to the action.&lt;/li&gt; 
 &lt;li&gt;A good quote introduces a human voice, explains something important, frames a problem or dilemma, adds information, reveals the character or personality of the speaker, and introduces what is next to come.&lt;/li&gt; 
 &lt;li&gt;Most quotes are displaced because they are spoken above or outside the action, and not in the action. But dialogue is not just heard, but overheard.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Tool 27: Reveal traits of character. Show character-istics through scenes, details, and dialogue.&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;Too often, writers turn abstractions into adjectives to define character. The reader who encounters character adjectives screams silently for examples, for evidence.&lt;/li&gt; 
 &lt;li&gt;The best writers create moving pictures of people, images that reveal their characteristics and aspirations, their hopes and fears.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Tool 28: Put odd and interesting things next to each other. Help the reader learn from contrast.&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;Ironic juxtaposition is the fancy term for what happens when two disparate things are placed side by side, each commenting on the other.&lt;/li&gt; 
 &lt;li&gt;Examples include valley girl meets demons (Buffy the Vampire Slayer), Hitler meets musical (The Producers), and murder meets Christmas (Holidays on Ice).&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Tool 29: Foreshadow dramatic events and powerful conclusions. Plant important clues early.&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;Playwright Anton Chekhov wrote &quot;One must not put a loaded rifle on the stage if no one is thinking of firing it,&quot; a foreshadowing device called &lt;em&gt;Chekhov&apos;s Gun&lt;/em&gt;.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Tool 30: To generate suspense, use internal cliffhangers. To propel readers, make them wait.&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;A cliffhanger creates suspsense, a word derived from the Latin suspendere, &quot;to hang under.&quot; Suspense leaves the reader, and sometimes a character, hanging.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Tool 31: Build your work around a key question. Stories need an engine, a question that the action answers for the reader.&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;The engine is the question the story answers for the reader. If the internal cliffhanger drives the reader from one section to the next, the engine moves the reader across the arc from beginning to end.&lt;/li&gt; 
 &lt;li&gt;Create a cast of characters for your stories by asking the question: Who has something at stake here? The answer can lead to the creation of a story engine.&lt;/li&gt; 
 &lt;li&gt;The premise of Othello is, &quot;Jealousy destroys itself and the object of its love.&quot; Its engine could be, &quot;Will Othello&apos;s jealousy destroy him and the woman he loves?&quot;&lt;/li&gt; 
 &lt;li&gt;The engine and its themes are distinct. &quot;What is Rosebud?&quot; is the engine of Citizen Kane, but its themes explore politics, democracy, and America.&lt;/li&gt; 
 &lt;li&gt;Some stories are driven not by what questions, but by how. For example, we know that Bond will conquer the villians and get the girl, but we are driven to know how.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Tool 32: Place gold coins along the path. Reward the reader with high points, especially in the middle.&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;A good start is its own reward, and crafty writers know enough to put something shiny at the end, a final reward. But put gold coins in the middle to reward the reader, and for motivation.&lt;/li&gt; 
 &lt;li&gt;A gold coin can appear as a small scene or anecdote, a startling fact, or a telling quote.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Tool 33: Repeat, repeat, and repeat. Purposeful repetition links the parts.&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;Repeating key words, phrases, and story elements creates a rhythm, a pace, a structure, a wavelength that reinforces the central theme of the work.&lt;/li&gt; 
 &lt;li&gt;If you&apos;re worried about too much repetition, delete all the repetition and read the passage aloud without it. Repeat the key element once. Repeat it again. Your voice and ear will let you know when you&apos;ve gone too far.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Tool 34: Write from different cinematic angles. Turn your notebook into a camera.&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;An establishing shot captures the setting in which action takes place, describing the world that the reader is about to enter, sometimes creating a mood.&lt;/li&gt; 
 &lt;li&gt;A middle distance shot is closer to the action, close enough to see the key players and their interaction.&lt;/li&gt; 
 &lt;li&gt;A close-up shot gets in the face of the subject, close enough to detect anger, fear, dread, sorrow, irony, the full range of emotions.&lt;/li&gt; 
 &lt;li&gt;An extreme close-up shot focuses on an important detail that would be invisible from a distance.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Tool 35: Report and write for scenes. Then align them in a meaningful sequence.&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;Tom Wolfe argues that realism is built on &quot;scene-by-scene construction, telling the story by moving from scene to scene and resorting as little as possible to sheer historical narrative.&quot;&lt;/li&gt; 
 &lt;li&gt;Scenes can be witnessed or, in fiction, invented, but they can also be remembered.&lt;/li&gt; 
 &lt;li&gt;Scenes can be arranged in space as well as in time, can be used to balance parallel narrative lines, shifting from the perspective of the criminal to the cop, and can flash back in time, or look ahead.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Tool 36: Mix narrative modes. Combine story forms using the broken line.&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;A movement between narrative and analysis both instructs and delights the reader.&lt;/li&gt; 
 &lt;li&gt;Any story that begins without the news requires a phrase, a sentence, a paragraph, a zone that answers the question &quot;So what?&quot;&lt;/li&gt; 
 &lt;li&gt;With the broken line form, the writer can begin with narrative and move to explanation, or begin with straight information and then illustrate the facts with an anecdote.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Tool 37: In short works, don’t waste a syllable. Shape short writing with wit and polish.&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;The author of a great big novel will waste a syllable, but in an ocean of words the reader will not notice. But the shorter the story form, the more precious is each word.&lt;/li&gt; 
 &lt;li&gt;Brevity gives short works a focused power; it creates opportunity for wit; and it inspires the writer to polish, to reveal the luster of the language.&lt;/li&gt; 
 &lt;li&gt;Longer works can contain powerful, witty, and polished shorter elements: anecdotes, scenes, descriptions, vignettes, set pieces that can be lifted out of the work for inspection and delight.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Tool 38: Prefer archetypes to stereotypes. Use subtle symbols, not crashing cymbals.&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;Good writers can be original by standing on a foundation of narrative archetypes, a set of story expectations that can be manipulated, frustrated, or fulfilled in novel ways on behalf of the reader.&lt;/li&gt; 
 &lt;li&gt;Examples include: the journey there and back, winning the prize, winning or losing the loved one, loss and restoration, the blessing becomes the curse, overcoming obstacles, the wasteland restored, rising from the ashes, the ugly duckling, the emperor has no clothes, and descent into the underworld.&lt;/li&gt; 
 &lt;li&gt;When it comes to powerful writing, a symbol need not be a cymbal. Subtlety is a writer’s virtue.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Tool 39: Write toward an ending. Help readers close the circle of meaning.&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;In written compositions, the author can build to a cresendo, fade out, stop short, echo the opening, close the circle, tieback to the body, tell what happens last in time or space, reveal a secret or solve a mystery, show an epilogue, offer solutions to a problem, use an apt quote, look to the future, or mobilize the reader.&lt;/li&gt; 
 &lt;li&gt;Remember that other parts of your story, like sentences and paragraphs, need endings too. Each of these mini-endings anticipates your finale.&lt;/li&gt; 
 &lt;li&gt;Don’t bury your ending. Put your hand over the last paragraph, and ask yourself &quot;What would happen if this ended here?&quot; Move it up another paragraph and repeat the question until you find the natural stopping place.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Part Four: Useful Habits&lt;/h3&gt; 
&lt;h4&gt;Tool 40: Draft a mission statement for your work. To sharpen your learning, write about your writing.&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;Good writers turn stories into workshops, intense moments of learning in which they advance their craft.&lt;/li&gt; 
 &lt;li&gt;Writing down your mission, covering both content and format, turns your vague hopes into language. By writing about your writing, you learn what you need to learn.&lt;/li&gt; 
 &lt;li&gt;Such mission statements are an expression of purpose, which show up in introductions or epilogues.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Tool 41: Turn procrastination into rehearsal. Plan and write it first in your head.&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;To write with your hands, you must write in your head. Treat each act of procrastination as a time of mental planning and preparation.&lt;/li&gt; 
 &lt;li&gt;Eliminate writers block by lowering your standards until there is no felt threshold to go over in writing. Nothing is more liberating than no standards.&lt;/li&gt; 
 &lt;li&gt;Other strategies for eliminating procrastination: Let your fingers do the writing and not your brain, adopt a daily routine, build in rewards, write earlier to discover the information you need instead of over-researching, discount nothing, rewrite, eliminate negative words from your vocabulary, dispose of distracting tasks, find someone who praises productivity and effort, and keep a daybook for fleeting ideas.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Tool 42: Do your homework well in advance. Prepare yourself for the expected— and unexpected.&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;Good writers fill a reservoir of knowledge they can drain at a moment’s notice. As Hamlet said, &quot;the readiness is all.&quot;&lt;/li&gt; 
 &lt;li&gt;Homework should answer what the point is, why this story is being told, and what it says about life, about the world, about the times we live in.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Tool 43: Read for both form and content. Examine the machinery beneath the text.&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;Reading other works for content and form informs you of what you&apos;re trying to build, and what tools you need to build it.&lt;/li&gt; 
 &lt;li&gt;When you can&apos;t put a story down, put it down and think about what magic propels you from paragraph to paragraph, page to page, chapter to chapter.&lt;/li&gt; 
 &lt;li&gt;Pay attention to the voice of the writer, undeveloped story ideas, and new storytelling forms. Read bits of books for taste, books directed by your writing compass, books on topics outside your discipline, and read with a pen nearby.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Tool 44: Save string. For big projects, save scraps others would toss.&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;Use a simple file box to save items, anecdotes, and statistics about a topic. It will fill up without effort, creating a literary life cycle: planting, cultivation, and harvesting.&lt;/li&gt; 
 &lt;li&gt;Grow several crops at a time, fertilizing one even as you harvest another.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Tool 45: Break long projects into parts. Then assemble the pieces into something whole.&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;At the front end, book projects seem impossible to get your arms around. Break long projects into parts, long stories into chapters, long chapters into episodes to make the task of writing a book tractable.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Tool 46: Take an interest in all crafts that support your work. To do your best, help others do their best.&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;If your story is well edited, accompanied by a powerful photograph, on a page that is well designed, it will look more important and more people will read it.&lt;/li&gt; 
 &lt;li&gt;Take an interest in all of the associated literary crafts, like copyediting, photography, and design, and make nice with people who come forth to help you.&lt;/li&gt; 
 &lt;li&gt;Think of copyeditors as champions of standards, invaluable test readers, your last line of defense.&lt;/li&gt; 
 &lt;li&gt;Learn to meet your deadlines to give others time to do their jobs. Even if you lack the authority to convene conversations, encourage early planning that includes all key players.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Tool 47: Recruit your own support group. Create a corps of helpers for feedback.&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;Work on developing the support system you need and deserve, including a cheerleader, an disinterested reader willing to answer your questions, expert helper who matches your topic, and a coach who helps you figure out what needs work.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Tool 48: Limit self-criticism in early drafts. Turn it loose during revision.&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;To become a fluent writer, one must silence the internal critic early until enough work has been done to warrant evaluation and revision.&lt;/li&gt; 
 &lt;li&gt;Pretend to write for a friend pleading, &quot;Tell me more. Tell me all you can. I want to understand more about everything you feel and know and all the changes inside and out of you. Let more come out.&quot;&lt;/li&gt; 
 &lt;li&gt;But during revision, the self-conscious application of all writing advice will turn you to stone if you try to do it too early, or if you misapply it as orthodoxy.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Tool 49: Learn from your critics. Tolerate even unreasonable criticism.&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;Don&apos;t fall into the trap of arguing about matters of taste or defending your work against negative criticism. Explain to your critic what you were trying to do, thereby transforming arguments into conversations.&lt;/li&gt; 
 &lt;li&gt;Even when an attack is personal, in your mind deflect it back onto the work.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Tool 50: Own the tools of your craft. Build a writing workbench to store your tools.&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;Sniff around for news, then explore ideas, collect evidence, find a focus, select the best material, recognize an order, write a draft, and finally revise and clarify.&lt;/li&gt; 
 &lt;li&gt;The focus of a story can be expressed in a title, a first sentence, a summary paragraph, a theme statement, a thesis, a question the story will answer for the reader, one perfect word.&lt;/li&gt; 
 &lt;li&gt;Don&apos;t dump all your research into a story or essay. Use a sharp focus to cut tempting material that does not contribute to the central meaning of the work.&lt;/li&gt; 
 &lt;li&gt;Such a blueprint for writing not only demystifies the process, but will help you diagnose problems, account for your strengths and weaknesses, and build a critical vocabulary for talking about your craft.&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>The Book on Writing</title>
      <link>https://tedneward.github.io/Research/writing/the-book-on-writing/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">writing/the-book-on-writing/index.html</guid>
      	<description>
	&lt;p&gt;&lt;em&gt;(by Paula LaRocque)&lt;/em&gt;&lt;/p&gt; 
&lt;h3&gt;Section One: Writing Mechanics&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;Accuracy aside, simplicity, clarity, and brevity are the most important criteria for all writing. They form the bedrock of all good communication, and have for time immemorial.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Chapter 1: Keep Sentences Short, Varied, and to One Main Idea&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;Vary sentence length to avoid tedium, but a safe average is probably around 20 words, with longish sentences reaching around 25.&lt;/li&gt; 
 &lt;li&gt;Precede and follow a long or &quot;difficult&quot; sentence with short and crisp sentences. This gives the reader rest and adds variety like in natural speech.&lt;/li&gt; 
 &lt;li&gt;The average sentence length, grade level, and Flesch Reading Ease score of your writing could be the difference between readability and unreadability.&lt;/li&gt; 
 &lt;li&gt;Clarifying a subject-verb-object relationship is one way to rewrite a badly written passage.&lt;/li&gt; 
 &lt;li&gt;For clear and readable lists, get the subject and verb out of the way early, and keep list items parallel, where the first word of each list item begins with the same part of speech.&lt;/li&gt; 
 &lt;li&gt;A list fails when it begins a paragraph, hanging in a vacuum. Preface it with a sentence or fragment that sets it up.&lt;/li&gt; 
 &lt;li&gt;Keep to one idea per sentence. You can use simple main idea-subordinate-idea sentences, as long as both ideas together don&apos;t result in an unmanageable sentence.&lt;/li&gt; 
 &lt;li&gt;In technical writing, there&apos;s probably no reason to stretch sentence length beyond what bulleted lists can handle.&lt;/li&gt; 
 &lt;li&gt;Some long sentences that work well introduce a single idea first and then only expand upon it.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Chapter 2: Avoid Pretensions, Gobbledygook, and Euphemisms&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;Most educated Americans prefer to read at or below the 10th grade level, and an appropriate Flesch Reading Ease Index score for most writing is 60 or 70.&lt;/li&gt; 
 &lt;li&gt;There&apos;s nothing intelligent about pretentious and abstract writing. One hallmark of intellect is the ability to make the complex easy to understand; anyone can be unclear.&lt;/li&gt; 
 &lt;li&gt;The wasted time and effort as well as the cost of mistakes and misunderstanding make fuzzy writing an expensive habit wherever it flourishes.&lt;/li&gt; 
 &lt;li&gt;Euphamisms at best amuse and at worst alienate. They don&apos;t soften language, but make the reader suspicious. Simple words seem more sincere and soften best.&lt;/li&gt; 
 &lt;li&gt;A long word is the right word if it&apos;s the best word.&lt;/li&gt; 
 &lt;li&gt;Say what something is not is misleading; say what it is.&lt;/li&gt; 
 &lt;li&gt;Stop trying to impress and try instead to communicate, thereby using concrete and not abstract phrasing, and disabusing ourselves of the notion that big words sound more intelligent, more professional, and more serious.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Chapter 3: Change Long and Difficult Words to Short and Simple Words&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;Many of our most ancient words are one-syllable utterances. Such words tend to be concrete and emotive.&lt;/li&gt; 
 &lt;li&gt;The clearest, most stirring writers and speakers depend upon plain, short words. Such words usually don&apos;t go to war with each other; they have a nice mesh.&lt;/li&gt; 
 &lt;li&gt;The clarity that comes with honest, basic expression benefits all writing. Utter simplicity offers the bedrock of authenticity.&lt;/li&gt; 
 &lt;li&gt;The more words we know, the surer and freer we are to choose the plainest, simplest, and right words.&lt;/li&gt; 
 &lt;li&gt;Use complex words when they&apos;re the best choice for the context. But whenever we have a choice, we choose the shortest words.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Chapter 4: Be Wary of Jargon, Fad, and Cliché&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;Good jargon is a specialized term for a similarly specialized audience. The challenge for the communicator is translating jargon into plain English for a lay audience.&lt;/li&gt; 
 &lt;li&gt;Good jargon sets forth the complex in economical, albeit specialized, language. Bad jargon sets forth the simple in bloated language.&lt;/li&gt; 
 &lt;li&gt;Wrapped in jargon, inanities can actually sound smart, which is always hurtful to good communication and a sham.&lt;/li&gt; 
 &lt;li&gt;The problem with language fad and cliché is such expression grows flat, predictable, and dull over time. Mimicry is the antithesis of freshness and originality.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Chapter 5: Use the Right Word&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;How we use words matters if only because we may be judged ignorant (by some) for what they consider a misuse.&lt;/li&gt; 
 &lt;li&gt;Avoid &lt;em&gt;alright&lt;/em&gt; and &lt;em&gt;alot&lt;/em&gt;, and use &lt;em&gt;all right&lt;/em&gt; and &lt;em&gt;a lot&lt;/em&gt; instead. &lt;em&gt;Awhile&lt;/em&gt; is an adverb, while &lt;em&gt;a while&lt;/em&gt; is a noun.&lt;/li&gt; 
 &lt;li&gt;&quot;The whole &lt;em&gt;comprises&lt;/em&gt; the parts.&quot; Avoid &lt;em&gt;comprise of&lt;/em&gt;; instead use &lt;em&gt;consist of&lt;/em&gt;, like &quot;The whole &lt;em&gt;consists of&lt;/em&gt; the parts.&quot; But &quot;The parts &lt;em&gt;constitute&lt;/em&gt; the whole.&quot;&lt;/li&gt; 
 &lt;li&gt;&lt;em&gt;Forthcoming&lt;/em&gt; means available or ready when needed, while &lt;em&gt;forthright&lt;/em&gt; means candid, direct, and straightforward.&lt;/li&gt; 
 &lt;li&gt;&lt;em&gt;Prerequisite&lt;/em&gt; is a requirement or precondition, while &lt;em&gt;perquisite&lt;/em&gt; is a benefit beyond one&apos;s salary, or perk.&lt;/li&gt; 
 &lt;li&gt;&lt;em&gt;Prescribe&lt;/em&gt; means to order, direct, or mandate, while &lt;em&gt;proscribe&lt;/em&gt; means to prohibit.&lt;/li&gt; 
 &lt;li&gt;&lt;em&gt;Refute&lt;/em&gt; means to disprove with conclusive evidence, while &lt;em&gt;rebut&lt;/em&gt; means to deny or dispute, but doesn&apos;t imply any evidence.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Chapter 6: Avoid Beginning With Long Dependent Phrases&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;When a sentence begins with a preposition, verb, verbal, or with certain conjunctions and adverbs, it begins with a dependent phrase rather than the subject, thereby delaying its point.&lt;/li&gt; 
 &lt;li&gt;Such sentences aren&apos;t caught because no one reads the &quot;backing-in&quot; phrases; our eyes skip ahead to the subject.&lt;/li&gt; 
 &lt;li&gt;Backing into the first sentence of a piece is not attractive, but doing so later for transition and variety in sentence structure is sensible as long as the resulting sentence is clear.&lt;/li&gt; 
 &lt;li&gt;To fix a backed-into beginning, simply start the sentence with the subject.&lt;/li&gt; 
 &lt;li&gt;Especially avoid beginning a structure with a long, unanchored list. Instead, place the list after the subject, clarifying their relationship.&lt;/li&gt; 
 &lt;li&gt;The worst fault of backing-in sentences is that they hide the subject. Readers learn some corollary thing about the subject before they even know what that subject is.&lt;/li&gt; 
 &lt;li&gt;If a sentence backs-in to something or someone unknown, the reader is bewildered instead of interested.&lt;/li&gt; 
 &lt;li&gt;Only back-in when we&apos;ve considered the alternatives, we know what we&apos;re doing and why, we have specific stylistic purposes that the backing-in structure satisfies.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Chapter 7: Prefer Active Verbs and the Active Voice&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;Just because a sentence has an auxiliary verb or a &quot;be&quot; verb does not mean that it is passive.&lt;/li&gt; 
 &lt;li&gt;The passive voice may be more effective than the active voice when the actor is irrelevant or gets in the way of the main point.&lt;/li&gt; 
 &lt;li&gt;Sometimes replacing a handful of weaker words with a single, strong verb leads to the active voice.&lt;/li&gt; 
 &lt;li&gt;Writing in active voice is clearer, more vigorous, and shorter than writing in the passive voice.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Chapter 8: Cut Wordiness&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;While a conversational style contributes to good writing, it is also wordy.&lt;/li&gt; 
 &lt;li&gt;Cutting prepositional phrases tightens writing. For example, replace &lt;em&gt;in regard to&lt;/em&gt; with &lt;em&gt;about&lt;/em&gt;, &lt;em&gt;in the event that&lt;/em&gt; with &lt;em&gt;if&lt;/em&gt;, &lt;em&gt;were in agreement&lt;/em&gt; with &lt;em&gt;agreed&lt;/em&gt;, and so on.&lt;/li&gt; 
 &lt;li&gt;Sentences that begin with &lt;em&gt;it&lt;/em&gt; and &lt;em&gt;there&lt;/em&gt; constructions are often wordy, and these constructions can be omitted.&lt;/li&gt; 
 &lt;li&gt;Imprecise or unnecessary adverbs and qualifiers also can lead to wordiness, such as using &lt;em&gt;moved quickly&lt;/em&gt; instead of &lt;em&gt;rushed&lt;/em&gt; or &lt;em&gt;hurried&lt;/em&gt;.&lt;/li&gt; 
 &lt;li&gt;Phrases like &quot;many,&quot; &quot;most,&quot; and &quot;what many described as&quot; do not add specificity and can be omitted. Likewise, omit words that specify the obvious.&lt;/li&gt; 
 &lt;li&gt;Pointless verb strings and unnecessary passives, or any handful of words instead of one active verb, can also lead to wordiness.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Chapter 9: Avoid Vague Qualifiers&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;The word &lt;em&gt;very&lt;/em&gt; and its siblings like &lt;em&gt;extremely&lt;/em&gt;, &lt;em&gt;totally&lt;/em&gt;, &lt;em&gt;completely&lt;/em&gt;, &lt;em&gt;entirely&lt;/em&gt;, &lt;em&gt;really&lt;/em&gt;, &lt;em&gt;quite&lt;/em&gt;, &lt;em&gt;rather&lt;/em&gt;, &lt;em&gt;somewhat&lt;/em&gt;, and &lt;em&gt;fairly&lt;/em&gt; help us get closer to our meaning when we can&apos;t think of the perfect word.&lt;/li&gt; 
 &lt;li&gt;If a word with a vague qualifier is really just fine standing alone, then the qualifier should be removed. The word left standing alone becomes stronger and more assertive.&lt;/li&gt; 
 &lt;li&gt;Words like &lt;em&gt;dead&lt;/em&gt;, &lt;em&gt;alive&lt;/em&gt;, and &lt;em&gt;unique&lt;/em&gt; have no degrees of meaning, like &lt;em&gt;pregnant&lt;/em&gt;, and should not be qualified.&lt;/li&gt; 
 &lt;li&gt;Sometimes intensifiers such as very are simply inflationary, or a way of exclaiming rather than explaining. Prefer the latter, adding vital and concrete information.&lt;/li&gt; 
 &lt;li&gt;A good test for whether we have the right word is whether it can stand alone. If it can&apos;t, then find a replacement.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Chapter 10: Prune Prepositions&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;A sentence generally can bear three prepositional phrases, but it breaks down rapidly if more are added after that, yielding an annoying singsong.&lt;/li&gt; 
 &lt;li&gt;Some prepositional phrases can be rendered adjective-plus-noun. For example, &lt;em&gt;members of the faculty&lt;/em&gt; becomes &lt;em&gt;faculty members&lt;/em&gt;.&lt;/li&gt; 
 &lt;li&gt;If trimming prepositions sacrifices incidental information, it can easily be placed in subsequent sentences.&lt;/li&gt; 
 &lt;li&gt;Even when excessive prepositional phrases don’t damage clarity, they damage flow.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Chapter 11: Limit Number and Symbol&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;Limit to three the numbers in a sentence if the reader must compare, contrast, or calculate with those numbers.&lt;/li&gt; 
 &lt;li&gt;Numbers are even more confusing when they have different forms like percentages, fractions, written out, numerals, etc.&lt;/li&gt; 
 &lt;li&gt;Symbols like dollar signs, decimals, percentage symbols, acronyms, or abbreviations are also visually uninviting.&lt;/li&gt; 
 &lt;li&gt;Graphic explanation like bulleted lists, tabulated material, charts, and white space is both clearer and more attractive than prose with numbers and symbols.&lt;/li&gt; 
 &lt;li&gt;Two exceptions to the three-number guideline include dates, and when each number in a consecutive run has the same form and identifies the same thing.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Chapter 12: Get Right to the Point. And Stay There.&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;If a story is inherently dramatic, tell it simply and swiftly. A florid style or rhetorical devices such as repetition can seem melodramatic, and may even trivialize the tragic or poignant.&lt;/li&gt; 
 &lt;li&gt;An opening anecdote should be short and pertinent. It should reveal something important about the story&apos;s theme and thus open a way in to the story, instead of getting in its way.&lt;/li&gt; 
 &lt;li&gt;Be wary of frustrating the reader with unanswered questions, instead of creating in him or her a healthy sense of curiosity.&lt;/li&gt; 
 &lt;li&gt;Failure to get right to the point and stay there is a chief cause of reader annoyance, whether from overwriting and wordiness, an ill-advised anecdote, or a dithering, vague style.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Section Two: Storytelling Devices&lt;/h3&gt; 
&lt;h4&gt;Chapter 20: Write Fast, Edit Slow&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;We cannot forgive slow, because fast is interesting and slow is dull. Slow makes us wait for the &lt;em&gt;first&lt;/em&gt; shoe to drop.&lt;/li&gt; 
 &lt;li&gt;Reading aloud forces us to listen, helping us locate the slow parts that interfere with the reader&apos;s progress, or stifle a speedy and seamless flow of writing.&lt;/li&gt; 
 &lt;li&gt;Such speedbumps include errors in content or form, distractions like awkward phrasing, the wrong word, and dense, wordy, fuzzy, repetitive, tentative, or extraneous passages.&lt;/li&gt; 
 &lt;li&gt;Proper research, finding a focus or theme, dividing your work into pieces, devising a beginning, middle, and end, and making an outline can help you write fast-moving prose.&lt;/li&gt; 
 &lt;li&gt;Most serious pace problems come from lack of focus and direction. Write a sentence that captures the essence of a section or chapter, and use it as a roadmap.&lt;/li&gt; 
 &lt;li&gt;One of the best way to &quot;remove all things that are not the story&quot; is to keep them out of the story in the first place. Fast writing helps keep extraneous material out.&lt;/li&gt; 
 &lt;li&gt;Don&apos;t edit as you write, or you&apos;ll lose momentum. You can edit slowly, because writing problems won&apos;t disappear as inspiration and spontaneity do.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Chapter 21: Speedbumps&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;Mistakes, failing to get to the point or present material logically, excessive length, obtrusive or tangential material, bad diction, and packing too much into sentences can lead to slow reading.&lt;/li&gt; 
 &lt;li&gt;The worst place to find speedbumps is at the beginning of the trip. Slow starts lose many readers, and clumsily executed anecdotal beginnings are among the worst offenders.&lt;/li&gt; 
 &lt;li&gt;Multiple anecdotes at the beginning is confusing because the readers is left guessing what the story is about. Get them over with quickly or have them follow the main point.&lt;/li&gt; 
 &lt;li&gt;Also mind not having a point, or failing to express that point briefly and clearly, or interrupting the work on the way to the point.&lt;/li&gt; 
 &lt;li&gt;Subjects and verbs should be close together, as should verbs and objects.&lt;/li&gt; 
 &lt;li&gt;Who, what, when, where, and why can wait if they’re going to get in the way of the message. Such information is not as important as writing well.&lt;/li&gt; 
 &lt;li&gt;Writing entails organizing into families of related thought, but one-sentence-per-paragraph writing orphans every sentence. And each has the same weight, so the thesis is not clear.&lt;/li&gt; 
 &lt;li&gt;Parenthetical or bracketed material is a major intrusion when striving for a conversational, story-telling style.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Chapter 22: Logic and Speedy Reading&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;The writer and reader must proceed in lockstep. If the writer is slower than the reader, the reader gets impatient. If the writer gets ahead, readers may get lost.&lt;/li&gt; 
 &lt;li&gt;Before embroidery comes the fabric, and the fabric of good writing is the tightly woven stuff of accuracy, clarity, brevity, precision, and logic.&lt;/li&gt; 
 &lt;li&gt;Illogic and loose connections can drive readers away and damage the writer&apos;s credibility.&lt;/li&gt; 
 &lt;li&gt;The essence of illogic is the non sequitur, which is an inference or conclusion that does not follow from the premise, such as in an if-then sentence.&lt;/li&gt; 
 &lt;li&gt;Non sequiturs also arise from a comment following an unrelated comment, and even conjoining the two with &lt;em&gt;but&lt;/em&gt;.&lt;/li&gt; 
 &lt;li&gt;Trouble also arises from illogical word pairs, mishandled figurative expressions, and using arguably to introduce sweeping, illogical, and insupportable claims.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Section Three: A Handbook&lt;/h3&gt; 
&lt;h4&gt;Chapter 23: A Brief (But Not Necessarily Easy) Quiz&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;Use adjectives rather than adverbs with sense verbs or with linking verbs such as forms of the verb &lt;em&gt;to be&lt;/em&gt;, &lt;em&gt;seem&lt;/em&gt;, &lt;em&gt;appear&lt;/em&gt;, &lt;em&gt;become&lt;/em&gt;, etc. For example, &lt;em&gt;the food smells bad&lt;/em&gt;, but &lt;em&gt;she swam badly&lt;/em&gt;. But &lt;em&gt;bad&lt;/em&gt; describes condition or passive states, such as &lt;em&gt;he felt bad&lt;/em&gt;, where &lt;em&gt;bad&lt;/em&gt; modifies the subject &lt;em&gt;he&lt;/em&gt;.&lt;/li&gt; 
 &lt;li&gt;Only place a comma between adjectives if it could be replaced by &lt;em&gt;and&lt;/em&gt;. For example, &lt;em&gt;a beautiful baby girl&lt;/em&gt;, and &lt;em&gt;a large, ugly dog&lt;/em&gt; are both correct.&lt;/li&gt; 
 &lt;li&gt;Use possessive pronouns before gerunds, which are words that end in &quot;ing&quot; but act as nouns.&lt;/li&gt; 
 &lt;li&gt;&lt;em&gt;Like&lt;/em&gt; is not a conjunction; use it as a conjunction to compare nouns and pronouns. Use &lt;em&gt;as&lt;/em&gt;, &lt;em&gt;as if&lt;/em&gt;, or &lt;em&gt;as though&lt;/em&gt; to introduce clauses, or a group of words containing both subject and verb.&lt;/li&gt; 
 &lt;li&gt;When using the phrase &quot;one of those [nouns] who,&quot; the subject of the following verb is &lt;em&gt;who&lt;/em&gt; and not &lt;em&gt;one&lt;/em&gt;, and so the verb should adopt the plural and not the singular form.&lt;/li&gt; 
 &lt;li&gt;The word &lt;em&gt;as&lt;/em&gt; should not follow &lt;em&gt;equally&lt;/em&gt;, or verbs such as &lt;em&gt;named&lt;/em&gt;, &lt;em&gt;called&lt;/em&gt;, &lt;em&gt;elected&lt;/em&gt;, etc.&lt;/li&gt; 
 &lt;li&gt;Subjective pronouns are &lt;em&gt;I&lt;/em&gt;, &lt;em&gt;he&lt;/em&gt;, &lt;em&gt;she&lt;/em&gt;, &lt;em&gt;we&lt;/em&gt;, &lt;em&gt;they&lt;/em&gt;, or &lt;em&gt;who&lt;/em&gt;. Objective pronouns are &lt;em&gt;me&lt;/em&gt;, &lt;em&gt;him&lt;/em&gt;, &lt;em&gt;her&lt;/em&gt;, &lt;em&gt;us&lt;/em&gt;, &lt;em&gt;them&lt;/em&gt;, or &lt;em&gt;whom&lt;/em&gt;.&lt;/li&gt; 
 &lt;li&gt;&lt;em&gt;Myself&lt;/em&gt; is a &quot;self&quot; pronoun that differs because it is neither a subject nor object, but a reflexive like &lt;em&gt;I hurt myself&lt;/em&gt;, or an intensifier like &lt;em&gt;I myself am staying at home&lt;/em&gt;.&lt;/li&gt; 
 &lt;li&gt;Removing other people from the sentence and letting the pronoun stand alone, or replacing the pronoun with another one, quickly reveals whether it is a subject or object.&lt;/li&gt; 
 &lt;li&gt;If a pronoun is preceded by &lt;em&gt;than&lt;/em&gt;, and placing a verb after the pronoun makes grammatical sense, then choose the subjective form.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Chapter 24: Dispelling the Myths&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;The infinitive is &lt;em&gt;to&lt;/em&gt; plus a verb. The split infinitive separates the two, typically with an adverb, such as &lt;em&gt;to boldly go&lt;/em&gt;. They are often unattractive, but they are not wrong.&lt;/li&gt; 
 &lt;li&gt;Ending sentences with a preposition is fine, but omit the preposition if it is a gross redundancy, such as with &lt;em&gt;Where is it at?&lt;/em&gt;&lt;/li&gt; 
 &lt;li&gt;Avoid ambiguous contractions like &lt;em&gt;he&apos;d&lt;/em&gt;, &lt;em&gt;we&apos;d&lt;/em&gt;, and &lt;em&gt;I&apos;d&lt;/em&gt;. The first can mean either &lt;em&gt;he would&lt;/em&gt;, or &lt;em&gt;he had&lt;/em&gt;. Avoiding contractions also makes text more emphatic or stately.&lt;/li&gt; 
 &lt;li&gt;Omitting the serial comma may cause ambiguities, whereas including it never will.&lt;/li&gt; 
 &lt;li&gt;Regarding &lt;em&gt;none&lt;/em&gt;, if it clearly means &lt;em&gt;no one&lt;/em&gt; or &lt;em&gt;not one&lt;/em&gt;, it&apos;s singular. If the stress is on &lt;em&gt;not any&lt;/em&gt;, or is on more than one, or if the following noun cannot be construed as singular, treat &lt;em&gt;none&lt;/em&gt; as plural.&lt;/li&gt; 
 &lt;li&gt;If each person in a couple is acting individually, then &lt;em&gt;couple&lt;/em&gt; is plural. But if two people are acting as one, then it is singular.&lt;/li&gt; 
 &lt;li&gt;Collective nouns like &lt;em&gt;company&lt;/em&gt;, &lt;em&gt;team&lt;/em&gt;, and &lt;em&gt;committee&lt;/em&gt; refer to an &lt;em&gt;it&lt;/em&gt;, not a &lt;em&gt;they&lt;/em&gt;, which can be awkward. Adding a plural noun to the collective one, like &lt;em&gt;faculty members&lt;/em&gt;, can remedy this.&lt;/li&gt; 
 &lt;li&gt;Retain &lt;em&gt;that&lt;/em&gt; with sentences containing both attribution and time, and following words such as &lt;em&gt;announce&lt;/em&gt;, &lt;em&gt;believe&lt;/em&gt;, &lt;em&gt;thought&lt;/em&gt;, &lt;em&gt;reveal&lt;/em&gt;, &lt;em&gt;declare&lt;/em&gt;, &lt;em&gt;understand&lt;/em&gt;, &lt;em&gt;assert&lt;/em&gt;, &lt;em&gt;assume&lt;/em&gt;, &lt;em&gt;allege&lt;/em&gt;, and so on.&lt;/li&gt; 
 &lt;li&gt;Use &lt;em&gt;a&lt;/em&gt; before a consonant sound and &lt;em&gt;an&lt;/em&gt; before a vowel sound. And so &lt;em&gt;an NCAA policy&lt;/em&gt;, &lt;em&gt;a eulogy&lt;/em&gt;, &lt;em&gt;an herb&lt;/em&gt;, and &lt;em&gt;a herbicide&lt;/em&gt; are all correct.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Chapter 25: Style Guide&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;Use &lt;em&gt;a.m.&lt;/em&gt; and &lt;em&gt;p.m.&lt;/em&gt; instead of &lt;em&gt;AM&lt;/em&gt; and &lt;em&gt;PM&lt;/em&gt;.&lt;/li&gt; 
 &lt;li&gt;&lt;em&gt;Anno&lt;/em&gt; and &lt;em&gt;annus&lt;/em&gt; mean &lt;em&gt;year&lt;/em&gt;, so use &lt;em&gt;first anniversary&lt;/em&gt; instead of &lt;em&gt;one-year anniversary&lt;/em&gt; and &lt;em&gt;25th anniversary&lt;/em&gt; instead of &lt;em&gt;25-year anniversary&lt;/em&gt;. &lt;em&gt;Three-week anniversary&lt;/em&gt; and &lt;em&gt;one-month anniversary&lt;/em&gt; are incorrect.&lt;/li&gt; 
 &lt;li&gt;It&apos;s &lt;em&gt;backward&lt;/em&gt;, not &lt;em&gt;backwards&lt;/em&gt;. Likewise, it&apos;s &lt;em&gt;toward&lt;/em&gt;, not &lt;em&gt;towards&lt;/em&gt;.&lt;/li&gt; 
 &lt;li&gt;It&apos;s the &lt;em&gt;better&lt;/em&gt; of two, and the &lt;em&gt;best&lt;/em&gt; of three or more.&lt;/li&gt; 
 &lt;li&gt;Countries have &lt;em&gt;citizens&lt;/em&gt;, while cities and states have &lt;em&gt;residents&lt;/em&gt;.&lt;/li&gt; 
 &lt;li&gt;Avoid the colon after a &lt;em&gt;be&lt;/em&gt; verb, like &lt;em&gt;The three objectives of the new plan are:&lt;/em&gt;&lt;/li&gt; 
 &lt;li&gt;Place a comma before a conjunction midsentence if what follows the conjunction could stand as a complete sentence.&lt;/li&gt; 
 &lt;li&gt;If a city and state, or a month, day, and year appear midsentence, then place a comma both before and after the state or the year. But no comma is necessary between month and year when the day is absent.&lt;/li&gt; 
 &lt;li&gt;&lt;em&gt;et al&lt;/em&gt;, &lt;em&gt;e.g.&lt;/em&gt;, and &lt;em&gt;i.e.&lt;/em&gt; should be lowercase and italicized.&lt;/li&gt; 
 &lt;li&gt;Use commas both before and after &lt;em&gt;etc.&lt;/em&gt; when it appears midsentence.&lt;/li&gt; 
 &lt;li&gt;Use &lt;em&gt;hang on to&lt;/em&gt; or &lt;em&gt;hold on to&lt;/em&gt;, but not &lt;em&gt;hang onto&lt;/em&gt; or &lt;em&gt;hold onto&lt;/em&gt;.&lt;/li&gt; 
 &lt;li&gt;&lt;em&gt;Holdup&lt;/em&gt; is a noun, while &lt;em&gt;hold up&lt;/em&gt; is a verb.&lt;/li&gt; 
 &lt;li&gt;&lt;em&gt;Likely&lt;/em&gt; is not an adverb and should not be used as a substitute for &lt;em&gt;probably&lt;/em&gt;. It&apos;s an adjective, parallel to &lt;em&gt;probable&lt;/em&gt; rather than &lt;em&gt;probably&lt;/em&gt;.&lt;/li&gt; 
 &lt;li&gt;&lt;em&gt;Makeup&lt;/em&gt; is a noun, &lt;em&gt;make up&lt;/em&gt; is a verb, and &lt;em&gt;make-up&lt;/em&gt; is an adjective.&lt;/li&gt; 
 &lt;li&gt;&lt;em&gt;Mini&lt;/em&gt; generally has no hyphen. &lt;em&gt;mid&lt;/em&gt; generally has no hyphen unless followed by a capital letter or numeral. &lt;em&gt;Non&lt;/em&gt; is generally not hyphenated except before a proper noun or to avoid awkward constructions, like &lt;em&gt;nonnuclear&lt;/em&gt;.&lt;/li&gt; 
 &lt;li&gt;Write out the numerals one through nine, while use numerals for 10 or more. Avoid numerals at sentence beginnings.&lt;/li&gt; 
 &lt;li&gt;&lt;em&gt;One of the only&lt;/em&gt; is an illiteracy; it should be &lt;em&gt;one of the few&lt;/em&gt;.&lt;/li&gt; 
 &lt;li&gt;Use &lt;em&gt;percent&lt;/em&gt; in text, and the symbol &lt;em&gt;%&lt;/em&gt; for charts, graphs, tabulated material, lists, and the like.&lt;/li&gt; 
 &lt;li&gt;Write out state names in text, and reserve postal abbreviations for lists, charts, or graphic material.&lt;/li&gt; 
 &lt;li&gt;Don&apos;t mark deletions at sentence beginning; just start the quotation there. An ellipsis at sentence end is four spaced dots, the last being the period.&lt;/li&gt; 
 &lt;li&gt;Avoid the constructions &lt;em&gt;the reason is because&lt;/em&gt; and &lt;em&gt;the reason why&lt;/em&gt;. The text within or following them can stand alone.&lt;/li&gt; 
 &lt;li&gt;Hyphenate &lt;em&gt;re-create&lt;/em&gt; when meaning to create again rather than fun or leisure activity.&lt;/li&gt; 
 &lt;li&gt;&lt;em&gt;Round trip&lt;/em&gt; is a noun, while &lt;em&gt;round-trip&lt;/em&gt; is an adjective.&lt;/li&gt; 
 &lt;li&gt;If you are including &lt;em&gt;sic.&lt;/em&gt; or many brackets in a quote, it should be paraphrased or made a partial quote.&lt;/li&gt; 
 &lt;li&gt;Drop &lt;em&gt;single&lt;/em&gt; from &lt;em&gt;single most&lt;/em&gt;, &lt;em&gt;single best&lt;/em&gt;, and &lt;em&gt;single biggest&lt;/em&gt;.&lt;/li&gt; 
 &lt;li&gt;Replace &lt;em&gt;the past decade&lt;/em&gt; with &lt;em&gt;the last decade&lt;/em&gt;.&lt;/li&gt; 
 &lt;li&gt;&lt;em&gt;These&lt;/em&gt; and &lt;em&gt;this&lt;/em&gt; point forward, while &lt;em&gt;those&lt;/em&gt; and &lt;em&gt;that&lt;/em&gt; point back.&lt;/li&gt; 
 &lt;li&gt;Don&apos;t use a hyphen between times; instead, use &lt;em&gt;from/to&lt;/em&gt;, or &lt;em&gt;between/and&lt;/em&gt;.&lt;/li&gt; 
 &lt;li&gt;Capitalize the first and last words of a title and all the principal words between. Lowercase articles, &lt;em&gt;to&lt;/em&gt;, coordinating conjunctions, and prepositions fewer than four letters. Capitalize longer prepositions like &lt;em&gt;between&lt;/em&gt;, &lt;em&gt;toward&lt;/em&gt;, &lt;em&gt;beyond&lt;/em&gt;, &lt;em&gt;among&lt;/em&gt;, &lt;em&gt;with&lt;/em&gt;, and &lt;em&gt;from&lt;/em&gt;.&lt;/li&gt; 
 &lt;li&gt;The initial article &lt;em&gt;A&lt;/em&gt;, &lt;em&gt;An&lt;/em&gt;, or &lt;em&gt;The&lt;/em&gt; in titles can be omitted if the article follows a possessive noun or pronoun, or if the article follows an adjective or another article.&lt;/li&gt; 
 &lt;li&gt;Avoid using &lt;em&gt;verbal agreement&lt;/em&gt; for &lt;em&gt;oral agreement&lt;/em&gt;, as the preferred meaning of &lt;em&gt;verbal&lt;/em&gt; is words, both written and spoken.&lt;/li&gt; 
 &lt;li&gt;&lt;em&gt;Wait for&lt;/em&gt;, and not &lt;em&gt;wait on&lt;/em&gt;, unless one is waiting on tables.&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>WASM Composable Runtime</title>
      <link>https://tedneward.github.io/Research/vms/wasm/composable-runtime/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">vms/wasm/composable-runtime/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://crates.io/crates/composable-runtime&quot;&gt;Website&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Happy New Moon with Report</title>
      <link>https://tedneward.github.io/Research/vms/wasm/happy-new-moon-with-report/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">vms/wasm/happy-new-moon-with-report/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/fishjd/HappyNewMoonWithReport&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Implemented in Java. Interpreted. Java/JVM interop.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Non-MVP features supported&lt;/strong&gt;: Sign Extensions&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Motor</title>
      <link>https://tedneward.github.io/Research/vms/wasm/motor/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">vms/wasm/motor/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/penberg/motor&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Implemented in Rust using Dynasm. JIT compiled.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>TWVM</title>
      <link>https://tedneward.github.io/Research/vms/wasm/twvm/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">vms/wasm/twvm/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/Becavalier/TWVM&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Implemented in C++. Interpreted.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>WaKit</title>
      <link>https://tedneward.github.io/Research/vms/wasm/wakit/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">vms/wasm/wakit/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/akkyie/WAKit&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Implemented in Swift. Interpreted.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>WasmBoy</title>
      <link>https://tedneward.github.io/Research/vms/wasm/wasmboy/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">vms/wasm/wasmboy/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://wasmboy.app/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/torch2424/wasmBoy&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Wasmo</title>
      <link>https://tedneward.github.io/Research/vms/wasm/wasmo/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">vms/wasm/wasmo/index.html</guid>
      	<description>
	&lt;ul&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Languages written in&lt;/strong&gt;&lt;/p&gt; 
  &lt;table&gt; 
   &lt;tbody&gt;
    &lt;tr&gt; 
     &lt;td&gt;Rust&lt;/td&gt; 
    &lt;/tr&gt; 
   &lt;/tbody&gt;
  &lt;/table&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Compiler framework&lt;/strong&gt;&lt;/p&gt; 
  &lt;table&gt; 
   &lt;tbody&gt;
    &lt;tr&gt; 
     &lt;td&gt;LLVM&lt;/td&gt; 
    &lt;/tr&gt; 
   &lt;/tbody&gt;
  &lt;/table&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Compilation / Execution modes&lt;/strong&gt;&lt;/p&gt; 
  &lt;table&gt; 
   &lt;tbody&gt;
    &lt;tr&gt; 
     &lt;td&gt;JIT&lt;/td&gt; 
    &lt;/tr&gt; 
   &lt;/tbody&gt;
  &lt;/table&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Interoperability with other languages&lt;/strong&gt;&lt;/p&gt; 
  &lt;ul&gt; 
   &lt;li&gt;&lt;code&gt;N/A&lt;/code&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Non-MVP features supported&lt;/strong&gt;&lt;/p&gt; 
  &lt;ul&gt; 
   &lt;li&gt;&lt;code&gt;N/A&lt;/code&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Host APIs supported&lt;/strong&gt;&lt;/p&gt; 
  &lt;ul&gt; 
   &lt;li&gt;&lt;code&gt;N/A&lt;/code&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Non-web standards&lt;/strong&gt;&lt;/p&gt; 
  &lt;ul&gt; 
   &lt;li&gt;&lt;code&gt;N/A&lt;/code&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Used by&lt;/strong&gt;&lt;/p&gt; 
  &lt;ul&gt; 
   &lt;li&gt;&lt;code&gt;N/A&lt;/code&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Platforms supported&lt;/strong&gt;&lt;/p&gt; 
  &lt;table&gt; 
   &lt;tbody&gt;
    &lt;tr&gt; 
     &lt;td&gt;macOS&lt;/td&gt; 
    &lt;/tr&gt; 
   &lt;/tbody&gt;
  &lt;/table&gt; &lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>wasmvm</title>
      <link>https://tedneward.github.io/Research/vms/wasm/wasmvm2/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">vms/wasm/wasmvm2/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/kogai/wasvm&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Implemented in Rust using Life. Interpreted.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Wizard</title>
      <link>https://tedneward.github.io/Research/vms/wasm/wizard/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">vms/wasm/wizard/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/titzer/wizard-engine&quot;&gt;Source&lt;/a&gt; |&lt;/p&gt; 
&lt;p&gt;The Wizard Engine is a lightweight WebAssembly virtual machine designed for teaching and research. Its implementation is designed to be flexible and easy to grasp, ideal for experimentation and modification. Built with the future in mind, it is written in a fast and lightweight safe, garbage-collected programming language, Virgil.&lt;/p&gt; 
&lt;p&gt;Implemented in Virgil. Interpreted and JIT compiled.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Non-MVP features supported&lt;/strong&gt;:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Bulk Memory Operations&lt;/li&gt; 
 &lt;li&gt;Import/Export of Mutable Globals&lt;/li&gt; 
 &lt;li&gt;Sign-extension operators&lt;/li&gt; 
 &lt;li&gt;Multi-Value Returns&lt;/li&gt; 
 &lt;li&gt;Name Section&lt;/li&gt; 
 &lt;li&gt;Non-trapping float-to-int conversions&lt;/li&gt; 
 &lt;li&gt;Reference Types&lt;/li&gt; 
 &lt;li&gt;SIMD&lt;/li&gt; 
 &lt;li&gt;Tail-call&lt;/li&gt; 
 &lt;li&gt;GC&lt;/li&gt; 
 &lt;li&gt;Exception Handling&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;&lt;strong&gt;Host APIs supported&lt;/strong&gt;: Wave, WASI&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Non-web standards&lt;/strong&gt;: WASI&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Zetavm</title>
      <link>https://tedneward.github.io/Research/vms/zetavm/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">vms/zetavm/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://pointersgonewild.com/category/zeta/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/zetavm/zetavm&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;(Claims under development, but no commits for 3 years.)&lt;/p&gt; 
&lt;p&gt;ZetaVM is a Virtual machine and JIT compiler for dynamic programming languages. It implements a basic core runtime environment on top of which programming dynamic languages can be implemented with relatively little effort.&lt;/p&gt; 
&lt;p&gt;Features of the VM include:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Built-in support for dynamic typing&lt;/li&gt; 
 &lt;li&gt;Garbage collection&lt;/li&gt; 
 &lt;li&gt;JIT compilation&lt;/li&gt; 
 &lt;li&gt;Dynamically growable objects (JS-like)&lt;/li&gt; 
 &lt;li&gt;Dynamically-typed arrays (JS/Python-like)&lt;/li&gt; 
 &lt;li&gt;Integer and floating-point arithmetic&lt;/li&gt; 
 &lt;li&gt;Immutable UTF-8 strings&lt;/li&gt; 
 &lt;li&gt;Text-based code and data storage format (JSON-like)&lt;/li&gt; 
 &lt;li&gt;First-class stack-based bytecode (code is data)&lt;/li&gt; 
 &lt;li&gt;Built-in graphical and audio libraries&lt;/li&gt; 
 &lt;li&gt;Coming soon: built-in package manager&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;Zeta image files (.zim) are JSON-like, human-readable text files containing objects, data and bytecodes to be executed by ZetaVM. They are intended to serve as a compilation target, and may contain executable programs, or libraries/packages.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Extism</title>
      <link>https://tedneward.github.io/Research/vms/wasm/extism/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">vms/wasm/extism/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/extism/extism&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Implemented in Rust. JIT compiled.&lt;/p&gt; 
&lt;p&gt;SDKs to execute WebAssembly in:&lt;br&gt; - &lt;a href=&quot;https://extism.org/docs/integrate-into-your-codebase/browser-runtime-sdk/&quot;&gt;&lt;code&gt;Browser&lt;/code&gt;&lt;/a&gt;&lt;br&gt; - &lt;a href=&quot;https://extism.org/docs/integrate-into-your-codebase/c-host-sdk/&quot;&gt;&lt;code&gt;C&lt;/code&gt;&lt;/a&gt;&lt;br&gt; - &lt;a href=&quot;https://extism.org/docs/integrate-into-your-codebase/cpp-host-sdk/&quot;&gt;&lt;code&gt;C++&lt;/code&gt;&lt;/a&gt;&lt;br&gt; - &lt;a href=&quot;https://extism.org/docs/integrate-into-your-codebase/dotnet-host-sdk&quot;&gt;&lt;code&gt;.NET&lt;/code&gt;&lt;/a&gt;&lt;br&gt; - &lt;a href=&quot;https://extism.org/docs/integrate-into-your-codebase/elixir-host-sdk/&quot;&gt;&lt;code&gt;Elixir&lt;/code&gt;&lt;/a&gt;&lt;br&gt; - &lt;a href=&quot;https://extism.org/docs/integrate-into-your-codebase/go-host-sdk/&quot;&gt;&lt;code&gt;Go&lt;/code&gt;&lt;/a&gt;&lt;br&gt; - &lt;a href=&quot;https://extism.org/docs/integrate-into-your-codebase/haskell-host-sdk/&quot;&gt;&lt;code&gt;Haskell&lt;/code&gt;&lt;/a&gt;&lt;br&gt; - &lt;a href=&quot;https://extism.org/docs/integrate-into-your-codebase/java-host-sdk&quot;&gt;&lt;code&gt;Java&lt;/code&gt;&lt;/a&gt;&lt;br&gt; - &lt;a href=&quot;https://extism.org/docs/integrate-into-your-codebase/node-host-sdk/&quot;&gt;&lt;code&gt;Node&lt;/code&gt;&lt;/a&gt;&lt;br&gt; - &lt;a href=&quot;https://extism.org/docs/integrate-into-your-codebase/ocaml-host-sdk/&quot;&gt;&lt;code&gt;OCaml&lt;/code&gt;&lt;/a&gt;&lt;br&gt; - &lt;a href=&quot;https://extism.org/docs/integrate-into-your-codebase/php-host-sdk/&quot;&gt;&lt;code&gt;PHP&lt;/code&gt;&lt;/a&gt;&lt;br&gt; - &lt;a href=&quot;https://extism.org/docs/integrate-into-your-codebase/python-host-sdk/&quot;&gt;&lt;code&gt;Python&lt;/code&gt;&lt;/a&gt;&lt;br&gt; - &lt;a href=&quot;https://extism.org/docs/integrate-into-your-codebase/ruby-host-sdk/&quot;&gt;&lt;code&gt;Ruby&lt;/code&gt;&lt;/a&gt;&lt;br&gt; - &lt;a href=&quot;https://extism.org/docs/integrate-into-your-codebase/rust-host-sdk/&quot;&gt;&lt;code&gt;Rust&lt;/code&gt;&lt;/a&gt;&lt;br&gt; - &lt;a href=&quot;https://extism.org/docs/integrate-into-your-codebase/zig-host-sdk&quot;&gt;&lt;code&gt;Zig&lt;/code&gt;&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;PDKs to create WebAssembly plug-ins in:&lt;br&gt; - &lt;a href=&quot;https://github.com/extism/rust-pdk&quot;&gt;&lt;code&gt;Rust&lt;/code&gt;&lt;/a&gt;&lt;br&gt; - &lt;a href=&quot;https://extism.org/docs/write-a-plugin/js-pdk&quot;&gt;&lt;code&gt;JavaScript&lt;/code&gt;&lt;/a&gt;&lt;br&gt; - &lt;a href=&quot;https://github.com/extism/go-pdk&quot;&gt;&lt;code&gt;Go&lt;/code&gt;&lt;/a&gt;&lt;br&gt; - &lt;a href=&quot;https://extism.org/docs/write-a-plugin/haskell-pdk&quot;&gt;&lt;code&gt;Haskell&lt;/code&gt;&lt;/a&gt;&lt;br&gt; - &lt;a href=&quot;https://github.com/extism/assemblyscript-pdk&quot;&gt;&lt;code&gt;AssemblyScript&lt;/code&gt;&lt;/a&gt;&lt;br&gt; - &lt;a href=&quot;https://github.com/extism/c-pdk&quot;&gt;&lt;code&gt;C&lt;/code&gt;&lt;/a&gt;&lt;br&gt; - &lt;a href=&quot;https://github.com/extism/c-pdk&quot;&gt;&lt;code&gt;C++&lt;/code&gt;&lt;/a&gt;&lt;br&gt; - &lt;a href=&quot;https://extism.org/docs/write-a-plugin/zig-pdk&quot;&gt;&lt;code&gt;Zig&lt;/code&gt;&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Host APIs supported&lt;/strong&gt;&lt;br&gt; - module loading &amp;amp; linking via &lt;a href=&quot;https://extism.org/docs/concepts/manifest&quot;&gt;&lt;code&gt;Manifest&lt;/code&gt;&lt;/a&gt;&lt;br&gt; - WASI&lt;br&gt; - non-WASI &lt;code&gt;http_request&lt;/code&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>inNative</title>
      <link>https://tedneward.github.io/Research/vms/wasm/innative/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">vms/wasm/innative/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/innative-sdk/innative&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Implemented in C++ using LLVM. AOT and JIT compiled.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Non-MVP features supported&lt;/strong&gt;:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Threads&lt;/li&gt; 
 &lt;li&gt;Multiple Result and Block Parameters&lt;/li&gt; 
 &lt;li&gt;Name Section&lt;/li&gt; 
 &lt;li&gt;Bulk Memory Operations&lt;/li&gt; 
 &lt;li&gt;Sign Extension Instructions&lt;/li&gt; 
 &lt;li&gt;Non-trapping Conversion Instructions&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;&lt;strong&gt;Host APIs supported&lt;/strong&gt;: Custom&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>py-wasm</title>
      <link>https://tedneward.github.io/Research/vms/wasm/pywasm/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">vms/wasm/pywasm/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/ethereum/py-wasm&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Implemented in Python. Interpreted.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>VMIR (Virtual Machine for Intermediate Representation)</title>
      <link>https://tedneward.github.io/Research/vms/wasm/vmir/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">vms/wasm/vmir/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/andoma/vmir&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Implemented in C using LLVM. Interpreted and JIT compiled.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>WAMR (WebAssembly Micro-Runtime)</title>
      <link>https://tedneward.github.io/Research/vms/wasm/wamr/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">vms/wasm/wamr/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/bytecodealliance/wasm-micro-runtime&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Implemented in C. Interpreted, AOT, and JIT compiled.&lt;/p&gt; 
&lt;p&gt;It includes a few parts as below:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt; &lt;p&gt;The &quot;iwasm&quot; VM core to run WASM applications, supporting interpreter mode, AOT mode (Ahead-of-Time compilation) and JIT modes (Just-in-Time compilation, LLVM JIT and Fast JIT are supported)&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;The &quot;wamrc&quot; AOT compiler to compile WASM file into AOT file for best performance and smaller runtime footprint, which is run by &quot;iwasm&quot; VM Core&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;The application framework and the supporting APIs for the WASM applications&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;The dynamic management of the WASM applications&lt;/p&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;&lt;strong&gt;Non-MVP features supported&lt;/strong&gt;&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/WebAssembly/nontrapping-float-to-int-conversions&quot;&gt;Non-trapping float-to-int conversions&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/WebAssembly/sign-extension-ops&quot;&gt;Sign-extension operators&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/WebAssembly/bulk-memory-operations&quot;&gt;Bulk memory operations&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/WebAssembly/threads/blob/main/proposals/threads/Overview.md#shared-linear-memory&quot;&gt;Shared memory&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/WebAssembly/multi-value&quot;&gt;Multi-value&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/WebAssembly/tail-call&quot;&gt;Tail-call&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;&lt;strong&gt;Host APIs supported&lt;/strong&gt;&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/WebAssembly/wasm-c-api&quot;&gt;wasm-c-api&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;&lt;strong&gt;Non-web standards&lt;/strong&gt;&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;[x] WASI&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>WasmEdge</title>
      <link>https://tedneward.github.io/Research/vms/wasm/wasmedge/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">vms/wasm/wasmedge/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://wasmedge.org/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/WasmEdge/WasmEdge&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Implemented in C++ using LLVM. Interpreted and AOT compiled.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Interoperability with other languages&lt;/strong&gt;:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Solidity&lt;/li&gt; 
 &lt;li&gt;Rust&lt;/li&gt; 
 &lt;li&gt;C/C++&lt;/li&gt; 
 &lt;li&gt;Go/TinyGo&lt;/li&gt; 
 &lt;li&gt;JavaScript&lt;/li&gt; 
 &lt;li&gt;Python&lt;/li&gt; 
 &lt;li&gt;Grain&lt;/li&gt; 
 &lt;li&gt;Swift&lt;/li&gt; 
 &lt;li&gt;Zig&lt;/li&gt; 
 &lt;li&gt;Ruby&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;&lt;strong&gt;Non-MVP features supported&lt;/strong&gt;:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Bulk Memory Operations&lt;/li&gt; 
 &lt;li&gt;SIMD&lt;/li&gt; 
 &lt;li&gt;Multi-Memory&lt;/li&gt; 
 &lt;li&gt;Multi-Value&lt;/li&gt; 
 &lt;li&gt;Reference Types&lt;/li&gt; 
 &lt;li&gt;Sign Extension Instructions&lt;/li&gt; 
 &lt;li&gt;Non-Trapping Float-to-Int Conversions&lt;/li&gt; 
 &lt;li&gt;Mutable Global&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;&lt;strong&gt;Host APIs supported&lt;/strong&gt;:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;WASI&lt;/li&gt; 
 &lt;li&gt;Networking Socket&lt;/li&gt; 
 &lt;li&gt;TensorFlow&lt;/li&gt; 
 &lt;li&gt;Command Interface&lt;/li&gt; 
 &lt;li&gt;Image Processing&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;&lt;strong&gt;Non-web standards&lt;/strong&gt;:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;WASI&lt;/li&gt; 
 &lt;li&gt;Gas Metering&lt;/li&gt; 
 &lt;li&gt;Ethereum Environment Interface&lt;/li&gt; 
 &lt;li&gt;Oasis&lt;/li&gt; 
 &lt;li&gt;Substrate&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;&lt;strong&gt;Used by&lt;/strong&gt;:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://blog.suborbital.dev/suborbital-wasmedge&quot;&gt;Suborbital&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/containers/crun/pull/774&quot;&gt;crun&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/superedge/superedge/pull/335&quot;&gt;SuperEdge&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/openyurtio/openyurt.io/pull/85&quot;&gt;OpenYurt&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.infoq.com/articles/webassembly-dapr-wasmedge/&quot;&gt;Dapr&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/yomorun/yomo-wasmedge-tensorflow&quot;&gt;Yomo&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://medium.com/oasis-protocol-project/the-oasis-eth-paratime-is-live-on-mainnet-33d8713ec870&quot;&gt;Oasis ETH ParaTime&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>WasmRT</title>
      <link>https://tedneward.github.io/Research/vms/wasm/wasmrt/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">vms/wasm/wasmrt/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/rhitchcock/wasmrt&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Implemented in C++. Interpreted.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>WebAssembly Virtual Machine</title>
      <link>https://tedneward.github.io/Research/vms/wasm/wavm/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">vms/wasm/wavm/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/WAVM/WAVM&quot;&gt;Github&lt;/a&gt; | &lt;a href=&quot;https://wavm.github.io/&quot;&gt;Website&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Implemented in C++ and Python using LLVM. JIT compiled.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Host APIs supported&lt;/strong&gt;: WASI, Emscripten, WAVIX&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Non-web standards&lt;/strong&gt;: WASI&lt;/p&gt; 
&lt;p&gt;From the Github page:&lt;/p&gt; 
&lt;p&gt;WAVM fully supports WebAssembly 1.0, plus many proposed extensions to it:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;WASI&lt;/li&gt; 
 &lt;li&gt;128-bit SIMD&lt;/li&gt; 
 &lt;li&gt;Threads&lt;/li&gt; 
 &lt;li&gt;Reference types&lt;/li&gt; 
 &lt;li&gt;Multiple results and block parameters&lt;/li&gt; 
 &lt;li&gt;Bulk memory operations&lt;/li&gt; 
 &lt;li&gt;Non-trapping float-to-int conversions&lt;/li&gt; 
 &lt;li&gt;Sign-extension instructions&lt;/li&gt; 
 &lt;li&gt;Exception handling&lt;/li&gt; 
 &lt;li&gt;Extended name section&lt;/li&gt; 
 &lt;li&gt;Multiple memories&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;WAVM uses LLVM to compile WebAssembly code to machine code with close to native performance. It can even beat native performance in some cases, thanks to the ability to generate machine code tuned for the exact CPU that is running the code. WAVM also leverages virtual memory and signal handlers to execute WebAssembly&apos;s bounds-checked memory accesses at the same cost as a native, unchecked memory access.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>WebVM</title>
      <link>https://tedneward.github.io/Research/vms/webvm/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">vms/webvm/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://webvm.io/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/leaningtech/webvm&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://labs.leaningtech.com/blog/webvm-server-less-x86-virtual-machines-in-the-browser&quot;&gt;https://labs.leaningtech.com/blog/webvm-server-less-x86-virtual-machines-in-the-browser&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://labs.leaningtech.com/blog/mini-webvm-your-linux-box-from-dockerfile-via-wasm&quot;&gt;https://labs.leaningtech.com/blog/mini-webvm-your-linux-box-from-dockerfile-via-wasm&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://labs.leaningtech.com/blog/webvm-20&quot;&gt;https://labs.leaningtech.com/blog/webvm-20&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Z-machine</title>
      <link>https://tedneward.github.io/Research/vms/zmachine/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">vms/zmachine/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;http://www.ifwiki.org/index.php/Z-machine_versions&quot;&gt;Z-machine versions&lt;/a&gt; | &lt;a href=&quot;http://inform-fiction.org/zmachine/standards/&quot;&gt;Specification&lt;/a&gt; &lt;a href=&quot;http://inform-fiction.org/zmachine/standards/index.html&quot;&gt;Inform Standards&lt;/a&gt; | &lt;a href=&quot;https://en.wikipedia.org/wiki/Z-machine&quot;&gt;Wikipedia&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;http://curiousdannii.github.io/if/zspec12.html&quot;&gt;Z-Machine Standard 1.2 (draft)&lt;/a&gt; | &lt;a href=&quot;https://inform-fiction.org/zmachine/standards/z1point1/index.html&quot;&gt;Z-Machine Standards Document v1.1&lt;/a&gt; | &lt;a href=&quot;http://www.wolldingwacht.de/if/z-spec.html&quot;&gt;if-resources&lt;/a&gt;: Collection of Z-Machine standard document, consisting of Z-Machine Standard Document 1.0, Z-machine Common Save-File Format Standard (Quetzal) v1.3b, IF Resource Collection Format (Blorb) v1.1, and proposal for a Z-Machine Standard v1.1, in one PDF&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://web.archive.org/web/20100807003406/http://xlisp.org/zil.pdf&quot;&gt;Learning ZIL&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;http://xlisp.org/zip.pdf&quot;&gt;Description of ZIP&lt;/a&gt; (the Z-Language Interpreter Program, as per an Infocom internal document)&lt;/p&gt; 
&lt;p&gt;Interpreters/VMs:&lt;br&gt; * Glulx – Similar to the Z-machine, but relieves several legacy limitations&lt;br&gt; * &lt;a href=&quot;../languages/inform6&quot;&gt;Inform&lt;/a&gt; – A computer language that can produce Z-machine programs&lt;br&gt; * &lt;a href=&quot;../gamedev/scummvm&quot;&gt;SCUMM&lt;/a&gt; – Script Creation Utility for Maniac Mansion by LucasArts, a graphical system similar to Z-machine&lt;br&gt; * &lt;a href=&quot;../tads&quot;&gt;TADS&lt;/a&gt; – Like Glulx, made to address some of its limitations&lt;br&gt; * Motorola 68000 series – The base architecture used for virtual machines in Magnetic Scrolls&apos; adventure games&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://foss.heptapod.net/zilf/zilf&quot;&gt;ZILF&lt;/a&gt;: A set of tools for working with ZIL, including a compiler, assembler, disassembler, and game library. | &lt;a href=&quot;https://github.com/heasm66/ZILF-Reference-Guide&quot;&gt;ZILF Reference Guide&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://www.facebook.com/groups/ZILcom/&quot;&gt;Zork Implementation Language Facebook group&lt;/a&gt;&lt;/p&gt; 
&lt;hr&gt; 
&lt;h1&gt;&lt;a href=&quot;https://www.linusakesson.net/software/zeugma/index.php&quot;&gt;Zeugma&lt;/a&gt;&lt;/h1&gt; 
&lt;p&gt;A modern, highly optimised, open-source Z-machine implementation for the 6502 processor family. It is designed around a virtual memory model, where pages are retrieved on demand from an external storage resource, 512 KB in size, which must be preloaded with the game file.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Chicory</title>
      <link>https://tedneward.github.io/Research/vms/wasm/chicory/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">vms/wasm/chicory/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/dylibso/chicory&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Chicory is a JVM native WebAssembly runtime. It allows you to run WebAssembly programs with zero native dependencies or JNI. Chicory can run Wasm anywhere that the JVM can go. It is designed with simplicity and safety in mind.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>FDVM</title>
      <link>https://tedneward.github.io/Research/vms/wasm/fdvm/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">vms/wasm/fdvm/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/funcdef/fdvm&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Implemented in Javascript using NodeJS/V8. JIT compiled.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Life</title>
      <link>https://tedneward.github.io/Research/vms/wasm/life/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">vms/wasm/life/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/perlin-network/life&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Implemented in Go. Interpreted.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Swam</title>
      <link>https://tedneward.github.io/Research/vms/wasm/swam/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">vms/wasm/swam/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/satabin/swam&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Implemented in Scala. Interpreted.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>WAC</title>
      <link>https://tedneward.github.io/Research/vms/wasm/wac/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">vms/wasm/wac/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/kanaka/wac&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Implemented in C. Interpreted.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Warpy</title>
      <link>https://tedneward.github.io/Research/vms/wasm/warpy/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">vms/wasm/warpy/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/kanaka/warpy&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Implemented in RPython. JIT-compiled.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Wasmer</title>
      <link>https://tedneward.github.io/Research/vms/wasm/wasmer/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">vms/wasm/wasmer/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://wasmer.io/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/wasmerio&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Implemented in C++ and Rust using Singlepass, Cranelift, and LLVM. JIT and AOT compiled.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Interoperability with other languages&lt;/strong&gt;:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/wasmerio/wasmer&quot;&gt;Rust&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;C&lt;/li&gt; 
 &lt;li&gt;C++&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/wasmerio/wasmer-python&quot;&gt;Python&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/wasmerio/wasmer-go&quot;&gt;Go&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/wasmerio/wasmer-php&quot;&gt;PHP&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;Java&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/wasmerio/wasmer-ruby&quot;&gt;Ruby&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;Postgres&lt;/li&gt; 
 &lt;li&gt;C#/.Net&lt;/li&gt; 
 &lt;li&gt;Elixir&lt;/li&gt; 
 &lt;li&gt;R&lt;/li&gt; 
 &lt;li&gt;D&lt;/li&gt; 
 &lt;li&gt;Swift&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;&lt;strong&gt;Non-MVP features supported&lt;/strong&gt;:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Threads&lt;/li&gt; 
 &lt;li&gt;SIMD&lt;/li&gt; 
 &lt;li&gt;Multi Value returns&lt;/li&gt; 
 &lt;li&gt;Name Section&lt;/li&gt; 
 &lt;li&gt;Bulk Memory Operations&lt;/li&gt; 
 &lt;li&gt;Sign Extension Instructions&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;&lt;strong&gt;Host APIs supported&lt;/strong&gt;:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Emscripten&lt;/li&gt; 
 &lt;li&gt;WASI&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;&lt;strong&gt;Non-web standards&lt;/strong&gt;:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;WASI&lt;/li&gt; 
 &lt;li&gt;wasm-c-api&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;&lt;strong&gt;Used by&lt;/strong&gt;&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/spacemeshos/svm&quot;&gt;Spacemesh Virtual Machine&lt;/a&gt; - A Spacemesh smart contracts vm&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/CosmWasm/cosmwasm&quot;&gt;CosmWasm&lt;/a&gt; - A Cosmos-compatible library for running wasm smart contracts&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/near/nearcore&quot;&gt;NEAR Protocol&lt;/a&gt; - The reference client for NEAR protocol&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/dprint/dprint&quot;&gt;Dprint&lt;/a&gt; - Pluggable and configurable code formatting platform&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Wasmtime</title>
      <link>https://tedneward.github.io/Research/vms/wasm/wasmtime/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">vms/wasm/wasmtime/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://wasmtime.dev/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/bytecodealliance/wasmtime&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Implemented in Rust using Cranelift. JIT compiled. Interops with Python.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Non-MVP features supported&lt;/strong&gt;: Interface types&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Host APIs supported&lt;/strong&gt;: WASI&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Non-web standards&lt;/strong&gt;: WASI, wasm-c-api&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Used by&lt;/strong&gt;&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/paritytech/wasmi&quot;&gt;Wasmi&lt;/a&gt;: an efficient WebAssembly interpreter that is used by &lt;a href=&quot;https://github.com/paritytech/substrate&quot;&gt;Substrate&lt;/a&gt;, a next-generation framework for blockchain innovation.&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Wazero</title>
      <link>https://tedneward.github.io/Research/vms/wasm/wazero/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">vms/wasm/wazero/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://wazero.io&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Implemented in Go. Interpreted and JIT compiled.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Non-MVP features supported&lt;/strong&gt;:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Bulk Memory Operations&lt;/li&gt; 
 &lt;li&gt;Import/Export of Mutable Globals&lt;/li&gt; 
 &lt;li&gt;Sign-extension operators&lt;/li&gt; 
 &lt;li&gt;Multi-Value Returns&lt;/li&gt; 
 &lt;li&gt;Name Section&lt;/li&gt; 
 &lt;li&gt;Non-trapping float-to-int conversions&lt;/li&gt; 
 &lt;li&gt;Reference Types&lt;/li&gt; 
 &lt;li&gt;SIMD&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;&lt;strong&gt;Host APIs supported&lt;/strong&gt;:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;AssemblyScript&lt;/li&gt; 
 &lt;li&gt;WASI&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;&lt;strong&gt;Non-web standards&lt;/strong&gt;:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;WASI&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;&lt;strong&gt;Used by&lt;/strong&gt;&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/dapr/dapr&quot;&gt;dapr&lt;/a&gt; - APIs that simplify microservice connectivity&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/aquasecurity/trivy&quot;&gt;trivy&lt;/a&gt; - vulnerability/misconfiguration/secret scanner for containers and other artifacts&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/wapc/wapc-go&quot;&gt;wapc-go&lt;/a&gt; - WebAssembly Host Runtime for waPC-compliant modules&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>XVM</title>
      <link>https://tedneward.github.io/Research/vms/xvm/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">vms/xvm/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/xtclang/xvm&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>PIXAR&apos;s 22 Rules of Storytelling</title>
      <link>https://tedneward.github.io/Research/writing/22-rules-of-storytelling/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">writing/22-rules-of-storytelling/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://42courses.medium.com/pixars-22-rules-of-storytelling-dc24162fe8ce&quot;&gt;Website&lt;/a&gt;&lt;/p&gt; 
&lt;ol&gt; 
 &lt;li&gt; &lt;p&gt;You admire a character for trying more than for their successes.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Keep in mind what’s interesting to you as an audience, not what’s fun as a writer. They can be very different.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Trying for theme is important, however you won’t see what the story is about until you’re at the end of that story. Got it? Now rewrite.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Once upon a time there was ____. Every day, ___. One day ____. Because of that, ______. Until finally ____.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Simplify. Focus. Combine characters. Hop over detours. You’ll feel like you’re losing valuable stuff but it sets you free.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;What is your character good at or comfortable with? Throw the polar opposite at him. Challenge him. How does he deal with it?&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Come up with your ending before you figure out your middle. Seriously. Endings are hard. Get yours working up front.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Finish your story. Let go even if it’s not perfect. In an ideal world, you have both, but move on. Do better next time.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;When you’re stuck, make a list of what wouldn’t happen next. More often than not, the material that gets you unstuck appears.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Pull apart the stories you like. What you like in them is part of you. Recognise it before you use it.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Why must you tell this story in particular? What’s the belief burning within you that your story feeds off? That’s the heart of it.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Discount the 1st thing that comes to mind. And the 2nd, 3rd, 4th, 5th — get the obvious out of the way. Surprise yourself.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Give your characters opinions. A character being passive or malleable is easy for you as a writer, but it’s poison to your audience.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;What’s the essence of your story? What’s the most economical way of telling of it? If you know that, you can build out there.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;If you were your character, in this situation, how would you feel? Honesty lends credibility to unbelievable situations.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;What are the stakes? Give us reason to root for the character. What happens if he doesn’t succeed? Stack the odds against him.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;No work is ever wasted. And if it’s not working, let go and move on — if it’s useful, it’ll show up again.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;You have to know yourself, and know the difference between doing your best &amp;amp; being fussy. Story is testing, not refining.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Coincidences that get characters into trouble are great. Coincidences that get them out of it is cheating.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Exercise. Take the building blocks of a movie you dislike. How would you rearrange them into what you DO like?&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Identify with your situation/characters. Don’t write &quot;cool.&quot; What would make YOU act that way?&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Putting it on paper only allows you to start fixing it. If a perfect idea stays in your head, you’ll never share it with anyone.&lt;/p&gt; &lt;/li&gt; 
&lt;/ol&gt;
	</description>
    </item>
    <item>
      <title>CMM of WASM</title>
      <link>https://tedneward.github.io/Research/vms/wasm/cmm-of-wasm/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">vms/wasm/cmm-of-wasm/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/SimonJF/cmm_of_wasm&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Implemented in OCaml. AOT compilation.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Fizzy</title>
      <link>https://tedneward.github.io/Research/vms/wasm/fizzy/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">vms/wasm/fizzy/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/wasmx/fizzy&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Implemented in C++. Interpreted.&lt;/p&gt; 
&lt;p&gt;Supports WASI.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Lucet</title>
      <link>https://tedneward.github.io/Research/vms/wasm/lucet/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">vms/wasm/lucet/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/fastly/lucet&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;NOTE: Lucet is now in maintenance mode. Work has been moved to &lt;a href=&quot;https://github.com/bytecodealliance/wasmtime/&quot;&gt;wasmtime&lt;/a&gt;.&lt;/p&gt; 
&lt;/blockquote&gt; 
&lt;p&gt;Implemented in Rust using Cranelift. AOT compiled.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Host APIs supported&lt;/strong&gt;: WASI&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Non-web standards&lt;/strong&gt;: WASI&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>TeaVM</title>
      <link>https://tedneward.github.io/Research/vms/wasm/teavm/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">vms/wasm/teavm/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://teavm.org/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/konsoletyper/teavm&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;WebAssembly support is in experimental status. It may lack major features available in JavaScript backend. There&apos;s no documentation yet, and you should do many things by hands (like embedding generated wasm file into your page, importing JavaScript objects, etc).&lt;/p&gt; 
&lt;h2&gt;Purpose&lt;/h2&gt; 
&lt;p&gt;TeaVM is primarily a web development tool. It&apos;s not for taking your large existing codebase in Java or Kotlin and producing JavaScript. Unfortunately, Java was not designed to run efficiently in the browser. There are Java APIs that are impossible to implement without generating inefficient JavaScript. Some of these APIs are: reflection, resources, class loaders, and JNI. TeaVM restricts usage of these APIs. Generally, you&apos;ll have to manually rewrite your code to fit into TeaVM constraints.&lt;/p&gt; 
&lt;p&gt;TeaVM is for you, if:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;You are a Java developer and you are going to write a web front-end from scratch.&lt;/li&gt; 
 &lt;li&gt;You already have a Java-based backend and want to integrate front-end code tightly into your existing development infrastructure.&lt;/li&gt; 
 &lt;li&gt;You have some Java back-end code you want to reuse in the front end.&lt;/li&gt; 
 &lt;li&gt;You are ready to rewrite your code to work with TeaVM.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;If you have tightly-coupled applications that use Swing, you want to run these applications in web, and you don&apos;t care about download size, start-up time and performance, you should probably look elsewhere; there are more appropriate tools for you, like CheerpJ.&lt;/p&gt; 
&lt;h2&gt;Strong parts&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;TeaVM tries to reconstruct original structure of a method, so in most cases it produces JavaScript that you would write manually. No bloated while/switch statements, as naive compilers often do.&lt;/li&gt; 
 &lt;li&gt;TeaVM has a very sophisticated optimizer, which knows a lot about your code. Some examples are: 
  &lt;ul&gt; 
   &lt;li&gt;Dead code elimination produces very small JavaScript.&lt;/li&gt; 
   &lt;li&gt;Devirtualization turns virtual calls into static function calls, which makes code faster.&lt;/li&gt; 
   &lt;li&gt;TeaVM can reuse one local variables to store several local variables.&lt;/li&gt; 
   &lt;li&gt;TeaVM renames methods to as short forms as possible; UglifyJS usually can&apos;t perform such optimization.&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;TeaVM supports threads. JavaScript does not provide APIs to create threads (WebWorkers are not threads, since they don&apos;t allow to share state between workers). TeaVM is capable of transforming methods to continuation-passing style. This makes possible to emulate multiple logical threads in one physical thread. TeaVM threads are, in fact, green threads.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt;TeaVM is very fast, you don&apos;t need to wait for minutes until your application gets recompiled.&lt;/li&gt; 
 &lt;li&gt;TeaVM produces source maps; TeaVM IDEA plugin allows you to debug code right from the IDE.&lt;/li&gt; 
 &lt;li&gt;TeaVM has a nice JavaScript interop API.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Integrating with Gradle&lt;/h3&gt; 
&lt;p&gt;Here&apos;s a minimal &lt;code&gt;build.gradle&lt;/code&gt;:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;plugins {
    id &quot;java&quot;
    id &quot;war&quot;
    id &quot;org.teavm&quot; version &quot;0.12.3&quot;
}
repositories {
    mavenCentral()
}

// This is optional, but for real-world applications you need to interact with browser.
// This dependency provides useful wrappers.
dependencies {
    implementation teavm.libs.jsoApis
}

teavm {
    all {
        mainClass = &quot;example.MainClass&quot;
    }
    js {
        addedToWebApp = true

        // this is also optional, default value is &amp;lt;project name&amp;gt;.js
        targetFileName = &quot;example.js&quot;
    }
    wasmGC {
        addedToWebApp = true

        // this is also optional, default value is &amp;lt;project name&amp;gt;.wasm
        targetFileName = &quot;example.wasm&quot;
    }
}
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;If you don&apos;t need either JS or WebAssembly GC, you can remove corresponding &lt;code&gt;addedToWebApp&lt;/code&gt; setting, or ever entire configuration section related to particular backend.&lt;/p&gt; 
&lt;p&gt;where &lt;code&gt;MainClass&lt;/code&gt; could do something simple like writing &quot;Hello, world&quot; string in the console. A bit more complex example of MainClass could be following:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;package example;

import org.teavm.jso.dom.html.HTMLDocument;

public class MainClass {
    public static void main(String[] args) {
        var document = HTMLDocument.current();
        var div = document.createElement(&quot;div&quot;);
        div.appendChild(document.createTextNode(&quot;TeaVM generated element&quot;));
document.getBody().appendChild(div);
    }
}
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Finally, you need to add to your webapp resources index.html page, which includes examples.js and runs main method, like this:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html&amp;gt;
  &amp;lt;head&amp;gt;
    &amp;lt;title&amp;gt;TeaVM example&amp;lt;/title&amp;gt;
    &amp;lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html;charset=utf-8&quot;&amp;gt;
    &amp;lt;script type=&quot;text/javascript&quot; charset=&quot;utf-8&quot; src=&quot;js/example.js&quot;&amp;gt;&amp;lt;/script&amp;gt;
  &amp;lt;/head&amp;gt;
  &amp;lt;body onload=&quot;main()&quot;&amp;gt;&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;or if you need WebAssembly, HTML file like this:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html&amp;gt;
  &amp;lt;head&amp;gt;
    &amp;lt;title&amp;gt;TeaVM WebAssembly example&amp;lt;/title&amp;gt;
    &amp;lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html;charset=utf-8&quot;&amp;gt;
    &amp;lt;script type=&quot;text/javascript&quot; charset=&quot;utf-8&quot; src=&quot;wasm-gc/example.wasm-runtime.js&quot;&amp;gt;&amp;lt;/script&amp;gt;
    &amp;lt;script&amp;gt;
      async function main() {
          let teavm = await TeaVM.wasmGC.load(&quot;wasm-gc/example.wasm&quot;);
          teavm.exports.main([]);
      }
    &amp;lt;/script&amp;gt;
  &amp;lt;/head&amp;gt;
  &amp;lt;body onload=&quot;main()&quot;&amp;gt;&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;now you can run &lt;code&gt;gradle build&lt;/code&gt; or, if you are using Gradle wrapper, &lt;code&gt;./gradlew build&lt;/code&gt; / &lt;code&gt;gradlew.bat build&lt;/code&gt;. Finally, take &lt;code&gt;.war&lt;/code&gt; file from &lt;code&gt;build/libs&lt;/code&gt; directory and deploy it to any compatible container or simply unzip and open &lt;code&gt;index.html&lt;/code&gt;.&lt;/p&gt; 
&lt;p&gt;Note that during development you can use Gretty plugin to serve you .war file via HTTP.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Wagon</title>
      <link>https://tedneward.github.io/Research/vms/wasm/wagon/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">vms/wasm/wagon/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/go-interpreter/wagon&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Implemented in Go. Interpreted.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>WASM3</title>
      <link>https://tedneward.github.io/Research/vms/wasm/wasm3/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">vms/wasm/wasm3/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/wasm3/wasm3&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Implemented in C. Interpreted.&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://wapm.io/package/vshymanskyy/wasm3&quot;&gt;Wasm3 on WAPM&lt;/a&gt; - WAPM package.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;&lt;strong&gt;Why use a &quot;slow interpreter&quot; versus a &quot;fast JIT&quot;?&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;In many situations, speed is not the main concern. Runtime executable size, memory usage, startup latency can be improved with the interpreter approach. Portability and security are much easier to achieve and maintain. Additionally, development impedance is much lower. A simple library like Wasm3 is easy to compile and integrate into an existing project. (Wasm3 builds in a just few seconds). Finally, on some platforms (i.e. iOS and WebAssembly itself) you can&apos;t generate executable code pages in runtime, so JIT is unavailable.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Why would you want to run WASM on embedded devices?&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;Wasm3 started as a research project and remains so by any means. Evaluating the engine in different environments is part of the research. Given that we have &lt;code&gt;Lua&lt;/code&gt;, &lt;code&gt;JS&lt;/code&gt;, &lt;code&gt;Python&lt;/code&gt;, &lt;code&gt;Lisp&lt;/code&gt;, &lt;code&gt;...&lt;/code&gt; running on MCUs, &lt;code&gt;WebAssembly&lt;/code&gt; is a promising alternative. It provides toolchain decoupling as well as a completely sandboxed, well-defined, predictable environment. Among practical use cases we can list &lt;code&gt;edge computing&lt;/code&gt;, &lt;code&gt;scripting&lt;/code&gt;, &lt;code&gt;plugin systems&lt;/code&gt;, running &lt;code&gt;IoT rules&lt;/code&gt;, &lt;code&gt;smart contracts&lt;/code&gt;, etc.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Interoperability with other languages&lt;/strong&gt;:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Python&lt;/li&gt; 
 &lt;li&gt;C/C++&lt;/li&gt; 
 &lt;li&gt;Rust&lt;/li&gt; 
 &lt;li&gt;Go&lt;/li&gt; 
 &lt;li&gt;Zig&lt;/li&gt; 
 &lt;li&gt;Swift&lt;/li&gt; 
 &lt;li&gt;C#/.Net&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;&lt;strong&gt;Non-MVP features supported&lt;/strong&gt;: Multi-Value, Bulk Memory Operations, Sign-extension operators, Non-trapping conversions, Name Section&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Host APIs supported&lt;/strong&gt;: WASI, Custom&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Non-web standards&lt;/strong&gt;: WASI, Gas Metering&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Used by&lt;/strong&gt;&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://wasmcloud.dev/&quot;&gt;wasmcloud&lt;/a&gt; - A platform for writing portable business logic&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://shareup.app/&quot;&gt;Shareup&lt;/a&gt; - Fast, private sharing for everyone&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://wowcube.com/&quot;&gt;WowCube&lt;/a&gt; - An nnovative console and the gaming platform&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/saghul/txiki.js&quot;&gt;txiki.js&lt;/a&gt; -A small and powerful JavaScript runtime&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Wasmi</title>
      <link>https://tedneward.github.io/Research/vms/wasm/wasmi/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">vms/wasm/wasmi/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/paritytech/wasmi&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Implemented in Rust. Interpreted.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Non-MVP features supported&lt;/strong&gt;:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Mutable Globals&lt;/li&gt; 
 &lt;li&gt;Sign-extension operators&lt;/li&gt; 
 &lt;li&gt;Non-trapping conversions&lt;/li&gt; 
 &lt;li&gt;Multi-Value&lt;/li&gt; 
 &lt;li&gt;Bulk Memory Operations&lt;/li&gt; 
 &lt;li&gt;Reference Types&lt;/li&gt; 
 &lt;li&gt;Tail Calls&lt;/li&gt; 
 &lt;li&gt;Extended Const&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;&lt;strong&gt;Non-web standards&lt;/strong&gt;&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;WASI&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;&lt;strong&gt;Used by&lt;/strong&gt;&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Substrate&lt;/li&gt; 
 &lt;li&gt;smoldot&lt;/li&gt; 
 &lt;li&gt;Ayaka Game Engine&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>WasmVM</title>
      <link>https://tedneward.github.io/Research/vms/wasm/wasmvm/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">vms/wasm/wasmvm/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/WasmVM/WasmVM&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Implemented in C++. Interpreted.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>webassembly</title>
      <link>https://tedneward.github.io/Research/vms/wasm/webasm/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">vms/wasm/webasm/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/dcodeIO/webassembly&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Implemented in Javascript using NodeJS/V8. JIT compiled.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>YARV (Yet Another Ruby VM)</title>
      <link>https://tedneward.github.io/Research/vms/yarv/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">vms/yarv/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://kddnewton.com/yarv/&quot;&gt;Instruction docs&lt;/a&gt; | &lt;a href=&quot;http://www.atdot.net/yarv/yarvarch.ja.html&quot;&gt;Design Document&lt;/a&gt;&lt;/p&gt; 
&lt;h2&gt;Articles&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;Compiling Ruby 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://lowlevelbits.org/compiling-ruby-part-0/&quot;&gt;Part 0&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://lowlevelbits.org/compiling-ruby-part-1/&quot;&gt;Part 1&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.hexdevs.com/posts/ruby-just-in-time-compiler-tenderjit/&quot;&gt;A Tender Introduction to Ruby Internals with TenderJIT&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://sitaramshelke.medium.com/inside-rubyvm-967b25e234db&quot;&gt;Inside RubyVM&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://i.loveruby.net/ja/rhg/book/&quot;&gt;Ruby source code complete explanation&lt;/a&gt; (Jul 2004) - Japanese text&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://magazine.rubyist.net/articles/0006/0006-YarvManiacs.html&quot;&gt;YARV maniacs&lt;/a&gt; - (May 2005) Japanese text&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://graysoftinc.com/the-ruby-vm-interview/the-ruby-vm-serial-interview&quot;&gt;The Ruby VM Serial Interview&lt;/a&gt; - (Feb 2007)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://lifegoo.pluskid.org/upload/doc/yarv/yarv_iset.html&quot;&gt;YARV instruction set&lt;/a&gt; - (Apr 2008)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://patshaughnessy.net/2012/6/29/how-ruby-executes-your-code&quot;&gt;How Ruby Executes Your Code (excerpt from Ruby Under a Microscope)&lt;/a&gt; - (Jun 2012)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.atdot.net/~ko1/diary/201212.html#d1&quot;&gt;ko1&apos;s 2012 Ruby VM advent calendar&lt;/a&gt; - (Dec 2012) Japanese text&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://qiita.com/sisshiki1969/items/3d25aa81a376eee2e7c2&quot;&gt;Ruby made with Rust&lt;/a&gt; - (Dec 2019)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://iliabylich.github.io/2020/01/25/evaluating-ruby-in-ruby.html&quot;&gt;Evaluating Ruby in Ruby&lt;/a&gt; - (Jan 2020)&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;&lt;a href=&quot;https://lifegoo.pluskid.org/upload/doc/yarv/yarv_iset.html&quot;&gt;Bytecode set&lt;/a&gt;&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;code&gt;adjuststack&lt;/code&gt;: accepts a single integer argument and removes that many elements from the top of the stack.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;anytostring&lt;/code&gt;: ensures that the value on top of the stack is a string.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;branchif&lt;/code&gt;: If the value popped off the stack is &lt;code&gt;true&lt;/code&gt;, branchif jumps to the jump index and continues executing there.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;branchnil&lt;/code&gt;: If the value popped off the stack is &lt;code&gt;nil&lt;/code&gt;, branchnil jumps to the jump index and continues executing there.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;branchunless&lt;/code&gt;: If the value popped off the stack is &lt;code&gt;false&lt;/code&gt; or &lt;code&gt;nil&lt;/code&gt;, branchunless jumps to the jump index and continues executing there.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;concatarray&lt;/code&gt;: concatenates the two Arrays on top of the stack.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;concatstrings&lt;/code&gt;: just pops a number of strings from the stack joins them together into a single string and pushes that string back on the stack.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;defined&lt;/code&gt;: checks if the top value of the stack is defined. If it is, it pushes its value onto the stack. Otherwise it pushes &lt;code&gt;nil&lt;/code&gt;.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;definemethod&lt;/code&gt;: defines a method on the class of the current value of &lt;code&gt;self&lt;/code&gt;.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;dup&lt;/code&gt;: copies the top value of the stack and pushes it onto the stack.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;dup_hash&lt;/code&gt;: pushes a hash onto the stack.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;duparray&lt;/code&gt;: copies a literal Array and pushes it onto the stack.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;dupn&lt;/code&gt;: duplicates the top n stack elements.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;expandarray&lt;/code&gt;: looks at the top of the stack, and if the value is an array it replaces it on the stack with num elements of the array, or nil if the elements are missing.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;getconstant&lt;/code&gt;: performs a constant lookup and pushes the value of the constant onto the stack.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;getglobal&lt;/code&gt;: pushes the value of a global variables onto the stack.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;getlocal&lt;/code&gt;: fetches the value of a local variable from a frame determined by the level and index arguments.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;getlocal_wc_0&lt;/code&gt;: is a specialized version of the getlocal instruction. It fetches the value of a local variable from the current frame determined by the index given as its only argument.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;getlocal_wc_1&lt;/code&gt;: is a specialized version of the getlocal instruction. It fetches the value of a local variable from the parent frame determined by the index given as its only argument.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;intern&lt;/code&gt;: converts top element from stack to a symbol.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;invokeblock&lt;/code&gt;: invokes the block passed to a method during a yield.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;jump&lt;/code&gt;: set PC to (PC + dst).&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;leave&lt;/code&gt;: exits the current frame.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;newarray&lt;/code&gt;: puts a new array initialized with size values from the stack.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;newhash&lt;/code&gt;: puts a new hash onto the stack, using num elements from the stack. num needs to be even.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;newrange&lt;/code&gt;: creates a Range.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;nop&lt;/code&gt;: is a no-operation instruction.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;objtostring&lt;/code&gt;: pops a value from the stack, calls to_s on that value and then pushes the result back to the stack.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;opt_and&lt;/code&gt;: a specialization of the opt_send_without_block instruction that occurs when the &amp;amp; operator is used.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;opt_aref&lt;/code&gt;: a specialization of the opt_send_without_block instruction that occurs when the [] operator is used.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;opt_aref_with&lt;/code&gt;: a specialization of the opt_aref instruction that occurs when the [] operator is used with a string argument known at compile time.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;opt_aset&lt;/code&gt;: an instruction for setting the hash value by the key in recv[obj] = set format.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;opt_aset_with&lt;/code&gt;: an instruction for setting the hash value by the known string key in the recv[obj] = set format.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;opt_case_dispatch&lt;/code&gt;: a branch instruction that moves the control flow for case statements.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;opt_div&lt;/code&gt;: a specialization of the opt_send_without_block instruction that occurs when the / operator is used.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;opt_empty_p&lt;/code&gt;: an optimization applied when the method empty? is called on a String, Array or a Hash.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;opt_eq&lt;/code&gt;: a specialization of the opt_send_without_block instruction that occurs when the == operator is used.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;opt_ge&lt;/code&gt;: a specialization of the opt_send_without_block instruction that occurs when the &amp;gt;= operator is used.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;opt_getinlinecache&lt;/code&gt;: a wrapper around a series of getconstant instructions that allows skipping past them if the inline cache is currently set.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;opt_gt&lt;/code&gt;: a specialization of the opt_send_without_block instruction that occurs when the &amp;gt; operator is used.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;opt_le&lt;/code&gt;: a specialization of the opt_send_without_block instruction that occurs when the &amp;lt;= operator is used.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;opt_length&lt;/code&gt;: a specialization of opt_send_without_block, when the length method is called on a Ruby type with a known size.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;opt_lt&lt;/code&gt;: a specialization of the opt_send_without_block instruction that occurs when the &amp;lt; operator is used.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;opt_ltlt&lt;/code&gt;: a specialization of the opt_send_without_block instruction that occurs when the &amp;lt;&amp;lt; operator is used.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;opt_minus&lt;/code&gt;: a specialization of the opt_send_without_block instruction that occurs when the - operator is used.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;opt_mod&lt;/code&gt;: a specialization of the opt_send_without_block instruction that occurs when the % operator is used.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;opt_mult&lt;/code&gt;: a specialization of the opt_send_without_block instruction that occurs when the * operator is used.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;opt_neq&lt;/code&gt;: an optimisation that tests whether two values at the top of the stack are not equal by testing their equality and performing a logical NOT on the result.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;opt_newarray_max&lt;/code&gt;: an instruction that represents calling max on an array literal. It is used to optimize quick comparisons of array elements.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;opt_newarray_min&lt;/code&gt;: an instruction that represents calling min on an array literal.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;opt_nil_p&lt;/code&gt;: an optimization applied when the method nil? is called.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;opt_not&lt;/code&gt;: negates the value on top of the stack.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;opt_or&lt;/code&gt;: a specialization of the opt_send_without_block instruction that occurs when the | operator is used.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;opt_plus&lt;/code&gt;: a specialization of the opt_send_without_block instruction that occurs when the + operator is used.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;opt_regexpmatch2&lt;/code&gt;: a specialization of the opt_send_without_block instruction that occurs when the =~ operator is used.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;opt_send_without_block&lt;/code&gt;: a specialization of the send instruction that occurs when a method is being called without a block.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;opt_setinlinecache&lt;/code&gt;: the final instruction after a series of getconstant instructions that populates the inline cache associated with an opt_getinlinecache instruction.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;opt_size&lt;/code&gt;: a specialization of opt_send_without_block, when the size method is called on a Ruby type with a known size.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;opt_str_freeze&lt;/code&gt;: pushes a frozen known string value with no interpolation onto the stack.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;opt_str_uminus&lt;/code&gt;: pushes a frozen known string value with no interpolation onto the stack.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;opt_succ&lt;/code&gt;: a specialization of the opt_send_without_block instruction when the method being called is succ.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;pop&lt;/code&gt;: pops the top value off the stack.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;putnil&lt;/code&gt;: pushes a global nil object onto the stack.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;putobject&lt;/code&gt;: pushes a known value onto the stack.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;putobject_int2fix_0&lt;/code&gt;: pushes 0 on the stack. It is a specialized instruction resulting from the operand unification optimization. It is the equivalent to putobject 0.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;putobject_int2fix_1&lt;/code&gt;: pushes 1 on the stack. It is a specialized instruction resulting from the operand unification optimization. It is the equivalent to putobject 1.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;putself&lt;/code&gt;: pushes the current value of self onto the stack.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;putstring&lt;/code&gt;: pushes a string literal onto the stack.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;send&lt;/code&gt;: invokes a method with a block.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;setglobal&lt;/code&gt;: sets the value of a global variable.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;setlocal&lt;/code&gt;: sets the value of a local variable on a frame determined by the level and index arguments. The level is the number of frames back to look and the index is the index in the local table. It pops the value it is setting off the stack.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;setlocal_wc_0&lt;/code&gt;: a specialized version of the setlocal instruction. It sets the value of a local variable on the current frame to the value at the top of the stack as determined by the index given as its only argument.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;setlocal_wc_1&lt;/code&gt;: a specialized version of the setlocal instruction. It sets the value of a local variable on the parent frame to the value at the top of the stack as determined by the index given as its only argument.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;setn&lt;/code&gt;: an instruction for set Nth stack entry to stack top.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;splatarray&lt;/code&gt;: calls to_a on an array to splat.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;swap&lt;/code&gt;: swaps the top two elements in the stack.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;topn&lt;/code&gt;: has one argument: n. It gets the nth element from the top of the stack and pushes it on the stack.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;toregexp&lt;/code&gt;: is generated when string interpolation is used inside a regex literal //. It pops a defined number of values from the stack, combines them into a single string and coerces that string into a Regexp object, which it pushes back onto the stack.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Tools&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/kddnewton/yarv&quot;&gt;YARV emulator written in Ruby&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Seax</title>
      <link>https://tedneward.github.io/Research/vms/seax/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">vms/seax/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/hawkw/seax&quot;&gt;Source&lt;/a&gt; | &lt;a href=&quot;https://github.com/hawkw/seax_svm&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>SPIM</title>
      <link>https://tedneward.github.io/Research/vms/spim/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">vms/spim/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://sourceforge.net/projects/spimsimulator/&quot;&gt;Source&lt;/a&gt; | &lt;a href=&quot;https://github.com/Tipoca/spim&quot;&gt;Source&lt;/a&gt; (Fork)&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>SushiVM</title>
      <link>https://tedneward.github.io/Research/vms/sushivm/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">vms/sushivm/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/eqela/sushivm&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Sushi is a fast and lightweight JIT-enabled virtual machine and dynamic language interpreter. It embeds and utilizes the LuaJIT interpreter and JIT engine and implements a fully custom-built cross-platform built-in API for Sushi applications. The entire virtual machine runs from a single executable and requires no particular installation. Executable Sushi programs can be compressed and appended to the executable, easily creating single-file executables that contain both the interpreter and application code. The executable size is about 400kb when dynamically linked and around 4MB when linked statically.&lt;/p&gt; 
&lt;p&gt;Sushi uses the Lua syntax as its native code format. While it is possible to write and execute hand-written Lua code on Sushi as well, the primary purpose of Sushi is to provide an optimal runtime environment for the Sling Programming Language.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>vm86</title>
      <link>https://tedneward.github.io/Research/vms/vm86/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">vms/vm86/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/tboox/vm86&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>SaberVM</title>
      <link>https://tedneward.github.io/Research/vms/sabervm/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">vms/sabervm/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/SaberVM/SaberVM&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;It will eventually have a number of implementations on different systems, and it will hopefully be easy enough to implement your own on your system/platform of choice.&lt;/p&gt; 
&lt;/blockquote&gt; 
&lt;h2&gt;From the README&lt;/h2&gt; 
&lt;h3&gt;What is SaberVM?&lt;/h3&gt; 
&lt;p&gt;SaberVM uses a typed stack-based bytecode language with compile-time and run-time instructions. Each instruction is one byte, though some instructions eat the next 1-4 bytes as a compile-time parameter. This all leads to a very expressive compile-time language for annotations that SaberVM uses for safety guarantees and, eventually, optimization.&lt;/p&gt; 
&lt;p&gt;By design, SaberVM will be able to be AOT-compiled with a number of optimizations, run on a JIT VM, or run on a simple VM for hobby projects or resource-constrained environments. Currently, a naive VM implementation is fairly fleshed-out, and being used as a prototype for rapid design iteration.&lt;/p&gt; 
&lt;p&gt;SaberVM has some of the resilience guarantees of the BEAM, and uses a concurrent semantics for being run in parallel or sequentially. It can also be compiled without memory safety runtime checks/tagging for a more LLVM-like experience. SaberVM is built on the research of &lt;a href=&quot;https://scholar.google.com/citations?user=Dswus94AAAAJ&amp;amp;hl=en&quot;&gt;Dr. Greg Morrisett&lt;/a&gt;, some of which (see Cyclone in &lt;a href=&quot;https://doc.rust-lang.org/reference/influences.html&quot;&gt;here&lt;/a&gt;) inspired Rust&apos;s memory safety model.&lt;/p&gt; 
&lt;p&gt;In a traditional CPS-based compiler pipeline, SaberVM is targeted after closure-conversion and hoisting, though like Erlang it will eventually have higher-level languages (namely Saber) to target and even use for projects.&lt;/p&gt; 
&lt;h3&gt;Why target SaberVM?&lt;/h3&gt; 
&lt;p&gt;A common choice for compiler backends is LLVM. However, for CPS-based compilers of functional languages, LLVM is not really an option. CPS is a good backend language for functional languages, for reasons that are too low-level to be expressed in LLVM&apos;s IR. LLVM is too tied to having C-style calling conventions and a return-address stack. In addition, functional languages (with pervasive immutability and recursion) can have their own set of good optimizations and heuristics that LLVM won&apos;t do. SaberVM aims to fill the vacuum left by LLVM, by being a CPS-based compiler backend oriented towards functional languages. However, it doesn&apos;t expect to be the only player in that field, and therefore makes opinionated tradeoffs. Namely, SaberVM tries to optimize for safety, portability, and expressivity.&lt;/p&gt; 
&lt;p&gt;SaberVM bytecode can guarantee memory safety and deadlock freedom, without a loss of expressivity. This is achieved in a way similar to &lt;a href=&quot;https://vale.dev/&quot;&gt;Vale&lt;/a&gt;, with a combination of borrow-checker-like compiler analysis and generational-reference-like runtime checks. These runtime checks don&apos;t crash the program when a dangling pointer is dereferenced, they instead put the program in a built-in panic mode so the broken parts of the program can be restarted, as in Erlang (but more low-level and manual).&lt;/p&gt; 
&lt;p&gt;This all combines to no loss in expressivity for safe programs, such that you can even write garbage collectors for your language without borrow-checker-induced nightmares. Supporting user-written garbage collectors is, of course, a hard requirement when we&apos;re trying to support functional languages. SaberVM&apos;s memory model finds a way to do this without compromising the soundness of the memory safety guarantees.&lt;/p&gt; 
&lt;p&gt;However, a compiler that cares more about performance than safety can turn off the runtime checks and tagging without any change to the bytecode; SaberVM&apos;s bytecode language is designed to be runtime-check-agnostic: proper resource handling is checked, not inferred.&lt;/p&gt; 
&lt;p&gt;SaberVM can also be used in a JVM-style, where the compiler simply outputs SaberVM bytecode and ships it to users, who have their own SaberVM or AOT-compiler. Thus they can run your program in a safe mode if they don&apos;t trust you (like websites), or a fast mode if they do (like games).&lt;/p&gt; 
&lt;h3&gt;How does it work?&lt;/h3&gt; 
&lt;p&gt;SaberVM has two main systems at play: regions and exceptions.&lt;/p&gt; 
&lt;h4&gt;Regions&lt;/h4&gt; 
&lt;p&gt;A region can be thought of as an arena with a malloc/free-style internal memory management system. To read or write from the heap, you need a region. Regions have statically-checked lifetimes and a borrow-checker-like system for checking that values within that region are only read or written to during the lifetime of the region. When a region&apos;s lifetime ends, it is freed like an arena. Doing borrow-checking on the scale of regions instead of values means that values can be freely mutated and aliased however you see fit; the system ensures that pointers into the region are never aliased after the region is freed, even if they continue to be passed around.&lt;/p&gt; 
&lt;p&gt;This structure of memory is important because in a safe compilation the values in the heap are tagged with information about which inhabitant is at that place in memory, so pointers can check that they&apos;re pointing at the thing they think they are when they&apos;re dereferenced. This introduces a memory fragmentation issue: &quot;slots&quot; in memory can then later be used only by values that are the same size or smaller; they have an unchangeable &quot;max size.&quot; To prove this, consider two values &lt;strong&gt;adjacent&lt;/strong&gt; in memory, &lt;code&gt;A&lt;/code&gt; and &lt;code&gt;B&lt;/code&gt;, and their pointers, &lt;code&gt;&amp;amp;A&lt;/code&gt; and &lt;code&gt;&amp;amp;B&lt;/code&gt;. Now say we free &lt;strong&gt;both&lt;/strong&gt;, and allocate &lt;code&gt;C&lt;/code&gt; at the same address where &lt;code&gt;A&lt;/code&gt; was (that is, &lt;code&gt;&amp;amp;C == &amp;amp;A&lt;/code&gt;). If &lt;code&gt;C&lt;/code&gt; is bigger than &lt;code&gt;A&lt;/code&gt; was, then it has arbitrary control of the bytes used to tag &lt;code&gt;B&lt;/code&gt;! &lt;code&gt;B&lt;/code&gt; has been freed, but now that &lt;code&gt;C&lt;/code&gt; controls those bytes, it could potentially make the bytes where &lt;code&gt;B&lt;/code&gt;&apos;s tag was appear to still show &lt;code&gt;B&lt;/code&gt; as unfreed. That means a nefarious program could potentially cause &lt;code&gt;&amp;amp;B&lt;/code&gt; to think that &lt;code&gt;B&lt;/code&gt; is still there, leading dereferences of &lt;code&gt;&amp;amp;B&lt;/code&gt; to read memory controlled by &lt;code&gt;C&lt;/code&gt;, instead of panicking.&lt;/p&gt; 
&lt;p&gt;The solution to this is to require that &lt;code&gt;C&lt;/code&gt; is no larger than the &lt;code&gt;A&lt;/code&gt; that was there before it. If allocating something in memory fixes a certain max-size for that bit of memory for the rest of the program&apos;s lifetime, that can cause issues with poor use of memory. Therefore, SaberVM puts its values in &lt;strong&gt;regions&lt;/strong&gt; so there are certain points in the program&apos;s lifecycle where it&apos;s statically known that nothing will dereference some set of pointers ever again, so their referent memory can be &lt;em&gt;really&lt;/em&gt; freed, with no restriction on its future use. As a language writer, if you find your output programs have significant fragmentation issues, you can do some light region inference to fix it. In addition, since regions are freed like arenas (reading uninitialized memory is statically prevented), regions offer a way to deallocate a bunch of memory instantly, and improve cache locality.&lt;/p&gt; 
&lt;h4&gt;Exceptions&lt;/h4&gt; 
&lt;p&gt;NOTE: this is currently unimplemented in the VM prototype, simply because I&apos;m just one person. You can &lt;a href=&quot;CONTRIBUTING.md&quot;&gt;contribute&lt;/a&gt; these things yourself (super appreciated!) or financially support me so I can work fewer hours at my day job, if you want to see these features sooner.&lt;/p&gt; 
&lt;p&gt;SaberVM&apos;s other interesting system is exceptions. Exceptions in SaberVM are not like normal exceptions, though there&apos;s nothing stopping a compiler writer from building a normal exception system on top of SaberVM. Instead, SaberVM exceptions &lt;strong&gt;don&apos;t take arguments&lt;/strong&gt;. Every function must have a catch-all exception case, and only that. Why? Having this built-in to SaberVM means that instructions that fail at runtime don&apos;t crash your program, they just jump to the exception handler. The language targeting SaberVM is then expected to produce exception handlers that do at least one of four things:&lt;/p&gt; 
&lt;ol&gt; 
 &lt;li&gt;crash the program (with an explicit &lt;code&gt;halt&lt;/code&gt; instruction)&lt;/li&gt; 
 &lt;li&gt;rethrow the exception (that is, jump to the &lt;em&gt;caller&apos;s&lt;/em&gt; catch-all exception handler)&lt;/li&gt; 
 &lt;li&gt;restart the crashed function (in a microreboot or Erlang style, without information about what caused the exception)&lt;/li&gt; 
 &lt;li&gt;release held resources (currently SaberVM doesn&apos;t have locks, only CAS, but this is likely to change)&lt;/li&gt; 
&lt;/ol&gt; 
&lt;p&gt;&lt;strong&gt;Note that SaberVM exceptions are not expected to be how your own language handles its exceptions!&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;For example, if you prefer a &lt;code&gt;Result&lt;/code&gt;-style exception handling, you can write functions that attempt single fallible instructions with an exception handler that produces the corresponding &lt;code&gt;Err&lt;/code&gt; value.&lt;/p&gt; 
&lt;h3&gt;The progress so far&lt;/h3&gt; 
&lt;p&gt;Currently work is underway on an MVP, that is, a simple non-JITing VM in Rust. Like Wasm, SaberVM bytecode must be verified before it is run. The project so far can parse an array of bytes, typecheck it, and execute it, but only supports a subset of the full SaberVM design. Thankfully, SaberVM has been designed to be easy to implement, so that languages targeting it can easily extend the number of platforms they support. Indeed, development has gone extremely swiftly so far.&lt;/p&gt; 
&lt;p&gt;The type checker uses a two-phase system: functions are forward-declared, and then their definitions are checked. This can be done in parallel trivially, though it isn&apos;t at the moment.&lt;/p&gt; 
&lt;p&gt;There are 27 instructions implemented right now, chosen to implement a simple &quot;duplicate&quot; function in naive CPS.&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;foo x = (x, x)
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;In SaberVM this has a fairly complex type:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;Forall r: Rgn, t: Type: 8-byte. (t, Exists u: 8-byte. ((u, (t, t)@r)-&amp;gt;0, u)@r, handle(r))-&amp;gt;0
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;To pick this apart a little, the function is quantified over a region, and a type that must be 8 bytes in size. &lt;code&gt;(a..)-&amp;gt;0&lt;/code&gt; is the syntax for a function type that takes the arguments &lt;code&gt;a..&lt;/code&gt;. The &lt;code&gt;-&amp;gt;0&lt;/code&gt; notation is to suggest that it&apos;s a CPS function, and therefore doesn&apos;t return. With the default region-quantification, you can imagine that &lt;code&gt;r&lt;/code&gt; is borrowed, if you&apos;re familiar with Rust. &lt;code&gt;Exists x: repr. t&lt;/code&gt; is an existential type, and is mostly used for typing closure environments. In this case, the continuation is existentially quantified so that it could have any closure environment struct. That is, a closure is typed at &lt;code&gt;Exists x. ((x, a..)-&amp;gt;0, x)@R&lt;/code&gt;. The &lt;code&gt;(a..)@R&lt;/code&gt; notation is product types (tuples) that are allocated in region &lt;code&gt;R&lt;/code&gt;. Finally, &lt;code&gt;handle(R)&lt;/code&gt; is the singleton type for the runtime information of a region &lt;code&gt;R&lt;/code&gt;, holding for example the pointer to the physical region in memory.&lt;/p&gt; 
&lt;p&gt;In summary, that type says that the function takes a value of type &lt;code&gt;t&lt;/code&gt;, a region &lt;code&gt;r&lt;/code&gt;, and a continuation that expects a value of type &lt;code&gt;(t, t)&lt;/code&gt; allocated in region &lt;code&gt;r&lt;/code&gt;. It also requires that &lt;code&gt;r&lt;/code&gt; hasn&apos;t been freed. That should seem like a reasonable type for the duplicate function. The richness of the information present in the type should hopefully justify how many compile-time instructions are used to construct it! Resorting too much to type inference would hurt the performance of the verifier asymptotically, so in the tradeoff between binary size and verifier performance I chose a faster verifier. Very small instructions helps the binary size a lot already.&lt;/p&gt; 
&lt;p&gt;I&apos;m also writing a little lambda-calculus &lt;a href=&quot;https://github.com/RyanBrewer317/SaberLC&quot;&gt;compiler&lt;/a&gt; to get much better tests of SaberVM.&lt;/p&gt; 
&lt;p&gt;This is very WIP; the purpose of this MVP is not to ship it per se, but mostly to play with the system and figure out what breaking changes need to be made. I&apos;ve already gone through several major rewrites and redesigns!&lt;/p&gt; 
&lt;p&gt;Polymorphism is currently just done in a simple Kinds-Are-Calling-Conventions-inspired approach, where the number of bytes of acceptible are specified by the quantifier. This is like given SaberVM a second, much simpler, C-like type system that has no polymorphism and only cares about numbers of bytes.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>SECD machine</title>
      <link>https://tedneward.github.io/Research/vms/secd/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">vms/secd/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/SECD_machine&quot;&gt;Wikipedia&lt;/a&gt; | &lt;a href=&quot;https://web.archive.org/web/20100620004154/http://fsl.cs.uiuc.edu/images/e/ef/P157-landin.pdf&quot;&gt;&quot;The next 700 programming languages&quot;&lt;/a&gt; | &lt;a href=&quot;https://pqnelson.github.io/org-notes/comp-sci/abstract-machines/secd.html&quot;&gt;SECD Machine&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;The letters stand for Stack, Environment, Control, Dump--the internal registers of the machine. The registers Stack, Control, and Dump point to (some realizations of) stacks, and Environment points to (some realization of) an associative array.&lt;/p&gt; 
&lt;h3&gt;Informal description&lt;/h3&gt; 
&lt;p&gt;When evaluation of an expression begins, the expression is loaded as the only element of control C. The environment E, stack S and dump D begin empty.&lt;/p&gt; 
&lt;p&gt;During evaluation of C it is converted to reverse Polish notation (RPN) with ap (for apply) being the only operator. For example, the expression F (G X) (a single list element) is changed to the list X:G:ap:F:ap.&lt;/p&gt; 
&lt;p&gt;Evaluation of C proceeds similarly to other RPN expressions. If the first item in C is a value, it is pushed onto the stack S. More exactly, if the item is an identifier, the value pushed onto the stack will be the binding for that identifier in the current environment E. If the item is an abstraction, a closure is constructed to preserve the bindings of its free variables (which are in E), and it is this closure which is pushed onto the stack.&lt;/p&gt; 
&lt;p&gt;If the item is ap, two values are popped off the stack and the application done (first applied to second). If the result of the application is a value, it is pushed onto the stack.&lt;/p&gt; 
&lt;p&gt;If the application is of an abstraction to a value, however, it will result in a lambda calculus expression that may itself be an application (rather than a value), and so cannot be pushed onto the stack. In this case, the current contents of S, E, and C are pushed onto the dump D (which is a stack of these triples), S is reinitialized to empty, and C is reinitialized to the application result with E containing the environment for the free variables of this expression, augmented with the binding that resulted from the application. Evaluation then proceeds as above.&lt;/p&gt; 
&lt;p&gt;Completed evaluation is indicated by C being empty, in which case the result will be on the stack S. The last saved evaluation state on D is then popped, and the result of the completed evaluation is pushed onto the stack contents restored from D. Evaluation of the restored state then continues as above.&lt;/p&gt; 
&lt;p&gt;If C and D are both empty, overall evaluation has completed with the result on the stack S.&lt;/p&gt; 
&lt;h3&gt;Registers and memory&lt;/h3&gt; 
&lt;p&gt;The SECD machine is stack-based. Functions take their arguments from the stack. The arguments to built-in instructions are encoded immediately after them in the instruction stream.&lt;/p&gt; 
&lt;p&gt;Like all internal data-structures, the stack is a list, with the S register pointing at the list&apos;s head or beginning. Due to the list structure, the stack need not be a continuous block of memory, so stack space is available as long as there is a single free memory cell. Even when all cells have been used, garbage collection may yield additional free memory. Obviously, specific implementations of the SECD structure can implement the stack as a canonical stack structure, thus improving the overall efficiency of the virtual machine, provided that a strict bound be put on the dimension of the stack.&lt;/p&gt; 
&lt;p&gt;The C register points at the head of the code or instruction list that will be evaluated. Once the instruction there has been executed, the C is pointed at the next instruction in the list—it is similar to an instruction pointer (or program counter) in conventional machines, except that subsequent instructions are always specified during execution and are not by default contained in subsequent memory locations, as is the case with the conventional machines.&lt;/p&gt; 
&lt;p&gt;The current variable environment is managed by the E register, which points at a list of lists. Each individual list represents one environment level: the parameters of the current function are in the head of the list, variables that are free in the current function, but bound by a surrounding function, are in other elements of E.&lt;/p&gt; 
&lt;p&gt;The dump, at whose head the D register points, is used as temporary storage for values of the other registers, for example during function calls. It can be likened to the return stack of other machines.&lt;/p&gt; 
&lt;p&gt;The memory organization of the SECD machine is similar to the model used by most functional language interpreters: a number of memory cells, each of which can hold either an atom (a simple value, for example 13), or represent an empty or non-empty list. In the latter case, the cell holds two pointers to other cells, one representing the first element, the other representing the list except for the first element. The two pointers are traditionally named car and cdr respectively—but the more modern terms head and tail are often used instead. The different types of values that a cell can hold are distinguished by a tag. Often different types of atoms (integers, strings, etc.) are distinguished as well.&lt;/p&gt; 
&lt;p&gt;So, a list holding the numbers 1, 2, and 3, usually written as (1 2 3), might be represented as follows:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;Address   Tag       Content (value for integers, car &amp;amp; cdr for lists)

      9 [ integer |     2 ]
      8 [ integer |     3 ]
      7 [ list    | 8 | 0 ]
      6 [ list    | 9 | 7 ]
      ...
      2 [ list    | 1 | 6 ]
      1 [ integer |     1 ]
      0 [ nil             ]
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;The memory cells 3 to 5 do not belong to our list, the cells of which can be distributed randomly over the memory. Cell 2 is the head of the list, it points to cell 1, which holds the first element&apos;s value, and the list containing only 2 and 3 (beginning at cell 6). Cell 6 points at a cell holding 2 and at cell 7, which represents the list containing only 3. It does so by pointing at cell 8 containing the value 3, and pointing at an empty list (nil) as cdr. In the SECD machine, cell 0 always implicitly represents the empty list, so no special tag value is needed to signal an empty list (everything needing that can simply point to cell 0).&lt;/p&gt; 
&lt;p&gt;The principle that the cdr in a list cell must point at another list is just a convention. If both car and cdr point at atoms, that will yield a pair, usually written like (1 . 2)&lt;/p&gt; 
&lt;h3&gt;Instructions&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;code&gt;nil&lt;/code&gt; pushes a nil pointer onto the stack&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;ldc&lt;/code&gt; pushes a constant argument onto the stack&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;ld&lt;/code&gt; pushes the value of a variable onto the stack. The variable is indicated by the argument, a pair. The pair&apos;s car specifies the level, the cdr the position. So (1 . 3) gives the current function&apos;s (level 1) third parameter.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;sel&lt;/code&gt; expects two list arguments, and pops a value from the stack. The first list is executed if the popped value was non-nil, the second list otherwise. Before one of these list pointers is made the new C, a pointer to the instruction following &lt;code&gt;sel&lt;/code&gt; is saved on the dump.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;join&lt;/code&gt; pops a list reference from the dump and makes this the new value of C. This instruction occurs at the end of both alternatives of a sel.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;ldf&lt;/code&gt; takes one list argument representing a function. It constructs a closure (a pair containing the function and the current environment) and pushes that onto the stack.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;ap&lt;/code&gt; pops a closure and a list of parameter values from the stack. The closure is applied to the parameters by installing its environment as the current one, pushing the parameter list in front of that, clearing the stack, and setting C to the closure&apos;s function pointer. The previous values of S, E, and the next value of C are saved on the dump.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;ret&lt;/code&gt; pops one return value from the stack, restores S, E, and C from the dump, and pushes the return value onto the now-current stack.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;dum&lt;/code&gt; pushes a &quot;dummy&quot;, an empty list, in front of the environment list.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;rap&lt;/code&gt; works like &lt;code&gt;ap&lt;/code&gt;, only that it replaces an occurrence of a dummy environment with the current one, thus making recursive functions possible&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;A number of additional instructions for basic functions like car, cdr, list construction, integer addition, I/O, etc. exist. They all take any necessary parameters from the stack.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Squeak VM</title>
      <link>https://tedneward.github.io/Research/vms/squeakvm/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">vms/squeakvm/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;http://wiki.squeak.org/squeak/1447&quot;&gt;Website&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://github.com/victorr/jsqueak&quot;&gt;JSqueak&lt;/a&gt;: JVM-based port of Squeak, originally at &lt;a href=&quot;http://research.sun.com/projects/JSqueak/&quot;&gt;Sun Research&lt;/a&gt; but since closed down.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>TopazRuby</title>
      <link>https://tedneward.github.io/Research/vms/topazruby/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">vms/topazruby/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;http://topazruby.com/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/topazproject/topaz&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>aWsm</title>
      <link>https://tedneward.github.io/Research/vms/wasm/awsm/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">vms/wasm/awsm/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/gwsystems/aWsm&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Implemented in Rust, C using LLVM&lt;/p&gt; 
&lt;p&gt;AOT compilation&lt;/p&gt; 
&lt;p&gt;Interop with C&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Salt</title>
      <link>https://tedneward.github.io/Research/vms/salt/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">vms/salt/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/discus-lang/salt&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Salt is a System-F variant intended as an intermediate language between higher level languages and an abstract assembly language (LLVM). Hand written code can also be used to implement runtime systems. The Disco Discus Compiler uses an earlier version of Salt (v1), and its runtime system is written in it. This current repo contains a newer version of Salt (v2) which is being split out into its own project. Salt v1 has a working LLVM backend, but the one for v2 in this repo is still a work in progress.&lt;/p&gt; 
&lt;p&gt;This project is a V2; see the Github for more notes and links to V1.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>SmallVM</title>
      <link>https://tedneward.github.io/Research/vms/smallvm/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">vms/smallvm/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/shanhuio/smlvm&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>STABLE</title>
      <link>https://tedneward.github.io/Research/vms/stable/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">vms/stable/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://w3group.de/stable.html&quot;&gt;Website&lt;/a&gt; | Source on site&lt;/p&gt; 
&lt;p&gt;Stable (STAck Bytecode Language &amp;amp; Engine) is an extreme minimal but useful stack oriented virtual machine, currently written in C (200 lines of extensively commented C code. The original comes with 47 lines of C code). The machine language consists only of printable letters which make it simple hackable with an editor. The goal of this engine is to be human hackable, simple and fast. So there are no complicated address calculations (for branch and jump addresses) and an easy to use instruction set. (43 instructions, 26 registers, 26 user defineable functions)&lt;/p&gt; 
&lt;p&gt;To avoid addresses to variables (registers) and functions, names are predefined. So instead of given the address for a function there is an ASCII opcode for that. Functions are upper case letters from A to Z which leads to 26 user defineable functions, registers are named from a to z (lower letter) which leads to 26 registers.&lt;/p&gt; 
&lt;h3&gt;Instructions&lt;/h3&gt; 
&lt;p&gt;From &lt;a href=&quot;https://w3group.de/stable_glossar.html&quot;&gt;here&lt;/a&gt;:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;arithmetic
+  ( a b--a+b) addition
-  ( a b--a-b) subtraction
*  ( a b--a*b) multiply
/  ( a b--a/b) division
%  ( a b--a%b) modulo (division reminder)
_  (   n-- -n) negate

bit manipulation
&amp;amp; ( a b--a&amp;amp;b)  32 bits and
|  ( a b--a|b) 32 bits or
~  (  n -- n&apos;) not, all bits inversed (0=&amp;gt;1 1=&amp;gt;0)

stack
#  ( a--a a) duplicate top of stack
\  ( a b--a) drop top of stack
$  ( a b--b a) swap top of stack
@  ( a b--a b a) (over) copy next of stack on top

register
x  ( --)  select register x (x: a..z)
;  ( --value) fetch from selected register
:  ( value--) store into selected register
?  ( --value) selected register contains an address. Fetch value from there
!  ( value--) selected register contains an address. Store value there.
+  ( --) immediately after register, increment content by 1
-  ( --) immediately after register, decrement content by 1

functions
{X ( --)  start function definition for function X (A..Z)
}  ( --)  end of function definition
X  ( --)  call function X (A..Z)

I/O
.  ( value--) display value as decimal number on stdout
,  ( value--) send value to terminal, 27 is ESC, 10 is newline, etc.
^  ( --key)   read key from terminal, don&apos;t wait for newline.
&quot;  ( --)      read string until next &quot; put it on stdout
0..9 ( --value) scan decimal number until non digit. to push two values
              on stack separete those by space (4711 3333)
              to enter negative numbers call _ (negate) after the number
0..9.0 ( --value) to enter float numbers digits must contain one . (only
              available if float module is active, see 0`)

conditions
&amp;lt; ( a b--f)  true (-1) if b is &amp;lt; a, false (0) otherwise
&amp;gt; ( a b--f)  true (-1) if b is &amp;gt; a, false (0) otherwise
= ( a b--f) true (-1) if a is queal to b, flase (0) otherwise
( ( f--) if f is true, execute content until ), if false
         skip code until )
[ ( f--f) begin while loop only if f is true. keep flag on stack
          if f is false, skip code until ]
] ( f--)  repeat the loop if f is true. If f is false, continue
          with code after ]

extensions (expermiental)
` ( n--) call extension function n
         0  ... switch to floating point mode
                 + - * / . _ &amp;lt; &amp;gt;

         1  ... switch back to interger mode
         2  ... dbg, function dbg() to set breakpoint for debugging
         3  ... switch traceing on (IP, TOKEN, SP, STACK) (not in stable_fast)
         4  ... switch traceing off. Tracing int file trace
         5  ... &amp;lt; = &amp;gt; without dropping their 2nd operand (NOS). This
                is the behavior of Santors original virtual engine.
         6  ... mstime, time in milliseconds, for timing
         7  ... ( n--) edit block number n
         8  ... ( n--) load block number n. Data segment remains. So this
			       is a kind of shared memory. Registers could be used as arguments.
					 After leaving the application and 0 is on TOS, STABLE will be
					 terminated. A value not equal 0 on TOS will load this block.
					 If the block is not valid, the command block will be loaded
					 Use block 0 as an index for all your block numbers
    9  ... ( n 9--) copy block n (1000 cells) into memory begining of 1000.
           write back the old content before. At exit write back current 
           data block. STABLE is starting with block 0 loaded.
   10  ... trace only current state (ip, rp, sp, ..) on stdout
   11  ... quit VM ( n--) n is exit code to os
   12  ... ( --n) push current data block number on stack
   13  ... ( --)  copy 1000 cells from address 1000 to 2000
   14  ... ( --)  copy 1000 cells from address 2000 to 1000
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;Interpreter&lt;/h3&gt; 
&lt;p&gt;Source in a single C file; there is a &lt;a href=&quot;https://w3group.de/stable_fast.c&quot;&gt;fast version&lt;/a&gt; and a &lt;a href=&quot;https://w3group.de/stable_debug.c&quot;&gt;debugging&lt;/a&gt; version, supping single-step monitoring:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;/* stable.c  interpreter:
 *
 * Idea and_ implementation    Sandor Schneider
 * Refactoring and extended   Andreas Klimas   klimas@w3group.de
 *
 * Tracing and Floating point as extension (see stable_glossar.html)
 * IDE, source and code blocks
 *
 *
 */

#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;
#include &amp;lt;setjmp.h&amp;gt;
#include &amp;lt;string.h&amp;gt;
#include &amp;lt;ctype.h&amp;gt;
#include &amp;lt;unistd.h&amp;gt;
#include &amp;lt;termios.h&amp;gt;
#include &amp;lt;signal.h&amp;gt;
#include &amp;lt;sys/time.h&amp;gt;
#include &amp;lt;sys/stat.h&amp;gt;

extern void (*words[])(void);
static FILE *trace_fp;

static int cur_reg,ip;  // selected register, instruction pointer
static int data[4000];// data segment (register and memory)
static char sp=-1,rp=-1,token,k,code[4096];// data stack pointer, return stack pointer,  current executed token, and code segment
static int stack[256]; // data stack
static int rstack[256]; // return stack
static short fentry[256];// startaddress of functions A-Z
static int is_trace, is_flt; // trace mode, floating point mode
static int cur_code_block; // current code block;
static int cur_data_blk; // current data block
static FILE *data_fp; // database file, permanent open

static struct termios oldterm; // for later use onexit()
static jmp_buf do_halt;
static sigjmp_buf do_sigint;

static void trace(void) ;

static void noop(void){}                                   // 01..32
static void grow(int delta) {
	int empty[4000];
	memset(empty, 0, sizeof(empty));
	fseek(data_fp, 0, SEEK_END);
	int i;
	for(i=0;i&amp;lt;delta;i++) {
		fwrite(empty, 1, sizeof(empty), data_fp);
	}
}
static void select_block(int blknr) {
	cur_data_blk=blknr;
	struct stat sb;
	fstat(fileno(data_fp), &amp;amp;sb);
	unsigned blks=sb.st_size/4000;
	if((cur_data_blk+1)&amp;gt;blks) grow(blks-cur_data_blk+10);

	fseek(data_fp, cur_data_blk*sizeof(int)*1000, SEEK_SET);
	fread(data+1000, sizeof(int), 1000, data_fp);
}
static void blocknr(void) {stack[++sp]=cur_data_blk;}
static void save_block(void) {
	tcsetattr(0, 0, &amp;amp;oldterm);
	fseek(data_fp, cur_data_blk*sizeof(int)*1000, SEEK_SET);
	fwrite(data+1000, sizeof(int), 1000, data_fp);
}
static void block(void) {
	save_block(); // write back current block
	select_block(stack[sp--]);
}
static int one_key(void) {
	struct termios t;

	fflush(stdout);
	if (!isatty(0)) return 0;

	tcgetattr(0, &amp;amp;oldterm);
	tcgetattr(0, &amp;amp;t);
	t.c_iflag &amp;amp;= ~(ICRNL | ICRNL | IXON|IXANY|IXOFF);
	t.c_iflag |= BRKINT;
	t.c_oflag &amp;amp;= ~OPOST;
 	t.c_lflag &amp;amp;= ~(ICANON | ECHO);
	t.c_lflag |= ISIG;
	t.c_cc[4]  = 1;
	tcsetattr(0, 0, &amp;amp;t);
	int c=0;
	read(0, &amp;amp;c, 1);
	tcsetattr(0, 0, &amp;amp;oldterm);
	return c;
}
static void halt(void) {longjmp(do_halt,1);}               // 0-Byte
static void store(void){data[data[cur_reg]]=stack[sp];sp--;}// !
static void print(void){char c; while((c=code[ip++])!=&apos;\&quot;&apos;) putc(c,stdout);} // &quot;
static void character(void){stack[++sp]=code[ip++];}
static void system_(void){ // ` system
	char buffer[256], *p=buffer, *end=buffer+sizeof(buffer)-1;
	char c;
	while((c=code[ip++])!=&apos;`&apos;) if(p&amp;lt;end) *p++=c;
	*p=0;
	system(buffer);
}
static void mstime(void) {
	struct timeval tv[1];
	gettimeofday(tv, 0);
   stack[++sp]=1000*tv-&amp;gt;tv_sec+tv-&amp;gt;tv_usec/1000;
}
static void dup_(void){sp++; stack[sp]=stack[sp-1]; }        // #
static void modulo(void){stack[sp-1]%=stack[sp];sp--;}       // %
static void and_(void){stack[sp-1]&amp;amp;=stack[sp];sp--;}          // &amp;amp; bitwise and_
static void if_(void){if(!stack[sp--]) while(code[ip++]!=&apos;)&apos;);} // (..)
static void mul(void){stack[sp-1]*=stack[sp]; sp--;}         // *
static void emit(void){printf(&quot;%c&quot;,stack[sp--]);}           // ,
static void dot(void){printf(&quot;%d&quot;,stack[sp--]);}            // . print digit
static void div_(void){stack[sp-1]/=stack[sp]; sp--; }       // / division
static void reg_get(void){data[cur_reg]=stack[sp--]; k=0; } // :
static void reg_set(void){stack[++sp]=data[cur_reg]; k=0; } // ;
static void lessv1(void){stack[sp]=stack[sp]&amp;gt;stack[sp-1]?-1:0; }      // &amp;lt;
static void equalv1(void){stack[sp]=stack[sp]==stack[sp-1]?-1:0; }    // =
static void greaterv1(void){stack[sp]=stack[sp]&amp;lt;stack[sp-1]?-1:0; }   // &amp;gt;
static void less(void){stack[sp-1]=stack[sp]&amp;gt;stack[sp-1]?-1:0; sp--;}      // &amp;lt;
static void equal(void){stack[sp-1]=stack[sp]==stack[sp-1]?-1:0; sp--;}    // =
static void greater(void){stack[sp-1]=stack[sp]&amp;lt;stack[sp-1]?-1:0; sp--;}   // &amp;gt;
static void fetch(void){stack[++sp]=data[data[cur_reg]];}   // ?
static void drop(void){sp--;}                              /* \    */
static void key(void){int c=one_key();stack[++sp]=c;}// ^ read char, push on stack 
static void negate(void){stack[sp]=-stack[sp]; }             // _
static void reg(void){k=1; cur_reg=token-97; }             // a-z
static void enddef(void){ip=rstack[rp--];}                   // } end of definition, return from subroutine
static void or_(void){stack[sp-1]|=stack[sp]; sp--; }         // |
static void not_(void){ stack[sp]=~stack[sp]; } // ~ bitwise inverse (not_)
static void add(void){ // + or_ increment register
	if(k) {data[cur_reg]++; k=0;}
	else {stack[sp-1]+=stack[sp]; sp--;}
}
static void sub(void){ // - sub or_ decrement register
	if(k) {data[cur_reg]--; k=0;}
	else {stack[sp-1]-=stack[sp]; sp--;}
}
static void digit(void){ /* build a number */
	int i=0;
	do {
		i=i*10+token-&apos;0&apos;;
	} while((token=code[ip++])&amp;amp;&amp;amp;(isdigit(token))) ;
	stack[++sp]=i;
	ip--;
}
static void swap(void){                                    // $
	int i=stack[sp];
	stack[sp]=stack[sp-1];
	stack[sp-1]=i;
}
static void over(void){                                     // @
	int i=stack[sp-1];
	stack[++sp]=i;
}
static void call(void){ // A..Z Call word
	rstack[++rp]=ip; // push current instruction pointer on return stack
	ip=fentry[token-65]; // jump to word in token
}
static void while_(void){ // [. top of stack will be droped on end of loop
	rstack[++rp]=ip; // push current instruction pointer, for looping
	// top of stack is false (0), so terminate loop
	char c;
	if(!stack[sp]) while((c=code[ip++]) &amp;amp;&amp;amp; (c!=&apos;]&apos;)) ;
}
static void endwhile(void){ // ] (code 93)
	if(stack[sp]) ip=rstack[rp]; // jump back to [ if top of stack is not_ zeor
	else rp--; // clean up return and_ data stack

	sp--; // drop datastack in any case
}
static void ext(void) {
	token=stack[sp--];
	words[token+130]();
}
static void def(void){ // { define word
	char i=code[ip++]-65;
	fentry[i]=ip; // point to code where definition already remains
	char c;
	while((c=code[ip++]) &amp;amp;&amp;amp; (c!=&apos;}&apos;)); // skip forward to } (end of definition)
}
static void flt_dot(void) {    /*.*/ 
	printf(&quot;%f&quot;,*(float*)&amp;amp;stack[sp--]);
}
static void flt_less(void) {
	int i=stack[sp--];
	stack[sp]=(*(float*)&amp;amp;i)&amp;gt;*(float*)&amp;amp;stack[sp]?-1:0;
}
static void flt_greater(void) {
	int i=stack[sp--];
	stack[sp]=(*(float*)&amp;amp;i)&amp;lt;(*(float*)&amp;amp;stack[sp])?-1:0;
}
static void flt_negate(void) {
	float f=(*(float*)&amp;amp;stack[sp])*-1.0;
	stack[sp]=*(int*)&amp;amp;f;
}
static void flt_mul(void) {
	float i=*(float*)&amp;amp;stack[sp--];
	*(float*)&amp;amp;stack[sp]=(*(float*)&amp;amp;stack[sp])*i;
}
static void flt_div(void) {
	float i=*(float*)&amp;amp;stack[sp--];
	*(float*)&amp;amp;stack[sp]=(*(float*)&amp;amp;stack[sp])/i;
}
static void flt_add(void) {  // + or_ increment register
	if(k) {data[cur_reg]++; k=0;}
	else {
		float i=*(float*)&amp;amp;stack[sp--];
		*(float*)&amp;amp;stack[sp]=(*(float*)&amp;amp;stack[sp])+i;
	}
}
static void flt_sub(void) {  // + or_ increment register
	if(k) {data[cur_reg]--;k=0;}
	else {
		float i=*(float*)&amp;amp;stack[sp--];
		*(float*)&amp;amp;stack[sp]=(*(float*)&amp;amp;stack[sp])-i;
	}
}
static void flt_digit(void) {  /* build a number */
	float val;
	char buffer[32], *p=buffer;
	int has_dot=0;
	int tos=0;
	do {
		if(token==&apos;.&apos;) has_dot=1;
		*p++=token;
	} while((token=code[ip++])&amp;amp;&amp;amp;(isdigit(token)||(!has_dot&amp;amp;&amp;amp;(token==&apos;.&apos;)))) ;
	*p=0;
	if(has_dot) {
		val=strtof(buffer, 0);
		tos=*(int*)&amp;amp;val;
	} else {
		tos=strtol(buffer, 0, 0);
	}
	stack[++sp]=tos;

	ip--;
}
static void flt(void) { /*000*/
	is_flt=1;
	words[46]=flt_dot;
	words[60]=flt_less;
	words[62]=flt_greater;
	words[95]=flt_negate;
	words[42]=flt_mul;
	words[47]=flt_div;
	words[43]=flt_add;
	words[45]=flt_sub;
	words[48]=flt_digit;
	words[49]=flt_digit;
	words[50]=flt_digit;
	words[51]=flt_digit;
	words[52]=flt_digit;
	words[53]=flt_digit;
	words[54]=flt_digit;
	words[55]=flt_digit;
	words[56]=flt_digit;
	words[57]=flt_digit;
}
static void unflt(void) {/*001*/
	is_flt=0;
	words[46]=dot;
	words[60]=less;
	words[62]=greater;
	words[95]=negate;
	words[42]=mul;
	words[47]=div_;
	words[43]=add;
	words[45]=sub;
	words[48]=digit;
	words[49]=digit;
	words[50]=digit;
	words[51]=digit;
	words[52]=digit;
	words[53]=digit;
	words[54]=digit;
	words[55]=digit;
	words[56]=digit;
	words[57]=digit;
}
static void traceon(void) {is_trace=1;}
static void traceoff(void) {is_trace=0;}
static void edit(void) {
	char buffer[32];
	snprintf(buffer, sizeof(buffer), &quot;vi %d&quot;, stack[sp--]);
	system(buffer);
}
static void load(void) {
	char buffer[8];
	cur_code_block=stack[sp--];
	if(!cur_code_block) cur_code_block=99;
	snprintf(buffer, sizeof(buffer), &quot;%d&quot;, cur_code_block);
	FILE *fp=fopen(buffer, &quot;r&quot;);
	if(!fp) {
		cur_code_block=99;
		fp=fopen(&quot;99&quot;, &quot;r&quot;); // 99 is edit block
	}
	if(fp) {
		code[fread(code, 1, sizeof(code)-1, fp)]=0;
		fclose(fp);

		memset(stack, 0, sizeof(stack));
		memset(rstack, 0, sizeof(rstack));
		memset(fentry, 0, sizeof(fentry));
		sp=rp=-1;
		cur_reg=0;
		ip=0;
		traceoff();
		unflt();
		longjmp(do_halt,9);
	} else {
		printf(&quot;no block %s\n&quot;, buffer);
	}
}
static void version1(void) {
	/* &amp;lt; 60 */  words[&apos;&amp;lt;&apos;]=lessv1;
	/* = 61 */  words[&apos;=&apos;]=equalv1;
	/* &amp;gt; 62 */  words[&apos;&amp;gt;&apos;]=greaterv1;
	/* ` 96 */  words[&apos;`&apos;]=system_;
}
static void quit(void) {exit(stack[sp--]);}
static void btod(void) {memcpy(data+2000, data+1000, sizeof(int)*1000);}
static void dtob(void) {memcpy(data+1000, data+2000, sizeof(int)*1000);}
static void dbg(void) {
}
void (*words[])(void)={
/*        0      1      2       3        4       5        6       7      8       9 */
/*  0*/ halt,  noop,  noop,   noop,    noop,    noop,    noop,   noop,  noop,   noop,
/* 10*/ noop,  noop,  noop,   noop,    noop,    noop,    noop,   noop,  noop,   noop,
/* 20*/ noop,  noop,  noop,   noop,    noop,    noop,    noop,   noop,  noop,   noop,
/* 30*/ noop,  noop,  noop,   store,   print,   dup_,    swap,   modulo,and_,    ext,
/* 40*/ if_,   noop,  mul,    add,     emit,    sub,     dot,    div_,  digit,  digit,
/* 50*/ digit, digit, digit,  digit,   digit,   digit,   digit,  digit, reg_get,reg_set,
/* 60*/ less,  equal, greater,fetch,   over,    call,    call,   call,  call,   call,
/* 70*/ call,  call,  call,   call,    call,    call,    call,   call,  call,   call,
/* 80*/ call,  call,  call,   call,    call,    call,    call,   call,  call,   call,
/* 90*/ call,  while_,drop,   endwhile,key,     negate,  character,reg,   reg,    reg,
/*100*/ reg,   reg,   reg,    reg,     reg,     reg,     reg,    reg,   reg,    reg,
/*110*/ reg,   reg,   reg,    reg,     reg,     reg,     reg,    reg,   reg,    reg,
/*120*/ reg,   reg,   reg,    def,     or_,     enddef,  not_,   noop,  noop,   noop,
/*130*/ flt,   unflt, dbg,    traceon, traceoff,version1,mstime, edit,  load,   block,
/*140*/ trace, quit,  blocknr,btod,    dtob,    noop,    noop,   noop,  noop,   noop,
/*150*/ noop , noop,  noop   ,noop,    noop,    noop,    noop,   noop,  noop,   noop,
/*160*/ noop , noop,  noop   ,noop,    noop,    noop,    noop,   noop,  noop,   noop,
/*170*/ noop , noop,  noop   ,noop,    noop,    noop,    noop,   noop,  noop,   noop,
/*180*/ noop , noop,  noop   ,noop,    noop,    noop,    noop,   noop,  noop,   noop,
/*190*/ noop , noop,  noop   ,noop,    noop,    noop,    noop,   noop,  noop,   noop,
/*200*/ noop , noop,  noop   ,noop,    noop,    noop,    noop,   noop,  noop,   noop,
};

static void trace_out_program(void) {
	if(!trace_fp) trace_fp=fopen(&quot;trace&quot;, &quot;a&quot;);
	int i=0;
	fprintf(trace_fp, &quot;blk:%d\n&quot;, cur_code_block);
	fprintf(trace_fp, &quot;code    0123456789 123456789 123456789 123456789&quot;);
	char *p=code, c;
	while(c=*p++) {
		if(i--==0) {
			fprintf(trace_fp, &quot;\n %4ld:  &quot;, p-code-1);
			i=39;
		}
		fputc(isprint(c)?c:&apos; &apos;, trace_fp);
	}
	fprintf(trace_fp, &quot;\n\n&quot;);
}
static char *tr_header=&quot; ip:code:reg:value:mem  :rp: rp0 rp1 rp2:sp:  TOS  sp1  sp2  sp3\n&quot;;
static void trace_header(void) {
	trace_out_program();
	fputs(tr_header, trace_fp);
}
static void trace_start_data(void) {
	static int header;

	if(!header++) trace_header();
	fprintf(trace_fp, &quot;%3d:&quot;, ip-1);
	if(isprint(token)) {
		fprintf(trace_fp, &quot;   %c:&quot;, token);
	} else {
		fprintf(trace_fp, &quot;\\%03d:&quot;,token);
	}
}
static void trace_data(void) {
	static int lines;
	int i=data[cur_reg];
	fprintf(trace_fp, &quot;  %c:%5d:&quot;, cur_reg+&apos;a&apos;, data[cur_reg]);
	if(i&amp;gt;=0 &amp;amp;&amp;amp; i&amp;lt;sizeof(data)/sizeof(int)) {
		fprintf(trace_fp, &quot;%5d&quot;, data[i]);
	}
	fprintf(trace_fp, &quot;:%2d:&quot;, (char)(rp+1));
	fprintf(trace_fp, &quot;%4d&quot;, rstack[rp]);
	fprintf(trace_fp, &quot;%4d&quot;, rstack[rp-1]);
	fprintf(trace_fp, &quot;%4d&quot;, rstack[rp-2]);
	fprintf(trace_fp, &quot;:%2d:&quot;, (char)(sp+1));
	char s=sp;
	if(is_flt) {
		fprintf(trace_fp, &quot;%5d(%f)&quot;, stack[s], *(float*)&amp;amp;stack[s]); s--;
		fprintf(trace_fp, &quot;%5d(%f)&quot;, stack[s], *(float*)&amp;amp;stack[s]); s--;
		fprintf(trace_fp, &quot;%5d(%f)&quot;, stack[s], *(float*)&amp;amp;stack[s]); s--;
		fprintf(trace_fp, &quot;%5d(%f)&quot;, stack[s], *(float*)&amp;amp;stack[s]);
	} else {
		fprintf(trace_fp, &quot;%5d&quot;, stack[s]); s--;
		fprintf(trace_fp, &quot;%5d&quot;, stack[s]); s--;
		fprintf(trace_fp, &quot;%5d&quot;, stack[s]); s--;
		fprintf(trace_fp, &quot;%5d&quot;, stack[s]);
	}
	fprintf(trace_fp,&quot;\n&quot;);
	if(lines++==20) {
		lines=0;
		fputc(&apos;\n&apos;, trace_fp);
		trace_header();
	}
}
static void sigint_handler(int sig) {
	siglongjmp(do_sigint, 1);
}
static void trace(void) {
	printf(&quot;blk=%d:ip=%d:reg=%c:value=%d:mem=&quot;, cur_code_block,ip, cur_reg+&apos;a&apos;,data[cur_reg]);
	int i=data[cur_reg];
	if(i&amp;gt;=0 &amp;amp;&amp;amp; i&amp;lt;sizeof(data)/sizeof(int)) {
		printf(&quot;%d&quot;, data[i]);
	}
	printf(&quot;:rp=%d:%d %d %d:sp=%d:%d %d %d %d:\n&quot;,
		rp, rstack[rp],rstack[rp-1],rstack[rp-2],
		sp, stack[sp],stack[sp-1],stack[sp-2],stack[sp-3]);
		
}
int main(int argc,char *argv[]){
	FILE *be=fopen(argv[1], &quot;r&quot;); 
	if (!be) be=fopen(&quot;99&quot;, &quot;r&quot;); // command line
	if (!be) {printf(&quot;usage stable filename [args]\n&quot;); return 1;}

	fread(code, 1, sizeof(code), be); // read program into memory
	fclose(be);

	int i;
	for(i=2;i&amp;lt;argc;i++) data[i-2]=atoi(argv[i]); // set arguments into registers

	data_fp=fopen(&quot;stable.db&quot;, &quot;r+&quot;);
	if(!data_fp) data_fp=fopen(&quot;stable.db&quot;, &quot;w+&quot;);
	select_block(0);
	atexit(save_block);
	signal(SIGINT, sigint_handler);
	if(sigsetjmp(do_sigint, SIGINT)) {
		printf(&quot;\n\n** SIGINT **\n\n&quot;);
		trace();
		stack[sp]=99;
		load();
	}
	if(setjmp(do_halt)==1) load();

	for(;;) { // start the VM, until do_halt 
		if(is_trace) {
			token=code[ip++]; 
			trace_start_data();
			words[token]();
			trace_data();
		} else {
			token=code[ip++]; 
			words[token]();
		}
	}

	return 0;
}
&lt;/code&gt;&lt;/pre&gt;
	</description>
    </item>
    <item>
      <title>Typhon</title>
      <link>https://tedneward.github.io/Research/vms/typhon/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">vms/typhon/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/monte-language/typhon&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Scratch VM</title>
      <link>https://tedneward.github.io/Research/vms/scratch-vm/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">vms/scratch-vm/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/LLK/scratch-vm&quot;&gt;Source&lt;/a&gt; | &lt;a href=&quot;https://scratch.mit.edu/&quot;&gt;Scratch&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Simple Object Machine</title>
      <link>https://tedneward.github.io/Research/vms/som/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">vms/som/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;http://som-st.github.io/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/SOM-st/&quot;&gt;Github&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Nine implementations:&lt;br&gt; * &lt;a href=&quot;https://github.com/SOM-st/som-java&quot;&gt;SOM (Java)&lt;/a&gt;&lt;br&gt; * &lt;a href=&quot;https://github.com/SOM-st/AweSOM&quot;&gt;AweSOM (Smalltalk)&lt;/a&gt;&lt;br&gt; * &lt;a href=&quot;https://github.com/SOM-st/CSOM&quot;&gt;CSOM (C)&lt;/a&gt;&lt;br&gt; * &lt;a href=&quot;https://github.com/SOM-st/SOMpp&quot;&gt;SOM++ (C++)&lt;/a&gt;&lt;br&gt; * &lt;a href=&quot;https://github.com/SOM-st/PySOM&quot;&gt;PySOM (Python)&lt;/a&gt;&lt;br&gt; * &lt;a href=&quot;https://github.com/SOM-st/RPySOM&quot;&gt;RPySOM (Python)&lt;/a&gt;&lt;br&gt; * &lt;a href=&quot;https://github.com/SOM-st/TruffleSOM&quot;&gt;TruffleSOM (Java/Graal)&lt;/a&gt;&lt;br&gt; * &lt;a href=&quot;https://github.com/SOM-st/RTruffleSOM&quot;&gt;RTruffleSOM (Tree-based)&lt;/a&gt;&lt;br&gt; * &lt;a href=&quot;https://github.com/SOM-st/JsSOM&quot;&gt;JsSOM (JavaScript)&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Strongtalk</title>
      <link>https://tedneward.github.io/Research/vms/strongtalk/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">vms/strongtalk/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;http://strongtalk.org/&quot;&gt;Website&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Uxn</title>
      <link>https://tedneward.github.io/Research/vms/uxn/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">vms/uxn/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://wiki.xxiivv.com/site/uxn.html&quot;&gt;Website&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;To get started, equip yourself with an assembler to convert tal source files into rom binary files, and an emulator to evaluate the rom files. The minimal system below includes the Console device:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;# Build the emulator
cc uxnmin.c -o uxnmin

# Build the assembler
xxd -r -p uxnasm.rom.txt uxnasm.rom

# Assemble a tal file
cat opctest.tal | uxnmin uxnasm.rom &amp;gt; opctest.rom

# Run a rom file
uxnmin opctest.rom
&lt;/code&gt;&lt;/pre&gt;
	</description>
    </item>
    <item>
      <title>S4</title>
      <link>https://tedneward.github.io/Research/vms/s4/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">vms/s4/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/CCurl/S4&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;h4&gt;README&lt;/h4&gt; 
&lt;p&gt;I think of S4 as a stack-based, RPN, Forth-like, virtual CPU/VM that can have as many registers, functions, and amount of user ram as the system supports.&lt;/p&gt; 
&lt;p&gt;A register is identified by up to 3 UPPER-case characters, so there is a maximum or (26x26x26) = 17576 registers available. I tend to think of registers as built-in variables. Reading, setting, incrementing or decrementing a register is a single operation.&lt;/p&gt; 
&lt;p&gt;A function is identified by any number of UPPER-case characters. The maximum number of functions is set in the config.h file.&lt;/p&gt; 
&lt;p&gt;The number of registers, function vectors, and user memory can be scaled as desired to fit into a system of any size. For example, on an ESP-8266 board, a typical configuration might be 576 (26&lt;em&gt;26) registers, 5000 functions, and 24K of user ram. In such a system, register names would be in the range of [aa.zz]. For a RPI Pico, I use 576 registers, 1000 functions, and 128K USER RAM. On a Arduino Leonardo, you might configure the system to have 26 registers and functions, and 1K USER. On a Windows or Linux system, I use 17576 registers (26&lt;/em&gt;26*26), 5000 functions, and 1MB USER.&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Example 1: &quot;Hello World!&quot; - the typical &quot;hello world&quot; program.&lt;/li&gt; 
 &lt;li&gt;Example 2: 1sA 2sB 3sC rA rB rC ++ . - would print 6.&lt;/li&gt; 
 &lt;li&gt;Example 4: 32 126[13,10,rI#.&quot;-&quot;,] - would print the ASCII table&lt;/li&gt; 
 &lt;li&gt;Example 3: 1000sS 13xPO 1{1 13 xPWD rS xW 0 13 xPWD rS xW} - the typical Arduino &quot;blink&quot; program.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;There were multiple reasons why to do this:&lt;/p&gt; 
&lt;ol&gt; 
 &lt;li&gt; &lt;p&gt;Many interpreted environments use tokens and a large SWITCH statement in a loop to execute the user&apos;s program. In these systems, the &quot;machine code&quot; (i.e. - byte-code ... the cases in the SWITCH statement) are often arbitrarily assigned and are not human-readable, so they have no meaning to the programmer when looking at the code that is actually being executed. Additionally there is a compiler and/or interpreter, often something similar to Forth, that is used to create the programs in that environment. For these enviromnents, there is a steep learning curve ... the programmer needs to learn the user environment and the hundreds or thousands of user functions in the libraries (or &quot;words&quot; in Forth). I wanted to avoid as much as that as possible, and have only one thing to learn: the machine code.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;I wanted to be free of the need for a multiple gigabyte tool chain and the edit/compile/run paradigm for developing everyday programs.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;I wanted a simple, minimal, and interactive programming environment that I could modify easily.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;I wanted an environment that could be easily configured for and deployed to many different types of development boards via the Arduino IDE.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;I wanted to be able to use the same environment on my personal computer as well as development boards.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;I wanted short commands so there was not a lot of typing needed.&lt;/p&gt; &lt;/li&gt; 
&lt;/ol&gt; 
&lt;p&gt;S4 is the result of my work towards those goals.&lt;/p&gt; 
&lt;p&gt;The implementation of S4&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;The entire system is implemented in a few files. The engine is in S4.cpp.&lt;/li&gt; 
 &lt;li&gt;There are a few additional files to support optional functionality (e.g - WiFi and File access).&lt;/li&gt; 
 &lt;li&gt;The same code runs on Windows, Linux, and multiple development boards (via the Arduino IDE).&lt;/li&gt; 
 &lt;li&gt;See the file &quot;config.h&quot; for system configuration settings.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;S4 Reference&lt;/h2&gt; 
&lt;h3&gt;ARITHMETIC&lt;/h3&gt; 
&lt;table&gt; 
 &lt;thead&gt; 
  &lt;tr&gt;
   &lt;th align=&quot;left&quot;&gt; Opcode&lt;/th&gt;
   &lt;th align=&quot;left&quot;&gt; Stack &lt;/th&gt;
   &lt;th align=&quot;left&quot;&gt; Description &lt;/th&gt;
  &lt;/tr&gt; 
 &lt;/thead&gt; 
 &lt;tbody&gt; 
  &lt;tr&gt;
   &lt;td align=&quot;left&quot;&gt; + &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; (a b--n) &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; n: a+b - addition&lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td align=&quot;left&quot;&gt; - &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; (a b--n) &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; n: a-b - subtraction&lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td align=&quot;left&quot;&gt; * &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; (a b--n) &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; n: a*b - multiplication&lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td align=&quot;left&quot;&gt; / &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; (a b--q) &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; q: a/b - division&lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td align=&quot;left&quot;&gt; ^ &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; (a b--r) &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; r: MODULO(a, b)&lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td align=&quot;left&quot;&gt; &amp;amp; &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; (a b--q r) &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; q: DIV(a,b), r: MODULO(a,b) - /MOD&lt;/td&gt;
  &lt;/tr&gt; 
 &lt;/tbody&gt; 
&lt;/table&gt; 
&lt;h3&gt;BIT MANIPULATION&lt;/h3&gt; 
&lt;table&gt; 
 &lt;thead&gt; 
  &lt;tr&gt;
   &lt;th align=&quot;left&quot;&gt; Opcode&lt;/th&gt;
   &lt;th align=&quot;left&quot;&gt; Stack &lt;/th&gt;
   &lt;th align=&quot;left&quot;&gt; Description &lt;/th&gt;
  &lt;/tr&gt; 
 &lt;/thead&gt; 
 &lt;tbody&gt; 
  &lt;tr&gt;
   &lt;td align=&quot;left&quot;&gt; b&amp;amp; &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; (a b--n) &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; n: a AND b&lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td align=&quot;left&quot;&gt; b| &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; (a b--n) &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; n: a OR b&lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td align=&quot;left&quot;&gt; b^ &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; (a b--n) &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; n: a XOR b&lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td align=&quot;left&quot;&gt; b~ &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; (a--b) &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; b: NOT a (ones-complement, e.g - 101011 =&amp;gt; 010100)&lt;/td&gt;
  &lt;/tr&gt; 
 &lt;/tbody&gt; 
&lt;/table&gt; 
&lt;h3&gt;STACK&lt;/h3&gt; 
&lt;table&gt; 
 &lt;thead&gt; 
  &lt;tr&gt;
   &lt;th align=&quot;left&quot;&gt; Opcode&lt;/th&gt;
   &lt;th align=&quot;left&quot;&gt; Stack &lt;/th&gt;
   &lt;th align=&quot;left&quot;&gt; Description &lt;/th&gt;
  &lt;/tr&gt; 
 &lt;/thead&gt; 
 &lt;tbody&gt; 
  &lt;tr&gt;
   &lt;td align=&quot;left&quot;&gt; # &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; (a--a a) &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; Duplicate TOS (DUP)&lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td align=&quot;left&quot;&gt; \ &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; (a b--a) &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; Drop TOS (DROP)&lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td align=&quot;left&quot;&gt; $ &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; (a b--b a) &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; Swap top 2 stack items (SWAP)&lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td align=&quot;left&quot;&gt; % &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; (a b--a b a) &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; Push 2nd (OVER)&lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td align=&quot;left&quot;&gt; _ &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; (a--b) &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; b: -a (Negate)&lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td align=&quot;left&quot;&gt; xA &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; (a--b) &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; b: abs(a) (Absolute)&lt;/td&gt;
  &lt;/tr&gt; 
 &lt;/tbody&gt; 
&lt;/table&gt; 
&lt;h3&gt;MEMORY&lt;/h3&gt; 
&lt;table&gt; 
 &lt;thead&gt; 
  &lt;tr&gt;
   &lt;th align=&quot;left&quot;&gt; Opcode&lt;/th&gt;
   &lt;th align=&quot;left&quot;&gt; Stack &lt;/th&gt;
   &lt;th align=&quot;left&quot;&gt; Description &lt;/th&gt;
  &lt;/tr&gt; 
 &lt;/thead&gt; 
 &lt;tbody&gt; 
  &lt;tr&gt;
   &lt;td align=&quot;left&quot;&gt; c@ &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; (a--n) &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; Fetch BYTE n from address a&lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td align=&quot;left&quot;&gt; @ &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; (a--n) &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; Fetch CELL n from address a&lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td align=&quot;left&quot;&gt; c! &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; (n a--) &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; Store BYTE n to address a&lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td align=&quot;left&quot;&gt; ! &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; (n a--) &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; Store CELL n to address a&lt;/td&gt;
  &lt;/tr&gt; 
 &lt;/tbody&gt; 
&lt;/table&gt; 
&lt;h3&gt;REGISTERS and LOCALS&lt;/h3&gt; 
&lt;p&gt;NOTES:&lt;br&gt; - Register names are 1 to 3 UPPERCASE characters: [rA..rZZZ]&lt;br&gt; - LOCALS: S4 provides 10 locals per call [r0..r9].&lt;br&gt; - The number of registers is controlled by the NUM_REGS #define in &quot;config.h&quot;.&lt;br&gt; - Register &apos;rI&apos; is the FOR Loop index &lt;strong&gt;special&lt;/strong&gt;&lt;/p&gt; 
&lt;table&gt; 
 &lt;thead&gt; 
  &lt;tr&gt;
   &lt;th align=&quot;left&quot;&gt; Opcode&lt;/th&gt;
   &lt;th align=&quot;left&quot;&gt; Stack &lt;/th&gt;
   &lt;th align=&quot;left&quot;&gt; Description &lt;/th&gt;
  &lt;/tr&gt; 
 &lt;/thead&gt; 
 &lt;tbody&gt; 
  &lt;tr&gt;
   &lt;td align=&quot;left&quot;&gt; rXXX &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; (--n) &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; read register/local XXX&lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td align=&quot;left&quot;&gt; sXXX &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; (n--) &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; set register/local XXX to n&lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td align=&quot;left&quot;&gt; iXXX &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; (--) &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; increment register/local XXX&lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td align=&quot;left&quot;&gt; dXXX &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; (--) &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; decrement register/local XXX&lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td align=&quot;left&quot;&gt; nXXX &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; (--) &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; increment register/local XXX by the size of a cell (next cell)&lt;/td&gt;
  &lt;/tr&gt; 
 &lt;/tbody&gt; 
&lt;/table&gt; 
&lt;h3&gt;WORDS/FUNCTIONS&lt;/h3&gt; 
&lt;p&gt;NOTES:&lt;br&gt; - Word/Function names are ProperCase identifiers.&lt;br&gt; - They must begin with [A..Z], and can include lowercase characters [a..z].&lt;br&gt; - The number of words is controlled by the NUM_FUNCS #define in &quot;config.h&quot;&lt;br&gt; - NUM_FUNCS needs to be a power of 2.&lt;br&gt; - If a word has already been defined, S4 prints &quot;-redef-&quot;.&lt;/p&gt; 
&lt;table&gt; 
 &lt;thead&gt; 
  &lt;tr&gt;
   &lt;th align=&quot;left&quot;&gt; Opcode&lt;/th&gt;
   &lt;th align=&quot;left&quot;&gt; Stack &lt;/th&gt;
   &lt;th align=&quot;left&quot;&gt; Description &lt;/th&gt;
  &lt;/tr&gt; 
 &lt;/thead&gt; 
 &lt;tbody&gt; 
  &lt;tr&gt;
   &lt;td align=&quot;left&quot;&gt; : &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; (--) &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; Define word/function. Copy chars to (HERE++) until closing &apos;;&apos;.&lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td align=&quot;left&quot;&gt; ABC &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; (--) &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; Execute/call word/function ABC&lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td align=&quot;left&quot;&gt; ; &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; (--) &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; Return: PC = rpop()&lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td align=&quot;left&quot;&gt; &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; - Returning while inside of a loop is not supported; break out of the loop first.&lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td align=&quot;left&quot;&gt; &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; - Use &apos;|&apos; to break out of a FOR or WHILE loop.&lt;/td&gt;
  &lt;/tr&gt; 
 &lt;/tbody&gt; 
&lt;/table&gt; 
&lt;h3&gt;INPUT/OUTPUT&lt;/h3&gt; 
&lt;table&gt; 
 &lt;thead&gt; 
  &lt;tr&gt;
   &lt;th align=&quot;left&quot;&gt; Opcode&lt;/th&gt;
   &lt;th align=&quot;left&quot;&gt; Stack &lt;/th&gt;
   &lt;th align=&quot;left&quot;&gt; Description &lt;/th&gt;
  &lt;/tr&gt; 
 &lt;/thead&gt; 
 &lt;tbody&gt; 
  &lt;tr&gt;
   &lt;td align=&quot;left&quot;&gt; . &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; (N--) &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; Output N as decimal number.&lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td align=&quot;left&quot;&gt; , &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; (N--) &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; Output N as character (Forth EMIT).&lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td align=&quot;left&quot;&gt; &quot; &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; (?--?) &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; Output characters until the next &apos;&quot;&apos;.&lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td align=&quot;left&quot;&gt; &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; - %d outputs TOS as an integer (eg - 123&quot;x%dx&quot; outputs x123x)&lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td align=&quot;left&quot;&gt; &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; - %c outputs TOS as a character (eg - 65&quot;x%cx&quot; outputs xAx)&lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td align=&quot;left&quot;&gt; &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; - %n outputs CR/LF&lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td align=&quot;left&quot;&gt; &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; - %&lt;x&gt;
      output 
     &lt;x&gt;
       (eg - &quot;x%&quot; %% %&quot;x&quot; outputs x&quot; % &quot;x)
     &lt;/x&gt;
    &lt;/x&gt;&lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td align=&quot;left&quot;&gt; 0..9 &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; (--n) &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; Scan DECIMAL number. For multiple numbers, separate them by space (47 33).&lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td align=&quot;left&quot;&gt; &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; - To enter a negative number, use &quot;negate&quot; (eg - 490_).&lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td align=&quot;left&quot;&gt; hNNN &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; (--h) &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; h: NNN as a HEX number (0-9, A-F, UPPERCASE only).&lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td align=&quot;left&quot;&gt; &apos;x &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; (--n) &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; n: the ASCII value of x&lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td align=&quot;left&quot;&gt; &lt;code&gt;XXX&lt;/code&gt; &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; (a--a b) &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; Copies XXX to address a, b is the next address after the NULL terminator.&lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td align=&quot;left&quot;&gt; xZ &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; (a--) &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; Output the NULL terminated string starting at address a.&lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td align=&quot;left&quot;&gt; xK? &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; (--f) &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; f: 1 if a character is waiting in the input buffer, else 0.&lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td align=&quot;left&quot;&gt; xK@ &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; (--c) &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; c: next character from the input buffer. If no character, wait.&lt;/td&gt;
  &lt;/tr&gt; 
 &lt;/tbody&gt; 
&lt;/table&gt; 
&lt;h3&gt;CONDITIONS/LOOPS/FLOW CONTROL&lt;/h3&gt; 
&lt;table&gt; 
 &lt;thead&gt; 
  &lt;tr&gt;
   &lt;th align=&quot;left&quot;&gt; Opcode&lt;/th&gt;
   &lt;th align=&quot;left&quot;&gt; Stack &lt;/th&gt;
   &lt;th align=&quot;left&quot;&gt; Description &lt;/th&gt;
  &lt;/tr&gt; 
 &lt;/thead&gt; 
 &lt;tbody&gt; 
  &lt;tr&gt;
   &lt;td align=&quot;left&quot;&gt; &amp;lt; &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; (a b--f) &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; f: (a &amp;lt; b) ? 1 : 0;&lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td align=&quot;left&quot;&gt; = &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; (a b--f) &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; f: (a = b) ? 1 : 0;&lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td align=&quot;left&quot;&gt; &amp;gt; &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; (a b--f) &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; f: (a &amp;gt; b) ? 1 : 0;&lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td align=&quot;left&quot;&gt; ~ &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; (n -- f) &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; f: (a = 0) ? 1 : 0; (Logical NOT)&lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td align=&quot;left&quot;&gt; ( &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; (f--) &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; IF: if (f != 0), continue into &apos;()&apos;, else skip to matching &apos;)&apos;&lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td align=&quot;left&quot;&gt; [ &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; (F T--) &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; FOR: start a For/Next loop. if (T &amp;lt; F), swap T and F&lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td align=&quot;left&quot;&gt; rI &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; (--n) &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; n: the index of the current FOR loop&lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td align=&quot;left&quot;&gt; ] &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; (--) &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; NEXT: increment index (rI) and restart loop if (rI &amp;lt;= T)&lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td align=&quot;left&quot;&gt; &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; NOTE: A FOR loop always runs at least one iteration.&lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td align=&quot;left&quot;&gt; &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; - It can be put it inside a &apos;()&apos; to keep it from running.&lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td align=&quot;left&quot;&gt; { &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; (f--f) &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; WHILE: if (f == 0) skip to matching &apos;}&apos;&lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td align=&quot;left&quot;&gt; } &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; (f--f?) &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; WHILE: if (f != 0) jump to matching &apos;{&apos;, else drop f and continue&lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td align=&quot;left&quot;&gt; uL &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; (--) &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; Unwind the loop stack. Use with &apos;;&apos;.eg = (uL;)&lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td align=&quot;left&quot;&gt; uF &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; (--) &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; Exit FOR. Continue after the next &apos;]&apos;.&lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td align=&quot;left&quot;&gt; uW &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; (--) &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; Exit WHILE. Continue after the next &apos;}&apos;.&lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td align=&quot;left&quot;&gt; uC &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; (--) &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; Continue. Jump to the beginning of the current loop.&lt;/td&gt;
  &lt;/tr&gt; 
 &lt;/tbody&gt; 
&lt;/table&gt; 
&lt;h3&gt;OTHER&lt;/h3&gt; 
&lt;table&gt; 
 &lt;thead&gt; 
  &lt;tr&gt;
   &lt;th align=&quot;left&quot;&gt; Opcode&lt;/th&gt;
   &lt;th align=&quot;left&quot;&gt; Stack &lt;/th&gt;
   &lt;th align=&quot;left&quot;&gt; Description &lt;/th&gt;
  &lt;/tr&gt; 
 &lt;/thead&gt; 
 &lt;tbody&gt; 
  &lt;tr&gt;
   &lt;td align=&quot;left&quot;&gt; xBO &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; (n m--fh) &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; File: Block Open (block-nnn.s4, m: 0=&amp;gt;read, 1=write)&lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td align=&quot;left&quot;&gt; xBR &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; (n a sz--) &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; File: Block Read (block-nnn.s4, max sz bytee).&lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td align=&quot;left&quot;&gt; xBW &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; (n a sz--) &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; File: Block Write (block-nnn.s4, sz bytes).&lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td align=&quot;left&quot;&gt; xBL &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; (n--) &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; File: Load code from file (block-nnn.src). This can be nested.&lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td align=&quot;left&quot;&gt; xFL &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; (--) &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; File: Load code from ./Code.S4.&lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td align=&quot;left&quot;&gt; xFS &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; (--) &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; File: Save code to ./Code.S4.&lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td align=&quot;left&quot;&gt; xFO &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; (n m--h) &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; File: Open - n: file name, m: mode, h: file handle (0 means not opened)&lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td align=&quot;left&quot;&gt; xFC &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; (h--) &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; File: Close - h: file handle&lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td align=&quot;left&quot;&gt; xFD &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; (n--) &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; File: Delete - n: file name&lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td align=&quot;left&quot;&gt; xFR &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; (h--c f) &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; File: Read - h: file handle, c: char, n: success?&lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td align=&quot;left&quot;&gt; xFW &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; (c h--f) &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; File: Write - h: file handle, c: char, n: success?&lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td align=&quot;left&quot;&gt; &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; NOTE: File operations are enabled by #define &lt;strong&gt;FILES&lt;/strong&gt;&lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td align=&quot;left&quot;&gt; xPI &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; (p--) &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; Arduino: Pin Input (pinMode(p, INPUT))&lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td align=&quot;left&quot;&gt; xPU &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; (p--) &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; Arduino: Pin Pullup (pinMode(p, INPUT_PULLUP))&lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td align=&quot;left&quot;&gt; xPO &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; (p--) &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; Arduino: Pin Output (pinMode(p, OUTPUT)&lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td align=&quot;left&quot;&gt; xPRA &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; (p--n) &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; Arduino: Pin Read Analog (n = analogRead(p))&lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td align=&quot;left&quot;&gt; xPRD &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; (p--n) &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; Arduino: Pin Read Digital (n = digitalRead(p))&lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td align=&quot;left&quot;&gt; xPWA &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; (n p--) &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; Arduino: Pin Write Analog (analogWrite(p, n))&lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td align=&quot;left&quot;&gt; xPWD &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; (n p--) &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; Arduino: Pin Write Digital (digitalWrite(p, n))&lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td align=&quot;left&quot;&gt; xR &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; (n--r) &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; r: a random number in the range [0..(n-1)]&lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td align=&quot;left&quot;&gt; &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; NB: if n=0, r is the entire 32-bit random number&lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td align=&quot;left&quot;&gt; xT &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; (--n) &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; Milliseconds (Arduino: millis(), Windows: GetTickCount())&lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td align=&quot;left&quot;&gt; xN &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; (--n) &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; Microseconds (Arduino: micros(), Windows: N/A)&lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td align=&quot;left&quot;&gt; xW &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; (n--) &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; Wait (Arduino: delay(), Windows: Sleep())&lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td align=&quot;left&quot;&gt; xIAF &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; (--a) &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; INFO: a: address of first function vector&lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td align=&quot;left&quot;&gt; xIAH &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; (--a) &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; INFO: a: address of HERE variable&lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td align=&quot;left&quot;&gt; xIAR &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; (--a) &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; INFO: a: address of first register vector&lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td align=&quot;left&quot;&gt; xIAS &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; (--a) &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; INFO: a: address of beeginning of system structure&lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td align=&quot;left&quot;&gt; xIAU &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; (--a) &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; INFO: a: address of beeginning of user area&lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td align=&quot;left&quot;&gt; xIF &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; (--n) &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; INFO: n: number of words/functions&lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td align=&quot;left&quot;&gt; xIH &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; (--n) &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; INFO: n: value of HERE variable&lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td align=&quot;left&quot;&gt; xIR &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; (--n) &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; INFO: n: number of registers&lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td align=&quot;left&quot;&gt; xIU &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; (--n) &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; INFO: n: number of bytes in the USER area&lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td align=&quot;left&quot;&gt; xSR &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; (--) &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; S4 system reset&lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td align=&quot;left&quot;&gt; xQ &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; (--) &lt;/td&gt;
   &lt;td align=&quot;left&quot;&gt; PC: Exit S4&lt;/td&gt;
  &lt;/tr&gt; 
 &lt;/tbody&gt; 
&lt;/table&gt; 
&lt;h1&gt;Examples&lt;/h1&gt; 
&lt;p&gt;; To enter a comment:&lt;br&gt; 0( here is a comment )&lt;br&gt; ; here is another comment&lt;/p&gt; 
&lt;p&gt;; if (c) { print(&quot;Yes&quot;) } else { print(&quot;No&quot;) }&lt;br&gt; rC #(&quot;Yes&quot;)~(&quot;No&quot;)&lt;/p&gt; 
&lt;p&gt;; x = (a == b) ? c : d;&lt;br&gt; rA rB=#(rC$)~(rD)sX;&lt;/p&gt; 
&lt;p&gt;; To make sure F &amp;lt; T&lt;br&gt; ; S4 code: %%&amp;gt;($)&lt;br&gt; ; Forth equivalent: OVER OVER &amp;gt; IF SWAP THEN&lt;br&gt; ; C equivalent: if (f &amp;gt; t) { int x = f; f = t; t = x; }&lt;/p&gt; 
&lt;p&gt;; To do something (in this case, execute LP) N times:&lt;br&gt; 1 rN[LP]&lt;/p&gt; 
&lt;p&gt;; Increment Register x, decrement register Y&lt;br&gt; iX dY&lt;/p&gt; 
&lt;p&gt;; To print numbers from F to T:&lt;br&gt; ; S4 code: rF rT[rI.&quot; &quot;]&lt;br&gt; ; Forth equivalent: F @ T @ FOR I . NEXT&lt;br&gt; ; C equivalent: for (int i = F; i &amp;lt;= T; i)) { printf(&quot;%d &quot;, i); }&lt;/p&gt; 
&lt;p&gt;; One way to copy N bytes from A to B (n f t--)&lt;br&gt; N A B s2 s1 1[r1 c@ r2 c! i1 i2]&lt;/p&gt; 
&lt;p&gt;; One way to copy N CELLS from A to B (N A B--)&lt;br&gt; N A B s2 s1 1[r1 @ r2 ! n1 n2]&lt;/p&gt; 
&lt;p&gt;; A simple benchmark for a 100 million FOR loop:&lt;br&gt; 1000#* 100* xT$ 1[] xT$-.&quot; ms&quot;&lt;/p&gt; 
&lt;p&gt;; A simple benchmark for a 100 million WHILE loop:&lt;br&gt; 1000#* 100* xT$ {1-} xT$-.&quot; ms&quot;&lt;/p&gt; 
&lt;p&gt;; Define a word to display the currently defined code:&lt;br&gt; :CODE xIAU xIH 1-[rI c@ #,&apos;;=(rI 1+ c@&apos;: =(13,10,))];&lt;/p&gt; 
&lt;p&gt;; Exit S4:&lt;br&gt; xQ&lt;/p&gt; 
&lt;h1&gt;Adding new functionality to S4:&lt;/h1&gt; 
&lt;p&gt;In run(start) (S4.cpp), in the &quot;switch&quot; statement, there are cases available for direct support of new instructions, mostly unused lowercase characters. New functionality can be put there by comandeering one of the /* FREE */ cases.&lt;/p&gt; 
&lt;p&gt;S4 also has &quot;extended&quot; instructions. These are triggered by the &apos;x&apos; case. All extended instructions begin with &apos;x&apos;. For extended instructions, function doExt() is called. It behaves in a similar way to run(), by setting &apos;ir = *(pc++)&apos; and a switch statement. The &quot;default:&quot; case calls an external function, doCustom(ir, pc). That is where I usually put system-specific functionality; (eg - pin manipulation for Arduino Boards). Function doCustom(ir, pc) needs to return the address where pc should continue.&lt;/p&gt; 
&lt;p&gt;As an example, I will add Gamepad/Joystick simulation to S4 as extended instructions. This example uses the HID-Project from NicoHood (&lt;a href=&quot;https://github.com/NicoHood/HID&quot;&gt;https://github.com/NicoHood/HID&lt;/a&gt;).&lt;/p&gt; 
&lt;p&gt;Import the library into Arduino using &quot;Import Library&quot;.&lt;/p&gt; 
&lt;p&gt;In the doCustom(ir, pc) function (S4.ino), add a new case for ir. In this case, I am adding case &apos;G&apos;.&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;addr doCustom(byte ir, addr pc) {
    ir = *(pc++);
    switch (ir) {
    ...
    case &apos;G&apos;: pc = doGamePad(ir, pc);        break;
    ...
    }
    return pc;
}
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Then it is a simple matter of implementing doGamePad(ir, pc):&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;\#ifdef __GAMEPAD__
\#include &amp;lt;HID-Project.h&amp;gt;
\#include &amp;lt;HID-Settings.h&amp;gt;
addr doGamePad(byte ir, addr pc) {
    ir = *(pc++);
    switch (ir) {
    case &apos;X&apos;: Gamepad.xAxis(pop());          break;
    case &apos;Y&apos;: Gamepad.yAxis(pop());          break;
    case &apos;P&apos;: Gamepad.press(pop());          break;
    case &apos;R&apos;: Gamepad.release(pop());        break;
    case &apos;A&apos;: Gamepad.dPad1(pop());          break;
    case &apos;B&apos;: Gamepad.dPad2(pop());          break;
    case &apos;L&apos;: Gamepad.releaseAll();          break;
    case &apos;W&apos;: Gamepad.write();               break;
    default:
        isError = 1;
        printString(&quot;-notGamepad-&quot;);
    }
    return pc;
}
\#else
addr doGamePad(addr pc) { printString(&quot;-noGamepad-&quot;); return pc; }
\#endif
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;The last thing to do is #define __GAMEPAD__. This is best done in &quot;config.h&quot;.&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;...
#elif __BOARD__ == XIAO
  #define __GAMEPAD__
  #define STK_SZ          8
  #define LSTACK_SZ       4
  #define USER_SZ        (22*1024)
  #define NUM_REGS       (26*26)
 ...
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Now in S4, you can do things like:&lt;/p&gt; 
&lt;p&gt;3 xGP xGW 0(Press button 3)&lt;br&gt; 3 xGR xGW 0(Release button 3)&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>q3vm</title>
      <link>https://tedneward.github.io/Research/vms/q3vm/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">vms/q3vm/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/jnz/q3vm&quot;&gt;GitHub&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;A lightweight (single file: vm.c) embeddable interpreter/Virtual Machine (VM) for compiled bytecode files (.qvm) based on good old C-language input (.c). A complete C compiler to generate .qvm files is included (LCC). The interpreter is based on the Quake III Arena virtual machine (hence the name q3vm) but the interpreter is not tied to Quake III Arena and can be used for any kind of project. For example code that needs to run in a sandbox.&lt;/p&gt; 
&lt;p&gt;Introduction to Q3VM: &lt;a href=&quot;http://fabiensanglard.net/quake3/qvm.php&quot;&gt;http://fabiensanglard.net/quake3/qvm.php&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Reading about Virtual Machines</title>
      <link>https://tedneward.github.io/Research/vms/reading/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">vms/reading/index.html</guid>
      	<description>
	&lt;h2&gt;Posts, Papers&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/spencertipping/jit-tutorial&quot;&gt;How to write a very simple JIT compiler&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://ittc.ku.edu/~kulkarni/teaching/EECS768/slides/chapter1.pdf&quot;&gt;Introduction to Virtual Machines&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.186.4512&amp;amp;rep=rep1&amp;amp;type=pdf&quot;&gt;An Introduction to Virtual Machines Implementation and Applications&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;Crafting Interpreters: &lt;a href=&quot;https://www.craftinginterpreters.com/a-virtual-machine.html&quot;&gt;A Virtual Machine&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.jmeiners.com/lc3-vm/&quot;&gt;Write your Own Virtual Machine&lt;/a&gt; &lt;a href=&quot;https://github.com/justinmeiners/lc3-vm&quot;&gt;Source&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://merlintec.com/download/mario.pdf&quot;&gt;&quot;A Smalltalk Implementation in Self&quot;&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.andreinc.net/2021/12/01/writing-a-simple-vm-in-less-than-125-lines-of-c&quot;&gt;Writing a simple 16-bit VM in less than 125 lines of C&lt;/a&gt; (&lt;a href=&quot;https://github.com/nomemory/lc3-vm&quot;&gt;Github&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://en.wikibooks.org/wiki/Creating_a_Virtual_Machine/Register_VM_in_C&quot;&gt;Creating a Virtual Machine/Register VM in C&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.lua.org/doc/jucs05.pdf&quot;&gt;The Implementation of Lua 5.0&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.gnu.org/software/guile/manual/html_node/A-Virtual-Machine-for-Guile.html&quot;&gt;A Virtual Machine for Guile&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.cs.cornell.edu/people/egs/papers/kimera-sosp99.pdf&quot;&gt;Design and implementation of a distributed virtual machine for networked computers&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;./VirtualMachinesAndAbstractCompilers.pdf&quot;&gt;&quot;Virtual Machines and Abstract Compilers&quot;&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;./TitzerVEE10.pdf&quot;&gt;&quot;Improving Compiler-Runtime Separation with XIR&quot;&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;./2204.06156.pdf&quot;&gt;&quot;Modular and Didactic Compiler Design with XML Inter-Phases Communication&quot;&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://stevehanov.ca/blog/index.php?id=92&quot;&gt;qb.js: An implementation of QBASIC in Javascript&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Videos&lt;/h2&gt; 
&lt;p&gt;Build Your Own Virtual Machine&lt;/p&gt; 
&lt;ol&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=BNXP0w4Ppto&amp;amp;list=PLSiFUSQSRYAOFwfP-aMzXJlWKVyIuWfPU&amp;amp;index=4&quot;&gt;How to Build a Virtual Machine from Scratch&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=Dw9URS-s9M8&amp;amp;list=PLSiFUSQSRYAOFwfP-aMzXJlWKVyIuWfPU&amp;amp;index=3&amp;amp;t=1s&quot;&gt;Create Your Own Stack Machine&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=UnGYvjDDPJI&amp;amp;list=PLSiFUSQSRYAOFwfP-aMzXJlWKVyIuWfPU&amp;amp;index=2&amp;amp;t=1s&quot;&gt;Build Your Own Virtual Machine - Lexer&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=A5Ioln_8Wbc&amp;amp;list=PLSiFUSQSRYAOFwfP-aMzXJlWKVyIuWfPU&amp;amp;index=1&amp;amp;t=1s&quot;&gt;Build Your Own Virtual Machine - Assembler&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=9Pa0iDObijA&amp;amp;list=PLSiFUSQSRYAOFwfP-aMzXJlWKVyIuWfPU&amp;amp;index=5&quot;&gt;Build Your Own Virtual Machine - Finish Assembler&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=pPFP9yA1MF8&amp;amp;list=PLSiFUSQSRYAOFwfP-aMzXJlWKVyIuWfPU&amp;amp;index=6&amp;amp;t=1s&quot;&gt;Build Your Own Virtual Machine - Finish Up!&lt;/a&gt;&lt;/li&gt; 
&lt;/ol&gt; 
&lt;p&gt;&lt;a href=&quot;http://dmitrysoshnikov.com/courses/virtual-machine/&quot;&gt;Building a Virtual Machine for Programming Language&lt;/a&gt; - Commercial; &lt;a href=&quot;https://www.youtube.com/playlist?list=PLGNbPb3dQJ_446PjTYQ0mCn2OGoHSKraB&quot;&gt;first 5 parts&lt;/a&gt;&lt;/p&gt; 
&lt;h2&gt;College/University Courses&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.wolczko.com/CS294/&quot;&gt;UCB CS294-113&lt;/a&gt;: Virtual Machines and Managed Runtimes 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://archive.org/download/vmss16/wolczko.pdf&quot;&gt;A Concise and Opinionated History of Virtual Machines&lt;/a&gt; or &lt;a href=&quot;https://www.youtube.com/watch?v=QnQYhrpX39M&quot;&gt;YouTube&lt;/a&gt; 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://soft-dev.org/events/vmss16/&quot;&gt;Virtual Machines Summer School 2016&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://course.ece.cmu.edu/~ece600/fall17/lectures/lecture19.pdf&quot;&gt;18-600: Fondations of Computer Systems/Lecture 19: Virtual Machine Design &amp;amp; Implementation&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://ycpcs.github.io/cs340-fall2016/lectures/lecture19.html&quot;&gt;CS 340: Lecture 19: Virtual Machines&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.wolczko.com/CS294/&quot;&gt;UCB CS294-113: Virtual Machines and Managed Runtimes&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Rubinius</title>
      <link>https://tedneward.github.io/Research/vms/rubinius/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">vms/rubinius/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://rubinius.com/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/rubinius/rubinius&quot;&gt;Github&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;From the Github Overview:&lt;/p&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;Rubinius is a virtual computing machine. As a computing machine, it possesses several mechanisms that physical computers possess to support computation. It runs in an environment that provides various capabilities. These are presented to the machine through the Environment object. It has certain configuration values that influence how the machine operates. This is managed by the Configuration object. The machine has a boot process that carefully builds up the components in a precise order until the machine is ready to run user code. When the user code completes executing, the machine halts, again following a precise sequence of deconstructing the various components. The rest of the components of the machine are described below.&lt;/p&gt; 
&lt;/blockquote&gt;
	</description>
    </item>
    <item>
      <title>CPython VM</title>
      <link>https://tedneward.github.io/Research/vms/python/cpython/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">vms/python/cpython/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/python/cpython&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;h2&gt;Books&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://leanpub.com/insidethepythonvirtualmachine/read&quot;&gt;Inside the Python Virtual Machine&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Posts&lt;/h2&gt; 
&lt;p&gt;&lt;a href=&quot;https://opensource.com/article/18/4/introduction-python-bytecode&quot;&gt;An introduction to Python bytecode&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Python behind the scenes:&lt;br&gt; * &lt;a href=&quot;https://tenthousandmeters.com/blog/python-behind-the-scenes-1-how-the-cpython-vm-works/&quot;&gt;#1: how the CPython VM works&lt;/a&gt;&lt;br&gt; * &lt;a href=&quot;https://tenthousandmeters.com/blog/python-behind-the-scenes-2-how-the-cpython-compiler-works/&quot;&gt;#2: how the CPython compiler works&lt;/a&gt;&lt;br&gt; * &lt;a href=&quot;https://tenthousandmeters.com/blog/python-behind-the-scenes-3-stepping-through-the-cpython-source-code/&quot;&gt;#3: stepping through the CPython source code&lt;/a&gt;&lt;br&gt; * &lt;a href=&quot;https://tenthousandmeters.com/blog/python-behind-the-scenes-4-how-python-bytecode-is-executed/&quot;&gt;#4: how CPython bytecode is executed&lt;/a&gt;&lt;br&gt; * &lt;a href=&quot;https://tenthousandmeters.com/blog/python-behind-the-scenes-5-how-variables-are-implemented-in-cpython/&quot;&gt;#5: how variables are implemented in CPython&lt;/a&gt;&lt;br&gt; * &lt;a href=&quot;https://tenthousandmeters.com/blog/python-behind-the-scenes-6-how-python-object-system-works/&quot;&gt;#6: how Python object system works&lt;/a&gt;&lt;br&gt; * &lt;a href=&quot;https://tenthousandmeters.com/blog/python-behind-the-scenes-7-how-python-attributes-work/&quot;&gt;#7: how Python attributes work&lt;/a&gt;&lt;br&gt; * &lt;a href=&quot;https://tenthousandmeters.com/blog/python-behind-the-scenes-8-how-python-integers-work/&quot;&gt;#8: how Python integers work&lt;/a&gt;&lt;br&gt; * &lt;a href=&quot;https://tenthousandmeters.com/blog/python-behind-the-scenes-9-how-python-strings-work/&quot;&gt;#9: how Python strings work&lt;/a&gt;&lt;br&gt; * &lt;a href=&quot;https://tenthousandmeters.com/blog/python-behind-the-scenes-10-how-python-dictionaries-work/&quot;&gt;#10: how Python dictionaries work&lt;/a&gt;&lt;br&gt; * &lt;a href=&quot;https://tenthousandmeters.com/blog/python-behind-the-scenes-11-how-the-python-import-system-works/&quot;&gt;#11: how the Python import system works&lt;/a&gt;&lt;br&gt; * &lt;a href=&quot;https://tenthousandmeters.com/blog/python-behind-the-scenes-12-how-asyncawait-works-in-python/&quot;&gt;#12: how async/await works&lt;/a&gt;&lt;br&gt; * &lt;a href=&quot;https://tenthousandmeters.com/blog/python-behind-the-scenes-13-the-gil-and-its-effects-on-python-multithreading/&quot;&gt;#13: the GIL and its effects on Python multithreading&lt;/a&gt;&lt;/p&gt; 
&lt;h2&gt;Slides&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://troeger.eu/files/teaching/pythonvm08.pdf&quot;&gt;Python 2.5: A Guided Tour (PDF)&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>PyPy</title>
      <link>https://tedneward.github.io/Research/vms/python/pypy/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">vms/python/pypy/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.pypy.org/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://www.pypy.org/download.html&quot;&gt;Downloads (Binaries and Source zips)&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Python VMs</title>
      <link>https://tedneward.github.io/Research/vms/python/index/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">vms/python/index/index.html</guid>
      	<description>
	&lt;h2&gt;Implementations&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;C/Native: &lt;a href=&quot;../cpython&quot;&gt;CPython&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;Java: &lt;a href=&quot;../jython&quot;&gt;Jython&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;Python: &lt;a href=&quot;../coco&quot;&gt;Coco&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://aosabook.org/en/500L/a-python-interpreter-written-in-python.html&quot;&gt;A Python in under 500 lines of Python&lt;/a&gt; (&lt;a href=&quot;https://github.com/nedbat/byterun&quot;&gt;Source&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;../medusavm&quot;&gt;MedusaVM&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;../pypy&quot;&gt;PyPy&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Jython</title>
      <link>https://tedneward.github.io/Research/vms/python/jython/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">vms/python/jython/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.jython.org/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/jython/jython/&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>MedusaVM</title>
      <link>https://tedneward.github.io/Research/vms/python/medusavm/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">vms/python/medusavm/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/lispyclouds/medusa&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Archived in 2015.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>SpiderMonkey</title>
      <link>https://tedneward.github.io/Research/vms/js/spidermonkey/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">vms/js/spidermonkey/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://spidermonkey.dev/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/mozilla-spidermonkey&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>JVM FFI</title>
      <link>https://tedneward.github.io/Research/vms/jvm/ffi/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">vms/jvm/ffi/index.html</guid>
      	<description>
	&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/zakgof/java-native-benchmark&quot;&gt;java-native-benchmark&lt;/a&gt;: Benchmarking Java&apos;s native call APIs: JNI, JNA, JNR, BridJ and Project Panama&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h1&gt;JNI (Java Native Interface)&lt;/h1&gt; 
&lt;p&gt;&lt;a href=&quot;https://docs.oracle.com/en/java/javase/17/docs/specs/jni/index.html&quot;&gt;Specification (Java 17)&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Basically broken into three parts:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Java calling native code (static methods marked &lt;code&gt;native&lt;/code&gt; and dynamically linked at runtime)&lt;/li&gt; 
 &lt;li&gt;Native code calling back into the JVM (native code accessing fields and methods of Java objects)&lt;/li&gt; 
 &lt;li&gt;Invocation/hosting (bringing the JVM up inside a native process--which is what the &lt;code&gt;java&lt;/code&gt; host does)&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Helpers&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/mapbox/jni.hpp&quot;&gt;jni.hpp&lt;/a&gt;: a modern, type-safe, header-only, C++14 wrapper for JNI&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/bytedeco/javacpp&quot;&gt;JavaCPP&lt;/a&gt;: The missing bridge between Java and native C++&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/SwiftAndroid/swift-jni&quot;&gt;swift-jni&lt;/a&gt;: Swift wrappers around JNI&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h1&gt;JNA&lt;/h1&gt; 
&lt;p&gt;&lt;a href=&quot;https://github.com/java-native-access/jna&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;h1&gt;JNR (jnr-ffi): Java Abstracted Foreign Function Layer&lt;/h1&gt; 
&lt;p&gt;Java library for loading native libraries without writing JNI code by hand or using tools such as SWIG. JNR is a comparingly young project that target the same problem. Similarly as JNA or Bridj it does not require native programming. There&apos;s not much documentation or reviews at the moment, but JNR is often called promising.&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://github.com/jnr/jnr-ffi&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;h1&gt;BridJ&lt;/h1&gt; 
&lt;p&gt;&lt;a href=&quot;https://github.com/nativelibs4java/BridJ&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;h1&gt;Project Panama&lt;/h1&gt; 
&lt;p&gt;&lt;a href=&quot;http://openjdk.java.net/projects/panama/&quot;&gt;Website (OpenJDK)&lt;/a&gt;&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Panama: A Foreign Policy for Java 
  &lt;ul&gt; 
   &lt;li&gt;Devoxx 2018; Maurizio Cimadamore&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=cfxBrYud9KM&quot;&gt;https://www.youtube.com/watch?v=cfxBrYud9KM&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Native Interfaces: The Phantom Menace 
  &lt;ul&gt; 
   &lt;li&gt;NYJavaSIG, February 7, 2018&lt;/li&gt; 
   &lt;li&gt;Tony Printezis - JVM Engineer - Twitter&lt;/li&gt; 
   &lt;li&gt;JNI, Project Panama&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.eventbrite.com/e/nyjavasig-native-interfaces-the-phantom-menace-and-java-9-compatibility-tickets-42519931259#&quot;&gt;https://www.eventbrite.com/e/nyjavasig-native-interfaces-the-phantom-menace-and-java-9-compatibility-tickets-42519931259#&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=YxHb6kAGZ10&quot;&gt;https://www.youtube.com/watch?v=YxHb6kAGZ10&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;GraalVM&lt;/h2&gt; 
&lt;p&gt;Supports native execution of LLVM bitcode using &lt;a href=&quot;https://github.com/graalvm/sulong&quot;&gt;Sulong&lt;/a&gt;. This enables interop to C/C++, Fortran, and other languages that can be compiled to LLVM bitcode.&lt;/p&gt; 
&lt;h1&gt;Other FFI&lt;/h1&gt;
	</description>
    </item>
    <item>
      <title>Jikes RVM</title>
      <link>https://tedneward.github.io/Research/vms/jvm/jikes/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">vms/jvm/jikes/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.jikesrvm.org/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/JikesRVM/JikesRVM&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;No updates since 2016.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>NanoVM</title>
      <link>https://tedneward.github.io/Research/vms/jvm/nanovm/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">vms/jvm/nanovm/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;http://www.harbaum.org/till/nanovm/index.shtml&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/harbaum/NanoVM&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;No updates since 2015 or so.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Waba (JVM)</title>
      <link>https://tedneward.github.io/Research/vms/jvm/waba/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">vms/jvm/waba/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://wabasoft.com/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;http://waba.sourceforge.net/&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Looks to not have been updated since 2001. &lt;a href=&quot;https://sourceforge.net/projects/waba/files/waba/20010521/&quot;&gt;This&lt;/a&gt; looks to be the latest source drop. Might be interesting for pedagogical purposes.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>miniVM</title>
      <link>https://tedneward.github.io/Research/vms/minivm/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">vms/minivm/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/FastVM/minivm&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;The most common way to get code running on MiniVM is to use &lt;a href=&quot;/languages/paka&quot;&gt;Paka&lt;/a&gt;.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>NanoVM</title>
      <link>https://tedneward.github.io/Research/vms/nanovm/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">vms/nanovm/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;http://www.harbaum.org/till/nanovm/index.shtml&quot;&gt;Website&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;No updates since 2005.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Parrot</title>
      <link>https://tedneward.github.io/Research/vms/parrot/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">vms/parrot/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;http://parrot.org/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/parrot/parrot&quot;&gt;Github&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Parrot work appears to have stopped in 2014.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>JavaScriptCore</title>
      <link>https://tedneward.github.io/Research/vms/js/jscore/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">vms/js/jscore/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://docs.webkit.org/Deep%20Dive/JSC/JavaScriptCore.html&quot;&gt;Website&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>V8</title>
      <link>https://tedneward.github.io/Research/vms/js/v8/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">vms/js/v8/index.html</guid>
      	<description>
	&lt;p&gt;The engine that drives NodeJS. Embeddable.&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://github.com/danbev/learning-v8&quot;&gt;Learning V8 project&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://v8.dev/blog&quot;&gt;V8 Dev Blog&lt;/a&gt;:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;/libraries/oilpan&quot;&gt;Oilpan&lt;/a&gt; is a standalone garbage collection library for C++ hosted by the V8 project.&lt;/li&gt; 
 &lt;li&gt;WebAssembly topics: 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://v8.dev/blog/4gb-wasm-memory&quot;&gt;Up to 4GB of memory&lt;/a&gt;: Thanks to recent work in Chrome and Emscripten, you can now use up to 4GB of memory in WebAssembly applications. That’s up from the previous limit of 2GB.&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://v8.dev/blog/wasm-decompile&quot;&gt;Introducing &lt;code&gt;wasm-decompile&lt;/code&gt;&lt;/a&gt;: wasm-decompile produces output that tries to look like a &quot;very average programming language&quot; while still staying close to the Wasm it represents.&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://v8.dev/blog/emscripten-standalone-wasm&quot;&gt;Standalone WebAssembly binaries using Emscripten&lt;/a&gt;: Emscripten has always focused first and foremost on compiling to the Web and other JavaScript environments like Node.js. But as WebAssembly starts to be used without JavaScript, new use cases are appearing, and so we&apos;ve been working on support for emitting standalone Wasm files from Emscripten, that do not depend on the Emscripten JS runtime!&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://v8.dev/blog/emscripten-llvm-wasm&quot;&gt;Emscripten and the LLVM WebAssembly backend&lt;/a&gt;: WebAssembly is normally compiled from a source language, which means that developers need tools to use it. Because of that, the V8 team works on relevant open-source projects like LLVM, Emscripten, Binaryen, and WABT. This post describes some of the work we’ve been doing on Emscripten and LLVM, which will soon allow Emscripten to switch to the LLVM WebAssembly backend by default — please test it and report any issues!&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://v8.dev/blog/wasm-code-caching&quot;&gt;Code caching for WebAssembly developers&lt;/a&gt;: There’s a saying among developers that the fastest code is code that doesn’t run. Likewise, the fastest compiling code is code that doesn’t have to be compiled. WebAssembly code caching is a new optimization in Chrome and V8 that tries to avoid code compilation by caching the native code produced by the compiler. We’ve written about how Chrome and V8 cache JavaScript code in the past, and best practices for taking advantage of this optimization. In this blog post, we describe the operation of Chrome’s WebAssembly code cache and how developers can take advantage of it to speed up loading for applications with large WebAssembly modules.&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://v8.dev/blog/sparkplug&quot;&gt;Sparkplug&lt;/a&gt;: a non-optimizing JavaScript compiler&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://v8.dev/blog/short-builtin-calls&quot;&gt;Short builtin calls&lt;/a&gt;: we’ve realized that function calls between embedded builtins and JIT compiled code can come at a considerable performance penalty. This cost depends on the microarchitecture of the CPU. In this post we’ll explain why this is happening, what the performance looks like, and what we’re planning to do to resolve this long-term.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://v8.dev/blog/fast-super&quot;&gt;Super fast property access&lt;/a&gt;: The super keyword can be used for accessing properties and functions on an object’s parent.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://v8.dev/blog/adaptor-frame&quot;&gt;Faster JavaScript calls&lt;/a&gt;: JavaScript allows calling a function with a different number of arguments than the expected number of parameters, i.e., one can pass fewer or more arguments than the declared formal parameters. The former case is called under-application and the latter is called over-application.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://v8.dev/blog/non-backtracking-regexp&quot;&gt;An additional non-backtracking RegExp engine&lt;/a&gt;: V8 ships with a new experimental non-backtracking RegExp engine (in addition to the existing Irregexp engine) which guarantees execution in linear time with respect to the size of the subject string.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://v8.dev/blog/system-analyzer&quot;&gt;Indicium&lt;/a&gt;: This system analyzer is a unified web interface to trace, debug and analyse patterns of how Inline Caches (ICs) and Maps are created and modified in real-world applications. V8 already has a tracing infrastructure for ICs and Maps which can process and analyse IC events using the IC Explorer and Map events using Map Processor. However, previous tools didn&apos;t allow us to analyze maps and ICs holistically and this is now possible with system analyzer.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://v8.dev/blog/slack-tracking&quot;&gt;Slack tracking&lt;/a&gt;: Slack tracking is a way to give new objects an initial size that is larger than what they may actually use, so they can have new properties added quickly. And then, after some period of time, to magically return that unused space to the system. Neat, huh?&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://v8.dev/blog/high-performance-cpp-gc&quot;&gt;High-performance garbage collection for C++&lt;/a&gt;: Because the C++ object graph around the DOM is heavily tangled with Javascript objects, the Chromium team switched a couple of years ago to a garbage collector, called Oilpan, for managing this kind of memory. Oilpan is a garbage collector written in C++ for managing C++ memory that can be connected to V8 using cross-component tracing that treats the tangled C++/JavaScript object graph as one heap.&lt;/li&gt; 
 &lt;li&gt;Understanding the ECMAScript spec: &lt;a href=&quot;https://v8.dev/blog/understanding-ecmascript-part-1&quot;&gt;Part 1&lt;/a&gt; | &lt;a href=&quot;https://v8.dev/blog/understanding-ecmascript-part-2&quot;&gt;Part 2&lt;/a&gt; | &lt;a href=&quot;https://v8.dev/blog/understanding-ecmascript-part-3&quot;&gt;Part 3&lt;/a&gt; | &lt;a href=&quot;https://v8.dev/blog/understanding-ecmascript-part-4&quot;&gt;Part 4&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;Blazingly-fast parsing: &lt;a href=&quot;https://v8.dev/blog/scanner&quot;&gt;Part 1: the scanner&lt;/a&gt; | &lt;a href=&quot;https://v8.dev/blog/preparser&quot;&gt;Part 2: lazy parsing&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://v8.dev/blog/pointer-compression&quot;&gt;Pointer compression in V8&lt;/a&gt;: There is a constant battle between memory and performance. As users, we would like things to be fast as well as consume as little memory as possible. Unfortunately, usually improving performance comes at a cost of memory consumption (and vice versa).&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://v8.dev/blog/regexp-tier-up&quot;&gt;Improving V8 regular expressions&lt;/a&gt;: In its default configuration, V8 compiles regular expressions to native code upon the first execution. As part of our work on JIT-less V8, we introduced an interpreter for regular expressions. Interpreting regular expressions has the advantage of using less memory, but it comes with a performance penalty. In this blog post we describe how we take advantage of the upsides of interpreting regular expressions while mitigating the downsides.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://v8.dev/blog/v8-lite&quot;&gt;A lighter V8&lt;/a&gt;: In late 2018 we started a project called V8 Lite, aimed at dramatically reducing V8’s memory usage. Initially this project was envisioned as a separate Lite mode of V8 specifically aimed at low-memory mobile devices or embedder use-cases that care more about reduced memory usage than throughput execution speed. However, in the process of this work, we realized that many of the memory optimizations we had made for this Lite mode could be brought over to regular V8 thereby benefiting all users of V8.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://v8.dev/blog/code-caching-for-devs&quot;&gt;Code caching for Javascript developers&lt;/a&gt;: In this blog post, we offer a few pieces of advice for JS developers who want to make the best use of code caching to improve the startup of their websites. This advice focuses on the implementation of caching in Chrome/V8, but most of it is likely transferable to other browsers’ code caching implementations too.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://v8.dev/docs/cross-compile-ios&quot;&gt;Cross-compiling for iOS&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://jayconrod.com/posts/51/a-tour-of-v8--full-compiler&quot;&gt;V8: full compiler&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://jayconrod.com/posts/55/a-tour-of-v8-garbage-collection&quot;&gt;V8: Garbage Collection&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://v8.dev/blog/static-roots&quot;&gt;Static Roots: Objects with Compile-Time Constant Addresses&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;(Lots more posts there, sorted by category as well: &lt;a href=&quot;https://v8.dev/blog/tags/internals&quot;&gt;internals&lt;/a&gt; &lt;a href=&quot;https://v8.dev/blog/tags/ecmascript&quot;&gt;ECMAScript spec&lt;/a&gt; &lt;a href=&quot;https://v8.dev/blog/tags/webassembly&quot;&gt;WebAssembly&lt;/a&gt; &lt;a href=&quot;https://v8.dev/blog/tags/memory&quot;&gt;memory&lt;/a&gt;)&lt;/p&gt; 
&lt;p&gt;Videos &lt;a href=&quot;https://www.youtube.com/@theavocoder&quot;&gt;by Lydia Hallie&lt;/a&gt;:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=zdGfo6I1yrA&amp;amp;t=1s&quot;&gt;Execution Contexts&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?app=desktop&amp;amp;v=Xs1EMmBLpn4&quot;&gt;Promise Execution&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?app=desktop&amp;amp;v=eiC58R16hb8&quot;&gt;Event Loop&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;&lt;a href=&quot;https://github.com/cmdr2/v8-android&quot;&gt;v8-android&lt;/a&gt;: Example Android Studio project that embeds v8 (plus some notes on compiling v8 for android)&lt;/p&gt; 
&lt;h2&gt;FFI&lt;/h2&gt; 
&lt;p&gt;&lt;a href=&quot;https://github.com/eclipsesource/J2V8&quot;&gt;Java bindings for V8&lt;/a&gt;: J2V8 is a set of Java bindings for V8. J2V8 focuses on performance and tight integration with V8. It also takes a &apos;primitive first&apos; approach, meaning that if a value can be accessed as a primitive, then it should be. This forces a more static type system between the JS and Java code, but it also improves the performance since intermediate Objects are not created. We developed J2V8 as a high performance engine for our multi-platform mobile toolkit tabris.js and it is a great choice for executing JavaScript on Android devices.&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://github.com/pmed/v8pp&quot;&gt;v8pp&lt;/a&gt;: Bind C++ functions and classes into V8 JavaScript engine&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>GraalVM</title>
      <link>https://tedneward.github.io/Research/vms/jvm/graalvm/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">vms/jvm/graalvm/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.graalvm.org/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/oracle/graal&quot;&gt;Source&lt;/a&gt; | &lt;a href=&quot;http://www.graalvm.org/docs/&quot;&gt;Docs&lt;/a&gt;&lt;/p&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;&quot;GraalVM is a high-performance JDK distribution designed to accelerate the execution of applications written in Java and other JVM languages along with support for JavaScript, Ruby, Python, and a number of other popular languages. GraalVM’s polyglot capabilities make it possible to mix multiple programming languages in a single application while eliminating foreign language call costs.&quot;&lt;/p&gt; 
&lt;/blockquote&gt; 
&lt;hr&gt; 
&lt;h2&gt;Notes&lt;/h2&gt; 
&lt;p&gt;Notes on Graal and Truffle&lt;/p&gt; 
&lt;h3&gt;Introductory Material&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt; &lt;p&gt;Add Graal JIT Compilation to Your JVM Language in 5 Steps, A Tutorial&lt;br&gt; &lt;a href=&quot;http://stefan-marr.de/2015/11/add-graal-jit-compilation-to-your-jvm-language-in-5-easy-steps-step-1/&quot;&gt;http://stefan-marr.de/2015/11/add-graal-jit-compilation-to-your-jvm-language-in-5-easy-steps-step-1/&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;The SimpleLanguage, an example of using Truffle with great JavaDocs; official getting-started project:&lt;br&gt; &lt;a href=&quot;https://github.com/graalvm/simplelanguage&quot;&gt;https://github.com/graalvm/simplelanguage&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Truffle Tutorial, Christan Wimmer, PLDI 2016, 3h recording&lt;br&gt; &lt;a href=&quot;https://youtu.be/FJY96_6Y3a4&quot;&gt;https://youtu.be/FJY96_6Y3a4&lt;/a&gt; &lt;a href=&quot;https://lafo.ssw.uni-linz.ac.at/pub/papers/2016_PLDI_Truffle.pdf&quot;&gt;Slides&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Truffle Tutorial, Nicolas Laurent&lt;br&gt; &lt;a href=&quot;https://norswap.com/truffle-tutorial/&quot;&gt;https://norswap.com/truffle-tutorial/&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Series of blog posts on implementing a Lisp&lt;br&gt; &lt;a href=&quot;http://cesquivias.github.io/&quot;&gt;http://cesquivias.github.io/&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Truffle Tutorials, Presentations, Publications&lt;br&gt; &lt;a href=&quot;https://github.com/graalvm/graal/blob/master/docs/Publications.md&quot;&gt;https://github.com/graalvm/graal/blob/master/docs/Publications.md&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Graal VM and Graal.JS on the Oracle Technology Network&lt;br&gt; &lt;a href=&quot;http://www.oracle.com/technetwork/oracle-labs/program-languages/overview/index-2301583.html&quot;&gt;http://www.oracle.com/technetwork/oracle-labs/program-languages/overview/index-2301583.html&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Papers on Truffle&lt;br&gt; &lt;a href=&quot;http://ssw.jku.at/Research/Projects/JVM/Truffle.html&quot;&gt;http://ssw.jku.at/Research/Projects/JVM/Truffle.html&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Papers on Graal&lt;br&gt; &lt;a href=&quot;http://ssw.jku.at/Research/Projects/JVM/Graal.html&quot;&gt;http://ssw.jku.at/Research/Projects/JVM/Graal.html&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Language Implementations&lt;/h3&gt; 
&lt;h4&gt;Maintained&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;FastR, an R implementation: &lt;a href=&quot;https://github.com/graalvm/fastr&quot;&gt;https://github.com/graalvm/fastr&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;TruffleRuby: &lt;a href=&quot;https://github.com/graalvm/truffleruby&quot;&gt;https://github.com/graalvm/truffleruby&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;SOM Smalltalk: &lt;a href=&quot;https://github.com/SOM-st/TruffleSOM&quot;&gt;https://github.com/SOM-st/TruffleSOM&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;SOMns, a Newspeak: &lt;a href=&quot;https://github.com/smarr/SOMns&quot;&gt;https://github.com/smarr/SOMns&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;SimpleLanguage: &lt;a href=&quot;https://github.com/graalvm/simplelanguage&quot;&gt;https://github.com/graalvm/simplelanguage&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;Graal.JS, a JavaScript implementation: &lt;a href=&quot;http://www.oracle.com/technetwork/oracle-labs/program-languages/overview/index-2301583.html&quot;&gt;http://www.oracle.com/technetwork/oracle-labs/program-languages/overview/index-2301583.html&lt;/a&gt;, &lt;a href=&quot;https://github.com/graalvm/graaljs/&quot;&gt;https://github.com/graalvm/graaljs/&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;GraalPython, a Python 3 implementation: &lt;a href=&quot;https://github.com/graalvm/graalpython/&quot;&gt;https://github.com/graalvm/graalpython/&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;Sulong, a LLVM IR implementation on top of the JVM &lt;a href=&quot;https://github.com/graalvm/sulong&quot;&gt;https://github.com/graalvm/sulong&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;RegexLanguage, a JavaScript-flavored regex language &lt;a href=&quot;https://github.com/oracle/graal/blob/master/regex/src/com.oracle.truffle.regex/src/com/oracle/truffle/regex/RegexLanguage.java#L38&quot;&gt;https://github.com/oracle/graal/blob/master/regex/src/com.oracle.truffle.regex/src/com/oracle/truffle/regex/RegexLanguage.java#L38&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Status Unknown&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;ZipPy, a Python 3: &lt;a href=&quot;https://github.com/securesystemslab/zippy&quot;&gt;https://github.com/securesystemslab/zippy&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Experiments&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt; &lt;p&gt;TruffleSqueak, Squeak interpreter on top of Truffle &lt;a href=&quot;https://github.com/timfel/trufflesqueak&quot;&gt;https://github.com/timfel/trufflesqueak&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;TruffleC, a C on top of the JVM: &lt;a href=&quot;http://dl.acm.org/citation.cfm?id=2647528&quot;&gt;http://dl.acm.org/citation.cfm?id=2647528&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Mumbler: A Lisp&lt;br&gt; &lt;a href=&quot;https://github.com/cesquivias/mumbler&quot;&gt;https://github.com/cesquivias/mumbler&lt;/a&gt; &amp;amp; &lt;a href=&quot;http://cesquivias.github.io/&quot;&gt;http://cesquivias.github.io/&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Lua&lt;br&gt; &lt;a href=&quot;https://github.com/lucasallan/LuaTruffle&quot;&gt;https://github.com/lucasallan/LuaTruffle&lt;/a&gt; &amp;amp; &lt;a href=&quot;http://www.luatruffle.org/&quot;&gt;http://www.luatruffle.org/&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Hex&lt;br&gt; &lt;a href=&quot;https://bitbucket.org/hexafraction/truffles&quot;&gt;https://bitbucket.org/hexafraction/truffles&lt;/a&gt; &amp;amp; &lt;a href=&quot;https://hextruffle.wordpress.com/&quot;&gt;https://hextruffle.wordpress.com/&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Golo (a minimal Truffle backend)&lt;br&gt; &lt;a href=&quot;https://github.com/smarr/golo-lang/tree/truffle&quot;&gt;https://github.com/smarr/golo-lang/tree/truffle&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;TruffleMATE, a Smalltalk with a completely reified runtime system&lt;br&gt; &lt;a href=&quot;https://github.com/charig/TruffleMATE&quot;&gt;https://github.com/charig/TruffleMATE&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;PureScript&lt;br&gt; &lt;a href=&quot;https://github.com/slamdata/truffled-purescript&quot;&gt;https://github.com/slamdata/truffled-purescript&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Mozart-Graal: An implementation of the Oz language&lt;br&gt; &lt;a href=&quot;https://github.com/eregon/mozart-graal&quot;&gt;https://github.com/eregon/mozart-graal&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;DynSem: A Language Specification-Language, as a meta-interpreter in Truffle&lt;br&gt; &lt;a href=&quot;https://github.com/metaborg/dynsem&quot;&gt;https://github.com/metaborg/dynsem&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Cover: A Safe Subset of C++&lt;br&gt; &lt;a href=&quot;https://github.com/gerard-/cover&quot;&gt;https://github.com/gerard-/cover&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;TrufflePascal&lt;br&gt; &lt;a href=&quot;https://github.com/Aspect26/TrufflePascal/&quot;&gt;https://github.com/Aspect26/TrufflePascal/&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Reactive Ruby: Truffle Ruby meets Reactive Programming&lt;br&gt; &lt;a href=&quot;https://github.com/guidosalva/ReactiveRubyTruffle&quot;&gt;https://github.com/guidosalva/ReactiveRubyTruffle&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;PorcE: An Orc implementation on top of Truffle&lt;br&gt; &lt;a href=&quot;https://github.com/orc-lang/orc/tree/master/PorcE&quot;&gt;https://github.com/orc-lang/orc/tree/master/PorcE&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;shen-truffle&lt;br&gt; &lt;a href=&quot;https://github.com/ragnard/shen-truffle&quot;&gt;https://github.com/ragnard/shen-truffle&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;NQP - Not Quite Perl (6)&lt;br&gt; &lt;a href=&quot;https://github.com/perl6/nqp/tree/truffle&quot;&gt;https://github.com/perl6/nqp/tree/truffle&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Go&lt;br&gt; &lt;a href=&quot;https://github.com/PDZaninov/GoLang-Compiler&quot;&gt;https://github.com/PDZaninov/GoLang-Compiler&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Key Papers&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt; &lt;p&gt;The Truffle paper: “Self-Optimizing AST Interpreters”&lt;br&gt; &lt;a href=&quot;http://lafo.ssw.uni-linz.ac.at/papers/2012_DLS_SelfOptimizingASTInterpreters.pdf&quot;&gt;http://lafo.ssw.uni-linz.ac.at/papers/2012_DLS_SelfOptimizingASTInterpreters.pdf&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;How to represent Objects Efficiently: “An Object Storage Model for the Truffle Language Implementation Framework”&lt;br&gt; &lt;a href=&quot;http://chrisseaton.com/rubytruffle/pppj14-om/pppj14-om.pdf&quot;&gt;http://chrisseaton.com/rubytruffle/pppj14-om/pppj14-om.pdf&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;The Truffle+Graal paper: &quot;One VM to Rule Them All&quot;&lt;br&gt; &lt;a href=&quot;http://lafo.ssw.uni-linz.ac.at/papers/2013_Onward_OneVMToRuleThemAll.pdf&quot;&gt;http://lafo.ssw.uni-linz.ac.at/papers/2013_Onward_OneVMToRuleThemAll.pdf&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;The Partical Evaluation paper: &quot;Practical partial evaluation for high-performance dynamic language runtimes&quot;&lt;br&gt; accessible via: &lt;a href=&quot;https://chrisseaton.com/rubytruffle/pldi17-truffle/pldi17-truffle.pdf&quot;&gt;https://chrisseaton.com/rubytruffle/pldi17-truffle/pldi17-truffle.pdf&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Other Related Papers&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;One Compiler: Deoptimization to Optimized Code (work on SubstrateVM, AOT compilation of Truffle code)&lt;br&gt; &lt;a href=&quot;http://doi.org/10.1145/3033019.3033025&quot;&gt;http://doi.org/10.1145/3033019.3033025&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>jvmulator</title>
      <link>https://tedneward.github.io/Research/vms/jvm/jvmulator/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">vms/jvm/jvmulator/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/alblue/jvmulator&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;This provides a simple emulator for Java bytecode as well as an in-memory Java compiler to allow bytecode to be generated. The generated code can be executed as well as emulated to allow stepping through bytecode line by line, and seeing what the content of the local variables or stack happens to be.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>OpenJDK JVM</title>
      <link>https://tedneward.github.io/Research/vms/jvm/openjdk/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">vms/jvm/openjdk/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;http://openjdk.java.net/groups/hotspot/&quot;&gt;OpenJDK&lt;/a&gt; (&lt;a href=&quot;https://github.com/openjdk&quot;&gt;Source&lt;/a&gt;); see &lt;a href=&quot;https://foojay.io/&quot;&gt;foojay&lt;/a&gt; for interesting details on OpenJDK&lt;/p&gt; 
&lt;h3&gt;Performance-related&lt;/h3&gt; 
&lt;p&gt;&lt;a href=&quot;https://www.oracle.com/java/technologies/whitepaper.html&quot;&gt;Java HotSpot Performance Engine Architecture&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://www.oracle.com/java/technologies/tuning-garbage-collection-v50-java-virtual-machine.html&quot;&gt;Tuning Garbage Collection with the 5.0 JVM&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://github.com/moditect/jfr-analytics&quot;&gt;jfr-analytics&lt;/a&gt;: An exploration for running analytics on JDK Flight Recorder recordings. There&apos;s two areas of interest: (1) Pull-based SQL queries on JFR recording files, using Apache Calcite, and (2) Streaming queries on realtime JFR event streams (implementation tbd., e.g. via Apache Flink or Akka Streams).&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>liblg</title>
      <link>https://tedneward.github.io/Research/vms/liblg/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">vms/liblg/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/codr7/liblg&quot;&gt;Source&lt;/a&gt; | &lt;a href=&quot;https://news.ycombinator.com/item?id=24388687&quot;&gt;HN&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>MoarVM</title>
      <link>https://tedneward.github.io/Research/vms/moarvm/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">vms/moarvm/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://moarvm.org&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/MoarVM/MoarVM&quot;&gt;Github&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;From Github:&lt;/p&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;MoarVM (short for Metamodel On A Runtime Virtual Machine) is a runtime built for the 6model object system. It is primarily aimed at running NQP and Rakudo, but should be able to serve as a backend for any compilers built using the NQP compiler toolchain.&lt;/p&gt; 
&lt;/blockquote&gt;
	</description>
    </item>
    <item>
      <title>Neko (VM)</title>
      <link>https://tedneward.github.io/Research/vms/neko/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">vms/neko/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;http://nekovm.org/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/HaxeFoundation/neko&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>PearPC</title>
      <link>https://tedneward.github.io/Research/vms/pearpc/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">vms/pearpc/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;http://pearpc.sourceforge.net/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/sebastianbiallas/pearpc&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>PrimJS</title>
      <link>https://tedneward.github.io/Research/vms/js/primjs/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">vms/js/primjs/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/lynx-family/primjs&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Built on top of &lt;a href=&quot;../quickjs&quot;&gt;QuickJS&lt;/a&gt;.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Emulators written in JavaScript</title>
      <link>https://tedneward.github.io/Research/vms/jsemu/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">vms/jsemu/index.html</guid>
      	<description>
	&lt;p&gt;A list of emulators written in the JavaScript programming language.&lt;/p&gt; 
&lt;p&gt;This list started as a compilation of JavaScript emulators posted to Echo JS&lt;br&gt; over the years. If you know about any missing emulators, please consider&lt;br&gt; adding them to the collection: the source for this page is available on&lt;br&gt; &lt;a href=&quot;https://github.com/fcambus/jsemu&quot;&gt;GitHub&lt;/a&gt;. Thank you in advance.&lt;/p&gt; 
&lt;h2&gt;Acorn&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://floooh.github.io/tiny8bit/atom.html&quot;&gt;Atom Tiny Emu&lt;/a&gt; - by Andre Weissflog (&lt;a href=&quot;https://github.com/floooh/chips-test&quot;&gt;source&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://econet.network/atom/&quot;&gt;Acorn Atom Emulator&lt;/a&gt; - by Phil Mainwaring. Software archive &lt;a href=&quot;http://econet.network/atom/menu.html&quot;&gt;here&lt;/a&gt;. (Older version &lt;a href=&quot;http://phils-place.co.uk/HTeMuLator/atom/&quot;&gt;here&lt;/a&gt;: Type &quot;OLD&quot; for an Easter Egg.)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://elkjs.azurewebsites.net/&quot;&gt;ElkJS&lt;/a&gt; - JavaScript based Acorn Electron emulator (&lt;a href=&quot;https://github.com/dmcoles/elkjs&quot;&gt;Source&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://bbc.godbolt.org&quot;&gt;JSBeeb&lt;/a&gt; - JavaScript BBC Micro emulator (&lt;a href=&quot;https://github.com/mattgodbolt/jsbeeb&quot;&gt;Source&lt;/a&gt;) (&lt;a href=&quot;https://xania.org/Emulation&quot;&gt;Development blog&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://jsacorn.commandercoder.com/?model=atom&quot;&gt;JSAtom&lt;/a&gt; - JavaScript Acorn Atom emulator including Software Archive (&lt;a href=&quot;https://github.com/CommanderCoder/JSATOM&quot;&gt;Source&lt;/a&gt;) Based on JSBeeb&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Altair&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://s2js.com/altair/&quot;&gt;MITS Altair Simulator&lt;/a&gt; Front panel simulation of the 8080-based Altair, by Ian Davies, built on 8080.js&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Amstrad&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://web.archive.org/web/20130302051242/http://www.cpcbox.com/&quot;&gt;CPCBox&lt;/a&gt; - Amstrad CPC emulator in JavaScript (archive link)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://floooh.github.io/tiny8bit/cpc.html&quot;&gt;CPC Tiny Emu&lt;/a&gt; - by Andre Weissflog (&lt;a href=&quot;https://github.com/floooh/chips-test&quot;&gt;source&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;Roland - An Amstrad CPC emulator written in JavaScript. (&lt;a href=&quot;https://sourceforge.net/p/emuscriptoria/code/HEAD/tree/jcpc.js&quot;&gt;Source&lt;/a&gt;)&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Apple&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.scullinsteel.com/apple1/&quot;&gt;Apple 1js&lt;/a&gt; - by Will Scullin&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://inindev.github.io/apple2e/&quot;&gt;Apple2e&lt;/a&gt; - Apple IIe emulator by John Clark (&lt;a href=&quot;https://github.com/inindev/apple2e&quot;&gt;Source&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.scullinsteel.com/apple2/&quot;&gt;Apple IIjs&lt;/a&gt; - An Apple ][ Emulator in JavaScript&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://porkrind.org/a2/&quot;&gt;a2&lt;/a&gt; - A fast, WebGL optimized Apple ][+ emulator&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/gmegidish/apple2js&quot;&gt;Apple2JS&lt;/a&gt; - A JavaScript emulator for the Apple II&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/jsdf/macemu&quot;&gt;BasiliskII&lt;/a&gt; - An Emscripten Port of BasiliskII (&lt;a href=&quot;https://jamesfriend.com.au/projects/basiliskii/BasiliskII-worker.html&quot;&gt;Demo 1&lt;/a&gt;, &lt;a href=&quot;http://macintosh-js-html.herokuapp.com/&quot;&gt;Demo 2&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/yksoft1/minivmac-em&quot;&gt;MiniVMac-Em&lt;/a&gt; - An Emscripten Port of MiniVMac (&lt;a href=&quot;https://yksoft1.github.io/mvmacdemo.html&quot;&gt;Demo&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.skibo.net/6502/apple2/&quot;&gt;Yet Another Apple 2+ in JavaScript&lt;/a&gt; - by Thomas Skibo&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Atari&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://8bitworkshop.com/?platform=vcs&amp;amp;file=examples%2Fhello&quot;&gt;8bit Workshop&lt;/a&gt; - VCS IDE by Steven Hugg, building on Javatari.js&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://estyjs.azurewebsites.net&quot;&gt;EstyJS&lt;/a&gt; - A pretty fast and functional JavaScript Atari ST emulator (&lt;a href=&quot;https://github.com/dmcoles/estyjs&quot;&gt;Source&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://javatari.org&quot;&gt;Javatari.js&lt;/a&gt; - Atari 2600 emulator by Paulo Augusto Peccin. (&lt;a href=&quot;https://www.2600online.com/adventure.php&quot;&gt;Example cartridges online&lt;/a&gt;) (&lt;a href=&quot;https://github.com/ppeccin/javatari.js&quot;&gt;Source&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://zerstoerung.de/jsa8e/&quot;&gt;jsA8E&lt;/a&gt; - JavaScript version of the A8E Atari 800 XL Emulator&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://raz0red.github.io/js7800/&quot;&gt;JS7800&lt;/a&gt; - JavaScript Atari 7800 Emulator&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Commodore&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;http://commodore-lcd.lgb.hu/jsemu/&quot;&gt;Commodore LCD emulator&lt;/a&gt; - by Gábor Lénárt &quot;LGB&quot;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.skibo.net/6502/pet2001/&quot;&gt;Commodore PET&lt;/a&gt; - by Thomas Skibo&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.kingsquare.nl/jsc64/&quot;&gt;JSC64&lt;/a&gt; - Commodore 64 emulator written in JavaScript (&lt;a href=&quot;https://github.com/Reggino/jsc64&quot;&gt;Source&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://mborgbrant.github.io/c64js/&quot;&gt;c64js&lt;/a&gt; - Commodore 64 emulator written in JavaScript by Mikael Borgbrant (&lt;a href=&quot;https://github.com/mborgbrant/c64js&quot;&gt;Source&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://floooh.github.io/tiny8bit/c64.html&quot;&gt;C64 Tiny Emu&lt;/a&gt; - by Andre Weissflog (&lt;a href=&quot;https://github.com/floooh/chips-test&quot;&gt;source&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.robsayers.com/jskim1/&quot;&gt;Kim1&lt;/a&gt; - emulation in JavaScript by Rob Sayers (&lt;a href=&quot;https://github.com/rsayers/jskim1&quot;&gt;Source&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://scriptedamigaemulator.net&quot;&gt;SAE&lt;/a&gt; - Scripted Amiga Emulator (&lt;a href=&quot;https://github.com/naTmeg/ScriptedAmigaEmulator&quot;&gt;Source&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.mdawson.net/vic20chrome/vic20.php&quot;&gt;VIC-20 Emulator&lt;/a&gt; - JavaScript VIC-20 emulator&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://vice.janicek.co/c64/&quot;&gt;VICE.js&lt;/a&gt; - Versatile Commodore Emulator for JavaScript (&lt;a href=&quot;https://github.com/rjanicek/vice.js&quot;&gt;Source&lt;/a&gt;)&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Data General&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.novasareforever.org/novajs/index.php&quot;&gt;Novas Are Forever&lt;/a&gt; - by Wild Hare Computer Systems, for the 50th anniversary.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;DEC&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.masswerk.at/spacewar/&quot;&gt;PDP-1 running the SpaceWar game&lt;/a&gt; and the &lt;a href=&quot;https://www.masswerk.at/minskytron/&quot;&gt;Minskytron demo&lt;/a&gt; - by Norbert Landsteiner&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://programmer209.wordpress.com/2011/01/30/pdp-8-assembly-language-part-2/&quot;&gt;PDP-8&lt;/a&gt; and &lt;a href=&quot;https://programmer209.wordpress.com/2011/08/14/pdp-11-assembly-language-simulator/&quot;&gt;PDP-11&lt;/a&gt; simulators with assembly language interfaces (explanatory articles with full source, not live site) - by programmer209&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://skn.noip.me/pdp11/pdp11.html&quot;&gt;JavaScript PDP 11&lt;/a&gt; - PDP-11/70 emulator with simulated front panel and a choice of operating systems. By Paul Nankervis&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://pdp11.aiju.de/&quot;&gt;PDP-11 Emulator&lt;/a&gt; - A JavaScript PDP-11 emulator running UNIX Sixth Edition. By Julius Schmidt&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://pavel-krivanek.github.io/pdp11/&quot;&gt;with teletype&lt;/a&gt; - PDP-11 emulator with teletype interface&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://takahirox.github.io/pdp11-js/unixv6.html&quot;&gt;pdp11-js&lt;/a&gt; - PDP-11 emulator with UNIX V6. By Takahiro Aoyagi (&lt;a href=&quot;https://github.com/takahirox/pdp11-js&quot;&gt;Source&lt;/a&gt;)&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Nintendo&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/schibo/1964js&quot;&gt;1964js&lt;/a&gt; - JavaScript port of the 1964 N64 emulator for Windows&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/jpikl/cfxnes&quot;&gt;CfxNES&lt;/a&gt; - JavaScript NES Emulator (&lt;a href=&quot;https://cfxnes.herokuapp.com/&quot;&gt;Demo&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://app.7io.org/CycloaJS/&quot;&gt;CycloaJS&lt;/a&gt; - JavaScript NES Emulator (&lt;a href=&quot;https://github.com/ledyba/CycloaJS&quot;&gt;Source&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://bitbucket.org/tsone/em-fceux&quot;&gt;em-fceux&lt;/a&gt; - an Emscripten port of FCEUX, an emulator of NES, Famicom, Famicom Disk System (FDS), and Dendy consoles. &lt;a href=&quot;https://tsone.kapsi.fi/em-fceux/&quot;&gt;Demo site&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://endrift.github.io/gbajs/&quot;&gt;GBA.js&lt;/a&gt; - Game Boy Advance in the Browser (&lt;a href=&quot;https://github.com/endrift/gbajs&quot;&gt;Source&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://taisel.github.io/IodineGBA/&quot;&gt;IodineGBA&lt;/a&gt; - A Game Boy Advance emulator written entirely in JavaScript (&lt;a href=&quot;https://github.com/taisel/IodineGBA&quot;&gt;Source&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://gba.ninja/&quot;&gt;gba.ninja&lt;/a&gt; - JavaScript port of VisualBoyAdvance-M, a Game Boy Advance emulator (&lt;a href=&quot;https://github.com/simon-paris/gba.ninja&quot;&gt;Source&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://jsnes.org&quot;&gt;JSNES&lt;/a&gt; - A JavaScript NES emulator (&lt;a href=&quot;https://github.com/bfirsh/jsnes&quot;&gt;Source&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://koen.kivits.com/nesnes/&quot;&gt;NESNES&lt;/a&gt; - JavaScript NES emulator, also available as a &lt;a href=&quot;https://github.com/koenkivits/x-nes&quot;&gt;web component&lt;/a&gt; (&lt;a href=&quot;https://github.com/koenkivits/nesnes&quot;&gt;Source&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://zelex.net/nezulator/&quot;&gt;Nezulator&lt;/a&gt; - A NES emulator in JavaScript&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://neilb.net/n64wasm/&quot;&gt;N64Wasm&lt;/a&gt; - A web based N64 Emulator (&lt;a href=&quot;https://github.com/nbarkhina/N64Wasm&quot;&gt;Source&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://tjwei.github.io/xnes/&quot;&gt;XNES&lt;/a&gt; - Experimental JavaScript Super Nintendo emulators (&lt;a href=&quot;https://github.com/tjwei/xnes&quot;&gt;Source&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;jsGB - A Game Boy emulator in JavaScript (&lt;a href=&quot;https://github.com/Two9A/jsGB&quot;&gt;Source&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://ardean.github.io/jsGBC-web/&quot;&gt;jsGBC&lt;/a&gt; - Game Boy Color Emulator written in JavaScript (&lt;a href=&quot;https://github.com/ardean/jsGBC&quot;&gt;Source&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://jquesnelle.github.io/mupen64plus-ui-console/&quot;&gt;mupen64plus&lt;/a&gt; - A port of the popular Nintendo 64 emulator for the Web (&lt;a href=&quot;https://github.com/jquesnelle/mupen64plus-ui-console/&quot;&gt;Source&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://hulkholden.github.io/n64js/&quot;&gt;n64js&lt;/a&gt; - An N64 emulator in JavaScript (&lt;a href=&quot;https://github.com/hulkholden/n64js&quot;&gt;Source&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://koute.github.io/pinky-web/&quot;&gt;pinky&lt;/a&gt; - A Rust based NES emulator ported to the web via WebAssembly (&lt;a href=&quot;https://github.com/koute/pinky/tree/master/pinky-web&quot;&gt;Source&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/44670/desmume-wasm&quot;&gt;DeSmuME-wasm&lt;/a&gt; - A WebAssembly port of the DeSmuME Nintendo DS emulator (&lt;a href=&quot;https://ds.44670.org/&quot;&gt;Demo&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/Unzor/desmond&quot;&gt;Desmond.js&lt;/a&gt; - A portable/embeddable version of DeSmuME-wasm (&lt;a href=&quot;https://js-emulators.github.io/desmond/&quot;&gt;Demo&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/skylersaleh/SkyEmu&quot;&gt;SkyEmu&lt;/a&gt; - SkyEmu is a low level Game Boy, Game Boy Color and Game Boy Advance emulator&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/linoscope/CAMLBOY&quot;&gt;CAMLBOY&lt;/a&gt; - A Game Boy emulator that runs in your browser written in OCaml&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/Unzor/TinyGB&quot;&gt;TinyGB&lt;/a&gt; - A Game Boy emulator that runs only in the terminal written in NodeJS&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://boytacean.joao.me&quot;&gt;Boytacean&lt;/a&gt; - A Game Boy emulator written in Rust that works in the Browser using WebAssembly (&lt;a href=&quot;https://github.com/joamag/boytacean&quot;&gt;Source&lt;/a&gt;)&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Robotron / VEB Mikroelektronik&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://lanale.de/kc85_emu/KC85_Emu.html&quot;&gt;KC85_Emu&lt;/a&gt; - KC85/3 and KC85/4 emulator by Alexander Lang&lt;/li&gt; 
 &lt;li&gt;KC85/2 family emulators by Andre Weissflog (&lt;a href=&quot;https://github.com/floooh/chips-test&quot;&gt;source&lt;/a&gt;): 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://floooh.github.io/tiny8bit/kc85.html?type=kc85_2&quot;&gt;KC85/2 Tiny Emu&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://floooh.github.io/tiny8bit/kc85.html?type=kc85_3&quot;&gt;KC85/3 Tiny Emu&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://floooh.github.io/tiny8bit/kc85.html?type=kc85_4&quot;&gt;KC85/4 Tiny Emu&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://floooh.github.io/tiny8bit/lc80.html&quot;&gt;LC-80&lt;/a&gt; - single board U880-based trainer from the DDR (warning: auto-plays sound at boot), via emscripten. By Andre Weissflog (&lt;a href=&quot;https://github.com/floooh/chips-test&quot;&gt;source&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://floooh.github.io/tiny8bit/z1013.html&quot;&gt;Z1013 Tiny Emu&lt;/a&gt; - by Andre Weissflog (&lt;a href=&quot;https://github.com/floooh/chips-test&quot;&gt;source&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://floooh.github.io/tiny8bit/z9001.html?type=kc87&quot;&gt;KC87 Tiny Emu&lt;/a&gt; - by Andre Weissflog (&lt;a href=&quot;https://github.com/floooh/chips-test&quot;&gt;source&lt;/a&gt;)&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Sega&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://gmarty.github.io/jsSMS/&quot;&gt;jsSMS&lt;/a&gt; - JavaScript Sega Master System &amp;amp; Game Gear emulator (&lt;a href=&quot;https://github.com/gmarty/jsSMS&quot;&gt;Source&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://xania.org/miracle/miracle.html&quot;&gt;Miracle&lt;/a&gt; - Sega Master System emulator (&lt;a href=&quot;https://github.com/mattgodbolt/Miracle&quot;&gt;Source&lt;/a&gt;)&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Sinclair&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;http://jsspeccy.zxdemo.org&quot;&gt;JSSpeccy&lt;/a&gt; - A ZX Spectrum emulator in JavaScript (&lt;a href=&quot;https://github.com/gasman/jsspeccy2&quot;&gt;Source&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.zx81stuff.org.uk/zx81/jtyone.html&quot;&gt;JtyOne Online ZX81 Emulator&lt;/a&gt; - by Simon Holdsworth&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://torinak.com/qaop&quot;&gt;Qaop/JS&lt;/a&gt; - ZX Spectrum emulator&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://nocanvas.zame-dev.org/0004/&quot;&gt;ZX80 Emulator&lt;/a&gt; - JavaScript ZX80 Emulator&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://em.ulat.es/machines/SinclairZX80&quot;&gt;EMF ZX80&lt;/a&gt; - EMF-based ZX80 Emulator - by Steven Goodwin (@MarquisdeGeek) (&lt;a href=&quot;https://github.com/MarquisdeGeek/emf-emulator-sinclair-zx80&quot;&gt;Source&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://em.ulat.es/machines/SinclairZX81&quot;&gt;EMF ZX81&lt;/a&gt; - EMF-based ZX81 Emulator - by Steven Goodwin (@MarquisdeGeek) (&lt;a href=&quot;https://github.com/MarquisdeGeek/emf-emulator-sinclair-zx81&quot;&gt;Source&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.dougrice.plus.com/dev/seg_mk14.htm&quot;&gt;Science of Cambridge MK14 simulator&lt;/a&gt; - by Doug Rice, based on Paul Robson&apos;s offline emulator.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://floooh.github.io/tiny8bit/zx.html?type=zx48k&quot;&gt;ZX Spectrum 48K Tiny Emy&lt;/a&gt; - by Andre Weissflog (&lt;a href=&quot;https://github.com/floooh/chips-test&quot;&gt;source&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://floooh.github.io/tiny8bit/zx.html?type=zx128&quot;&gt;ZX Spectrum 128 Tiny Emu&lt;/a&gt; - by Andre Weissflog (&lt;a href=&quot;https://github.com/floooh/chips-test&quot;&gt;source&lt;/a&gt;)&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Sony&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://kootstra-rene.github.io/enge-js/&quot;&gt;eNGE&lt;/a&gt; - JavaScript browser based PSX emulator (runs games at full speed) (&lt;a href=&quot;https://github.com/kootstra-rene/enge-js&quot;&gt;Source&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;PSeudo - JavaScript/WebGL/WebAudio browser based PLAYSTATION emulator (aka PSX) (needs boot ROM image, not supplied) (&lt;a href=&quot;https://github.com/dkoluris/pseudo&quot;&gt;Source&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://tjwei.github.io/pcsxjs/&quot;&gt;PCSXjs&lt;/a&gt; - Modified PCSX-Reloaded compiled with Emscripten (&lt;a href=&quot;https://github.com/tjwei/pcsxjs&quot;&gt;Source&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/js-emulators/WASMpsx&quot;&gt;WASMpsx&lt;/a&gt; - Easily embeddable fork of PCSXjs&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/kpspemu/kpspemu&quot;&gt;kpspemu&lt;/a&gt; - PSP Emulator written in Kotlin for JVM, JS and Native&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://playjs.purei.org&quot;&gt;Play!.js&lt;/a&gt; - This is a port of Play!, a PlayStation2 emulator, running in a web browser&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Tandy&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://bitchin100.com/CloudT/#/M100Display&quot;&gt;CloudT TRS-80 Model 100 Emulator&lt;/a&gt; - by John R. Hogerhuis (&lt;a href=&quot;https://www.mail-archive.com/m100@lists.bitchin100.com/msg02714.html&quot;&gt;Announcement&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://mc-10.com/&quot;&gt;MC-10 Emulator&lt;/a&gt; - Emulator for the TRS-80 MC-10 microcomputer&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://trsjs.48k.ca/trs80.html&quot;&gt;TRS-80 Model III Emulator&lt;/a&gt; a JavaScript emulator for the TRS-80 Model III, by Peter Phillips&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.haplessgenius.com/mocha/&quot;&gt;JS Mocha&lt;/a&gt; - The HTML5 CoCo 2 Emulator&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Multi-system Emulators&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://archive.org/details/historicalsoftware&quot;&gt;JSMESS examples&lt;/a&gt; - The JavaScript MESS (Multi Emulator Super System) (&lt;a href=&quot;https://github.com/jsmess/jsmess&quot;&gt;Source&lt;/a&gt;) (&lt;a href=&quot;https://github.com/jsmess/jsmess/wiki&quot;&gt;Notes&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/jsdf/pce&quot;&gt;PCE&lt;/a&gt; - PC emulators in JavaScript (Atari ST, &lt;a href=&quot;https://jamesfriend.com.au/pce-js/ibmpc-win/&quot;&gt;IBM PC 5150&lt;/a&gt;, &lt;a href=&quot;https://jamesfriend.com.au/pce-js/&quot;&gt;Macintosh&lt;/a&gt;, RC759 Piccoline)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://toadking.com/retroarch/&quot;&gt;RetroArch&lt;/a&gt; - JavaScript port of RetroArch (bundles Gambatte (Game Boy), Genesis Plus GX, Handy (Lynx), Snes9x Next, VBA Next (Game Boy Advance), Tyrquake and FinalBurn Alpha)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://retroweb.maclab.org&quot;&gt;RetroWeb&lt;/a&gt; - collection of JavaScript emulators and boot media, including Apple-IIe (VisiCalc), Macintosh (System 1.0), Atari 1040ST, Commodore 64, Amiga 500 (Workbench 1.3), IBM PC Model 5150 (PC-DOS, CP/M-86, Cassette Basic), IBM PC XT (DOS, GEM 1.2, VisiCalc, Windows 1.01, 8088 Corruption demo), RC759 Piccoline (Eliza, Bil-simulation, Concurrent CP/M-86), TRS-80.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://floooh.github.io/virtualkc/&quot;&gt;YAKC&lt;/a&gt; - Z1013, Z9001, KC85/2 family, Speccy, CPC, Acorn Atom, C64, with integrated debugging UI (&lt;a href=&quot;https://github.com/floooh/yakc&quot;&gt;source&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://floooh.github.io/tiny8bit/&quot;&gt;Tiny Emulators&lt;/a&gt; - based on the same chip- and system-emulator source code as YAKC, but as minimal WASM apps without fluff (&lt;a href=&quot;https://github.com/floooh/chips-test&quot;&gt;source&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://emulatorjs.netlify.app/&quot;&gt;EmulatorJS&lt;/a&gt; - RetroArch compiled to emscripten with a nice wrapper (&lt;a href=&quot;https://github.com/emulatorjs/emulatorjs&quot;&gt;source&lt;/a&gt;)&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;PC Emulators&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/dreamlayers/em-dosbox&quot;&gt;Em-DOSBox&lt;/a&gt; - An Emscripten port of DOSBox (&lt;a href=&quot;http://playdosgamesonline.com/&quot;&gt;Demo&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/nepx/halfix/&quot;&gt;Halfix&lt;/a&gt; - x86 PC emulator that runs both natively and in the browser, via WebAssembly (&lt;a href=&quot;https://nepx.github.io/halfix-demo/&quot;&gt;Demo 1&lt;/a&gt;, &lt;a href=&quot;https://pixelsuft.github.io/onwin/&quot;&gt;Demo2&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://js-dos.com&quot;&gt;js-dos&lt;/a&gt; - WebAssembly port of DOSBox (fork of Em-DOSBox with better js API) (&lt;a href=&quot;https://js-dos.com/#js-dos-622-demo&quot;&gt;Demo&lt;/a&gt;,&lt;a href=&quot;https://github.com/caiiiycuk/js-dos&quot;&gt;Source&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://bellard.org/jslinux/&quot;&gt;JS/Linux&lt;/a&gt; - JavaScript PC emulator&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://jsdosbox.sourceforge.net&quot;&gt;JsDOSBox&lt;/a&gt; - JavaScript PC DOS emulator (&lt;a href=&quot;https://sourceforge.net/projects/jsdosbox/files/&quot;&gt;Source&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.pcjs.org&quot;&gt;PCjs&lt;/a&gt; - IBM PC Model 5150 emulator (&lt;a href=&quot;https://github.com/jeffpar/pcjs&quot;&gt;Source&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/atrosinenko/qemujs&quot;&gt;QemuJS&lt;/a&gt; - An Emscripten port of QEMU (&lt;a href=&quot;https://atrosinenko.github.io/qemujs-demo&quot;&gt;Demo&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://copy.sh/v86/&quot;&gt;Virtual x86&lt;/a&gt; - x86 virtualization in your browser, recompiling x86 to wasm on the fly (&lt;a href=&quot;https://github.com/copy/v86&quot;&gt;Source&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://jemul8.com&quot;&gt;jemul8&lt;/a&gt; - An object-oriented JavaScript x86 emulator for Node.js and the Browser (&lt;a href=&quot;https://github.com/asmblah/jemul8&quot;&gt;Source&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;jsbochs - Bochs PC emulator for the Browser (&lt;a href=&quot;https://github.com/codinguncut/jsbochs&quot;&gt;Source&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.boxedwine.org/&quot;&gt;Boxedwine&lt;/a&gt; - An emulator that runs Windows applications using Wine and emulating a Linux kernel and CPU (&lt;a href=&quot;https://github.com/danoon2/Boxedwine&quot;&gt;Source&lt;/a&gt;)&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Bare CPUs&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.xlnsresearch.com/scelbal.htm&quot;&gt;8008 running SCELBAL&lt;/a&gt; by Mark G. Arnold. (&quot;SCELBAL is the only open-source, floating-point, high-level language ever implemented on the 8008&quot;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://typedarray.org/wp-content/projects/Intel8080/index.html&quot;&gt;8080 CPU emulator&lt;/a&gt; - Intel 8080 CPU emulator running Space Invaders ROM (&lt;a href=&quot;https://github.com/thibaultimbert/Intel8080&quot;&gt;Source&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://wokwi.com/arduino/projects/297787059514376717&quot;&gt;AVR8js&lt;/a&gt; - AVR architecture emulator, capable of running Arduino code (&lt;a href=&quot;https://github.com/wokwi/avr8js&quot;&gt;source&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://em.ulat.es/machines/TaitoSpaceInvaders&quot;&gt;EMF Arcade Invaders&lt;/a&gt; - EMF-based 8080 Emulator with Space Invaders ROM - by Steven Goodwin (@MarquisdeGeek) (&lt;a href=&quot;https://github.com/MarquisdeGeek/emf-emulator-arcade_invaders&quot;&gt;Source&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.netpipe.ca/apps/8086tiny/8086tiny.html&quot;&gt;8086tiny running FreeDOS&lt;/a&gt; - An Emscriptem port of Adrian Cable&apos;s 8086tiny. Source, and other emulators ported by Clay Shippy, at &lt;a href=&quot;emscripten-projects&quot;&gt;https://github.com/tecan/emscripten-projects&lt;/a&gt;.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/riscv/riscv-angel&quot;&gt;Angel&lt;/a&gt; - JavaScript RISC-V ISA simulator booting Linux in a web-browser&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/JeremyLikness/6502emulator#readme&quot;&gt;Angular 2 6502&lt;/a&gt; written with TypeScript and Angular 2, by Jeremy Likness&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://biged.github.io/arm-js/arm-js.html&quot;&gt;ARM-js&lt;/a&gt; - An ARM emulator written in JavaScript (&lt;a href=&quot;https://github.com/ozaki-r/arm-js&quot;&gt;Source&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.asm80.com&quot;&gt;ASM80&lt;/a&gt; - Online assembler for 8-bit microprocessors by Martin Malý. Includes emulation of several machines: 8080, Z80, 6502, 6809. (&lt;a href=&quot;https://github.com/maly&quot;&gt;Sources&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;Basic MIPS functional simulator by Mianzhi Wang (morriswmz). (&lt;a href=&quot;https://github.com/morriswmz/SimpleMIPS.js&quot;&gt;Source&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://skilldrick.github.io/easy6502/&quot;&gt;Easy6502&lt;/a&gt; - JavaScript 6502 tutorial and emulator (&lt;a href=&quot;https://github.com/skilldrick/easy6502&quot;&gt;Source&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://web.edumips.org/&quot;&gt;EduMIPS64&lt;/a&gt; - &lt;a href=&quot;https://www.edumips.org/&quot;&gt;Educational MIPS64 CPU&lt;/a&gt;, ported from Java by Andrea Spadaccini using GWT (see blog &lt;a href=&quot;http://edumips64.blogspot.com/2016/06/towards-javascript-port-of-edumips64.html&quot;&gt;here&lt;/a&gt;.) (&lt;a href=&quot;https://github.com/lupino3/edumips64&quot;&gt;Source&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://ivanzuzak.info/FRISCjs/webapp/&quot;&gt;FRISCjs&lt;/a&gt; - an 8-register educational RISC from the University of Zagreb, with both assembler and front panel, by Ivan Žužak. &lt;a href=&quot;https://github.com/izuzak/FRISCjs&quot;&gt;Source&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.mdawson.net/asm6502/6502asm.php&quot;&gt;Imaginary 6502&lt;/a&gt; - 6502 Emulator and Assembler&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://e4004.szyc.org/&quot;&gt;Intel 4004 emulator&lt;/a&gt; - by Maciej Szyc. Includes assembler and disassembler.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.tramm.li/i8080/&quot;&gt;Intel 8080 CPU Emulator&lt;/a&gt; - Emulates a minimal Intel 8080 Microcomputer that runs CP/M&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://polysoftit.co.uk/irisc-web/&quot;&gt;iRISC&lt;/a&gt; - Interactive ARMv7 assembly language interpreter and computer architecture simulator (&lt;a href=&quot;https://github.com/rtybanana/irisc-web/&quot;&gt;Source&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://bluishcoder.co.nz/js8080/&quot;&gt;JavaScript 8080 Emulator&lt;/a&gt; - 8080 arcade game emulator in JavaScript&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://blog.loadzero.com/demo/mipsdis/demo.html&quot;&gt;Mipsdis&lt;/a&gt; - MIPS disassembler that runs in the browser&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.enscope.nl/rrca/&quot;&gt;RISC Relay Computer&lt;/a&gt; - Relay based computer project with a 16 bit RISC CPU. Emulator includes an assembler and source for a calculator program. By RJH. See &lt;a href=&quot;http://www.enscope.nl/rrc&quot;&gt;website&lt;/a&gt;.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://bellard.org/riscvemu/js/&quot;&gt;RISCVEMU&lt;/a&gt; - RISC-V emulator boots 64-bit Linux. By Fabrice Bellard.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://wokwi.com/arduino/projects/297323005822894602&quot;&gt;RP2040js&lt;/a&gt; - Raspberry Pi Pico (RP2040 / Arm Cortex-M0+) emulator with C/C++/MicroPython/CircuitPython support (&lt;a href=&quot;https://github.com/wokwi/rp2040js&quot;&gt;Source&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://schweigi.github.io/assembler-simulator/&quot;&gt;Simple 8-bit Assembler Simulator&lt;/a&gt; - Provides a simplified assembler syntax (based on NASM) and is simulating a x86 like CPU (&lt;a href=&quot;https://github.com/Schweigi/assembler-simulator&quot;&gt;Source&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;uARM.wasm - ARMv5TE emulator running Linux in browsers (&lt;a href=&quot;https://github.com/TonyLianLong/uARM.wasm&quot;&gt;Source&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://alexaltea.github.io/unicorn.js/&quot;&gt;Unicorn.js&lt;/a&gt; - The Unicorn emulator framework, now available for JavaScript (&lt;a href=&quot;https://github.com/AlexAltea/unicorn.js&quot;&gt;Source&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://visual6502.org/sim/varm/armgl.html&quot;&gt;Visual ARM1&lt;/a&gt; - JavaScript/WebGL for ARM&apos;s first CPU, modelling 25000 transistors at switch level and animating the original chip layout - in 3D. See &lt;a href=&quot;http://blog.visual6502.org/2015/11/the-visual-arm1.html&quot;&gt;the blog post&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.visual6502.org/JSSim/&quot;&gt;Visual 6502&lt;/a&gt; - JavaScript simulator for the 6502 CPU, modelling thousands of transistors at switch level and animating the original chip layout. See also &lt;a href=&quot;http://www.visual6502.org/JSSim/expert.html?steps=10&quot;&gt;expert mode&lt;/a&gt;.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.visual6502.org/JSSim/expert-6800.html?steps=10&quot;&gt;Visual 6800&lt;/a&gt; - JavaScript simulator for the Motorola 6800 CPU, modelling thousands of transistors at switch level and animating the original chip layout.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.visual6502.org/JSSim/expert-z80.html&quot;&gt;Visual Z80&lt;/a&gt; - JavaScript simulator for the Z80 CPU, modelling thousands of transistors at switch level and animating the original chip layout.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://thlorenz.com/visulator/&quot;&gt;Visulator&lt;/a&gt; - x86 machine emulator that visualizes how each instruction is processed (&lt;a href=&quot;https://github.com/thlorenz/visulator&quot;&gt;Source&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://yamd.xuanji.li&quot;&gt;YAMD&lt;/a&gt; - Yet Another MIPS Debugger (&lt;a href=&quot;https://github.com/zodiac/yamd&quot;&gt;Source&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://s-macke.github.io/jor1k/&quot;&gt;jor1k&lt;/a&gt; - OpenRISC OR1K JavaScript emulator running Linux with network support (&lt;a href=&quot;https://github.com/s-macke/jor1k/&quot;&gt;Source&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.ubercomp.com/jslm32/src/&quot;&gt;jslm32&lt;/a&gt; - JavaScript LatticeMico32 emulator running Linux (&lt;a href=&quot;https://github.com/ubercomp/jslm32/&quot;&gt;Source&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.nablaman.com/relay/sim/zusie.html&quot;&gt;ZUSIE&lt;/a&gt; - JavaScript simulation of &lt;a href=&quot;http://www.nablaman.com/relay/&quot;&gt;Fredrik Andersson&apos;s homebrew relay machine&lt;/a&gt; inspired by Zuse&apos;s machines.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Early machines&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;http://ed-thelen.org/bab/bab-diff-JavaScript.html&quot;&gt;Babbage&apos;s Difference Engine&lt;/a&gt; (First funded 1823, first full build in 1855, first full rebuild in 1991)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.fourmilab.ch/babbage/aem/&quot;&gt;Babbage&apos;s Analytical Engine&lt;/a&gt; in JavaScript, by John Walker. (First described 1837, never completed, not yet rebuilt.) (&lt;a href=&quot;https://www.fourmilab.ch/babbage/emulator.html&quot;&gt;Documentation&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://rendell-attic.org/gol/TMapplet/index.htm&quot;&gt;Turing machine&lt;/a&gt; simulated in JavaScript. See &lt;a href=&quot;http://rendell-attic.org/gol/utm/&quot;&gt;here&lt;/a&gt; for more information. (1936)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://zuse-z1.zib.de/simulations/z1/adders/wgl/&quot;&gt;Z1 machine&apos;s adder in 3D&lt;/a&gt; JavaScript/WebGL interactive simulation of the mechanical adder of Zuse&apos;s first machine. By Jakob Mischek (&lt;a href=&quot;https://github.com/daign/zuse-z1.js&quot;&gt;Source&lt;/a&gt;) (1938)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://gymoberwil.educanet2.ch/a.hu/projektarbeit/zuse/addition/addition.htm&quot;&gt;Z3 machine&apos;s adder&lt;/a&gt; - ripple-carry electromechanical adder simulated in JavaScript, by Henry Raymond, Patrick Seewald and Vijeinath Tissaveerasingham. &lt;a href=&quot;http://gymoberwil.educanet2.ch/a.hu/projektarbeit/zuse/simu.htm&quot;&gt;Explanation&lt;/a&gt; (1941)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://edmundgriffiths.com/jsssem.html&quot;&gt;JsSSEM&lt;/a&gt; - Manchester Small-Scale Experimental Machine emulator (Also check &lt;a href=&quot;http://www.edmundgriffiths.com/czero.html&quot;&gt;Computer/zero&lt;/a&gt; which is very loosely based on the SSEM, and its &lt;a href=&quot;http://www.edmundgriffiths.com/degreezero.html&quot;&gt;tutorial&lt;/a&gt;) (1948)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://danieljabailey.github.io/c88-js/&quot;&gt;C88&lt;/a&gt; - C88 computer simulation (&lt;a href=&quot;http://bitofahack.com/post/1434913931&quot;&gt;The Homebrew CPU inspired by the SSEM&lt;/a&gt;) (1948)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://nhiro.org/learn_language/repos/EDSAC-on-browser/index.html&quot;&gt;EDSAC on Browser&lt;/a&gt; - by NISHIO Hirokazu (&lt;a href=&quot;https://www.dcs.warwick.ac.uk/~edsac/Software/EdsacTG.pdf&quot;&gt;Programming guide&lt;/a&gt;) (1949)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://em.ulat.es/machines/Elliott903&quot;&gt;EMF Elliott&lt;/a&gt; - EMF-based Elliott Emulator - by Steven Goodwin (@MarquisdeGeek) (&lt;a href=&quot;https://github.com/MarquisdeGeek/emf-emulator-elliott-903&quot;&gt;Source&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;WITCH Emulator - The Harwell Dekatron Machine, by Justin King. (&lt;a href=&quot;https://github.com/jsking/witch-e&quot;&gt;Source and example programs&lt;/a&gt;) (1951)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.masswerk.at/virtualunivac/&quot;&gt;UNIVAC I emulator&lt;/a&gt; - JavaScript emulator by Norbert Landsteiner (1951)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.phkimpel.us/ElectroData-205/webUI/D205.html&quot;&gt;ElectroData/Burroughs Datatron 205 Emulator&lt;/a&gt; - by Paul Kimpel (&lt;a href=&quot;https://github.com/pkimpel/retro-205&quot;&gt;Source&lt;/a&gt;) (1954)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.wizforest.com/tech/tx-0/#&quot;&gt;TX-0&lt;/a&gt; emulator by @wizforest, including several programs from the time. (&lt;a href=&quot;https://www.wizforest.com/tech/tx-0/manual.html&quot;&gt;Instructions&lt;/a&gt;) (1956)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://members.aon.at/nkehrer/mailuefterl/mailuefterl.html&quot;&gt;Mailüfterl&lt;/a&gt; - JavaScript emulator by Norbert Kehrer (1958)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://trinary.ru/projects/setunws/&quot;&gt;Setun (Russian)&lt;/a&gt; and &lt;a href=&quot;https://web.archive.org/web/20170114102246/http://en.trinary.ru/projects/setunws/&quot;&gt;English (archived)&lt;/a&gt; - JavaScript emulator by Обухов Александр. Ternary machine from Soviet Union (1958)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://digicomp-1.appspot.com&quot;&gt;Digi-Comp 1&lt;/a&gt; (&lt;a href=&quot;https://web.archive.org/web/20140222193139/http://www.scoopsfolks.com/digicomp1&quot;&gt;previously&lt;/a&gt;) - educational sliding-rods plastic computer. Emulator by Larry Groebe and Kevin Williams. (1963)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://museum.syssrc.com/joda/&quot;&gt;Digi-Comp II&lt;/a&gt; - educational falling-marbles computer. Emulator by Joda Redfearn. (1965)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://retro-b5500.blogspot.com&quot;&gt;Burroughs B5500 emulator&lt;/a&gt; - Burroughs B5500 emulator in JavaScript (&lt;a href=&quot;https://github.com/pkimpel/retro-b5500&quot;&gt;Source&lt;/a&gt;) (1964)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://svtsim.com/moonjs/agc.html&quot;&gt;Apollo Guidance Computer&lt;/a&gt; - Moonjs a port by Shahriar Iravanian of Ronald Burkey&apos;s Virtual AGC. (1966)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.mailcom.com/besm6/runitnew.cgi&quot;&gt;BESM-6&lt;/a&gt; - with examples in Algol, Fortran, and assembler. By Leonid A. Broukhis and Michael Yaroslavtsev. More &lt;a href=&quot;http://www.mailcom.com/besm6/&quot;&gt;here&lt;/a&gt;. (1968)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.cs.drexel.edu/~bls96/museum/cardsim.html&quot;&gt;CARDIAC&lt;/a&gt; - Bell Labs&apos; CARDIAC cardboard computer from 1969. &lt;a href=&quot;https://www.cs.drexel.edu/~bls96/museum/cardiac.html&quot;&gt;Instructions&lt;/a&gt; (1969)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.neocomputer.org/kenbak/kenbak1-JS.html&quot;&gt;Kenbak-1&lt;/a&gt; - John Blankenbaker&apos;s TTL-based 256byte personal computer. &lt;a href=&quot;http://www.neocomputer.org/kenbak/&quot;&gt;More information&lt;/a&gt; (1970)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://nguyen.univ-tln.fr/share/Archi/ordinapoche.html&quot;&gt;Ordinapoche&lt;/a&gt; - A paper computer from France, invented 1969, popularised in 1981 and 1985. (&lt;a href=&quot;http://nguyen.univ-tln.fr/ordinapoche.html&quot;&gt;More here&lt;/a&gt; and &lt;a href=&quot;https://www.abandonware-magazines.org/affiche_mag.php?mag=85&amp;amp;num=3809&amp;amp;album=oui&quot;&gt;see also the 1981 magazine&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.aconit.org/histoire/Gamma-3/Simulateur/&quot;&gt;BullGammaTor&lt;/a&gt; - A JavaScript emulator for the Bull Gamma 3 ET computer (&lt;a href=&quot;https://github.com/lutrampal/bullgammator/&quot;&gt;Source&lt;/a&gt;) (1952)&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Calculator emulators&lt;/h2&gt; 
&lt;h3&gt;Microcode-level calculators&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.sydneysmith.com/products/hp21u/run/index.html&quot;&gt;HP21u&lt;/a&gt;, &lt;a href=&quot;https://www.sydneysmith.com/products/hp25u/run/index.html&quot;&gt;HP25u&lt;/a&gt;, and &lt;a href=&quot;https://www.sydneysmith.com/products/hp29u/run/index.html&quot;&gt;HP29u&lt;/a&gt; - by Greg Sydney-Smith&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://ashleyf.github.io/HP35/&quot;&gt;HP-35&lt;/a&gt; - bug-compatible emulator by Ashley Feniello &lt;a href=&quot;https://blogs.msdn.microsoft.com/ashleyf/2010/09/25/microcode-level-hp-35-emulator-in-javascript/&quot;&gt;explained here&lt;/a&gt; using &lt;a href=&quot;https://nonpareil.brouhaha.com/&quot;&gt;Eric Smith&lt;/a&gt;&apos;s and &lt;a href=&quot;https://web.archive.org/web/20210601085601/http://home.citycable.ch/pierrefleur/Jacques-Laporte/&quot;&gt;Jacques Laporte&lt;/a&gt;&apos;s work&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://torotrak.wordpress.com/hp-classic/&quot;&gt;HP-35, HP-45, HP-55, HP-65, HP-80&lt;/a&gt; - collection of HP Classics, based on Feniello&apos;s work, by Francois Roulet&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://members.aon.at/nkehrer/hp45_js/hp45.html&quot;&gt;HP-45&lt;/a&gt; - statically recompiled ROM by Norbert Kehrer&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://jadegame.com/jsemu48/&quot;&gt;jsEmu48&lt;/a&gt; - emscripten port by Julien Meyer of HP EMU By Daniel Nilsson. (&lt;a href=&quot;https://github.com/brizzly/jsEmu48&quot;&gt;Source&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.sydneysmith.com/products/hp55u/run/&quot;&gt;HP-55&lt;/a&gt;, &lt;a href=&quot;https://www.sydneysmith.com/wordpress/hp65/&quot;&gt;HP-65&lt;/a&gt; and &lt;a href=&quot;https://www.sydneysmith.com/wordpress/1178/hp67-microcode-emulator/&quot;&gt;HP-67&lt;/a&gt; - with extra debug menu, by Greg Sydney-Smith&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://mk-61.moy.su/emulator.html&quot;&gt;мк-61&lt;/a&gt; - Elektronika&apos;s programmable calculators MK-61, Б3-34, МК-54, and МК-56, also the Феликс-М (Felix M) arithmometer, a slide rule and an abacus. By Felix Lazarev, Andrey_emu, Sergey Tarasov and others.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://files.righto.com/sinclair&quot;&gt;Sinclair Scientific&lt;/a&gt; and &lt;a href=&quot;https://files.righto.com/ti&quot;&gt;TI-1500&lt;/a&gt; - calculator simulations including full description of the algorithms and the reverse-engineering process. By Ken Shirriff. Further work by Phil Mainwaring shows &lt;a href=&quot;http://phils-place.co.uk/calculators/?calc=sc&quot;&gt;Sinclair Cambridge&lt;/a&gt;, &lt;a href=&quot;http://phils-place.co.uk/calculators/?calc=ti&quot;&gt;TI-1500&lt;/a&gt; and &lt;a href=&quot;http://phils-place.co.uk/calculators/?calc=sc&quot;&gt;Sinclair Scientific&lt;/a&gt;, each using different customisations of TI&apos;s 080x chip.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.pcjs.org/devices/ti42/machine/&quot;&gt;TI-42 &quot;MBA&quot; Programmable Calculator&lt;/a&gt; by Jeff Parsons (PCjs)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.pcjs.org/devices/ti55/&quot;&gt;TI-55&lt;/a&gt; by Jeff Parsons (PCjs)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.pcjs.org/devices/ti57/machine/&quot;&gt;TI-57 Programmable Calculator&lt;/a&gt; by Jeff Parsons (PCjs)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.ocf.berkeley.edu/~pad/emu/v11.html&quot;&gt;TI-92 Plus emulator&lt;/a&gt; - JavaScript emulator for the TI-92 Plus&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://tiplanet.org/emu68k_fork/&quot;&gt;JavaScript TI-89 / TI-92+ / TI-V200 / TI-89T emulator&lt;/a&gt; - by Patrick Davidson and Lionel Debroux&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Workalike calculators&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://stendec.io/ctb/hp11c.html&quot;&gt;HP-11C&lt;/a&gt;, &lt;a href=&quot;https://stendec.io/ctb/hp12c-platinum.html&quot;&gt;HP-12C Platinum&lt;/a&gt;, &lt;a href=&quot;https://stendec.io/ctb/hp16c.html&quot;&gt;HP-16C&lt;/a&gt; - by Elvis Pfützenreuter&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://jrpn.jovial.com/&quot;&gt;HP-16C (Jovial RPN)&lt;/a&gt; - by Bill Foote&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://hp15c.com/web/hp15c.html&quot;&gt;HP-15C&lt;/a&gt; - by Greg Hewgill. (&lt;a href=&quot;https://github.com/ghewgill/hp15c&quot;&gt;Source&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.sydneysmith.com/products/gss-hp21/run/index.html#&quot;&gt;HP-21&lt;/a&gt; and &lt;a href=&quot;http://www.sydneysmith.com/products/gss-hp29/run/index.html#&quot;&gt;HP-29&lt;/a&gt; by Greg Sydney-Smith (See &lt;a href=&quot;http://www.sydneysmith.com/wordpress/hp21/&quot;&gt;here&lt;/a&gt; and &lt;a href=&quot;http://www.sydneysmith.com/wordpress/hp29/&quot;&gt;here&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.jcczone.net/hp-25.html&quot;&gt;HP-25&lt;/a&gt; - by John Clenance&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://neil.fraser.name/software/hp-35/&quot;&gt;HP-35&lt;/a&gt; - JavaScript emulator by Neil Fraser&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://hansklav.home.xs4all.nl/rpn/hp35sos.html&quot;&gt;HP-35 SOS&lt;/a&gt; - modified HP-35 with stack overflow sensing LED, by Hans Klaver, based on Fraser&apos;s work&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.poleyland.com/hp48/index.html&quot;&gt;HP-48&lt;/a&gt; - JavaScript implementation of the most commonly used HP-48 functions. More info &lt;a href=&quot;http://www.poleyland.com/hp48/help.html&quot;&gt;here&lt;/a&gt;, by Josh Poley&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://biged.github.io/P101/p101viewport.html&quot;&gt;Olivetti Programma 101&lt;/a&gt; - JavaScript emulation of the first commercial programmable desktop computer, by &quot;Fabioamd87&quot;. &lt;a href=&quot;https://github.com/Fabioamd87/P101&quot;&gt;Source on GitHub&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.caffnib.co.uk/calculators/sinclair_prog.html&quot;&gt;Sinclair Cambridge Programmable&lt;/a&gt; by Nigel Bromley. (Source &lt;a href=&quot;http://www.caffnib.co.uk/calculators/sinclair_prog.js&quot;&gt;here&lt;/a&gt;.)&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Miscellaneous&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.pcjs.org/docs/c1pjs/&quot;&gt;C1Pjs&lt;/a&gt; - JavaScript simulation of the Challenger 1P (PCjs)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://archive.org/details/canoncat&quot;&gt;Canon Cat (in JSMess)&lt;/a&gt; - Jef Raskin&apos;s Forth-capable 68000-based word processor. (&lt;a href=&quot;https://github.com/mamedev/mame/blob/master/src/mame/drivers/cat.cpp#L16&quot;&gt;Instructions&lt;/a&gt; and &lt;a href=&quot;http://www.canoncat.net/&quot;&gt;more info&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.bedroomlan.org/hardware/cft/microcode-emulator&quot;&gt;CFT&lt;/a&gt; - JavaScript simulation of Alexios Chouchoulas&apos; 16-bit homebrew TTL machine. (&lt;a href=&quot;https://www.bedroomlan.org/hardware/cft/&quot;&gt;More information&lt;/a&gt; including documentation and a video.)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://biged.github.io/Chip-8-Emulator/&quot;&gt;Chip-8 virtual machine&lt;/a&gt; by Alexander Dickson - see &lt;a href=&quot;http://blog.alexanderdickson.com/javascript-chip-8-emulator&quot;&gt;blog entry&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://pachisystems.com/JSEmu/chip8.html&quot;&gt;Chip-8 virtual machine&lt;/a&gt; by Brian Milton (&lt;a href=&quot;https://github.com/PachiSystems/JSEmu&quot;&gt;Source&lt;/a&gt; may target several CPUs)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://xem.github.io/chip8/&quot;&gt;Chip8 1k&lt;/a&gt; - a code-golfed chip 8 emulator in 1k by Maxime Euzière and others&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://em.ulat.es/machines/Chip8&quot;&gt;EMF Chip 8&lt;/a&gt; - EMF-based Elliott Emulator - by Steven Goodwin (@MarquisdeGeek) (&lt;a href=&quot;https://github.com/MarquisdeGeek/emf-emulator-chip-8&quot;&gt;Source&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://em.ulat.es/machines/Megaprocessor&quot;&gt;EMF Megaprocessor&lt;/a&gt; - EMF-based Megaprocessor Emulator - by Steven Goodwin (@MarquisdeGeek) of the room-sized machine built by James Newman and housed in the Museum of Computing History, in Cambridge, England. (&lt;a href=&quot;https://github.com/MarquisdeGeek/emf-emulator-megaprocessor&quot;&gt;Source&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/doodlewind/merry8&quot;&gt;Merry8&lt;/a&gt; - JavaScript Chip-8 emulator by Yifeng Wang&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://compucolor.org/emu/ccemu.html&quot;&gt;Compucolor II Emulator&lt;/a&gt; - JavaScript Compucolor II Emulator&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.avoncliff.com/uk101/&quot;&gt;Compukit UK101&lt;/a&gt; - by David Stevenson&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://archives.loomcom.com/contraltojs/&quot;&gt;ContrAltoJS&lt;/a&gt; - Pure JavaScript implementation of the ContrAlto Xerox Alto emulator (&lt;a href=&quot;https://github.com/sethm/ContrAltoJS&quot;&gt;Source&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.donnelly-house.net/programming/cdp1802/simelf/&quot;&gt;COSMAC Elf-ish&lt;/a&gt; - simulator by William Donnelly&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://dcmo5.free.fr/online/&quot;&gt;DCMO5 Online&lt;/a&gt; - Thomson MO5 JavaScript emulator&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://play.dodolabs.io/?code=51447f62&quot;&gt;Dodo Playground&lt;/a&gt; - IDE and simulator for 6502-based Dodo homebrew game system by Peter Noyes&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://em.ulat.es/machines/Dragon32&quot;&gt;EMF Dragon&lt;/a&gt; - EMF-based Dragon Emulator - by Steven Goodwin (@MarquisdeGeek)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://em.ulat.es/machines/JupiterAce&quot;&gt;EMF Jupiter Ace&lt;/a&gt; - EMF-based ZX80 Emulator - by Steven Goodwin (@MarquisdeGeek) (&lt;a href=&quot;https://github.com/MarquisdeGeek/emf-emulator-jupiter-ace&quot;&gt;Source&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://ep.lgb.hu/jsep/demo/?autostart=yes&quot;&gt;Enterprise-128 JavaScript Emulator&lt;/a&gt; - by Gábor Lénárt &quot;LGB&quot;, based on JSSpeccy&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://corax89.github.io/esp8266Game/index.html&quot;&gt;ESP8266 Game Engine&lt;/a&gt; - a console-game-oriented virtual machine running on ESP8266, by Corax. (&lt;a href=&quot;https://github.com/corax89/esp8266_game_engine&quot;&gt;Source&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://gigatron.io/emu/&quot;&gt;Gigatron&lt;/a&gt; - emulator of the present-day TTL console computer with Tiny Basic and games. Also Wozmon on a nested emulation of 6502. (&lt;a href=&quot;https://gigatron.io/&quot;&gt;Website&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://diversen.github.io/hack-emulator-js/&quot;&gt;Hack&lt;/a&gt; - emulator of the computer from &lt;a href=&quot;https://nand2tetris.org&quot;&gt;nand2tetris&lt;/a&gt;, by diversen. (&lt;a href=&quot;https://github.com/diversen/hack-emulator-js&quot;&gt;Source&lt;/a&gt;.)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://phils-place.co.uk/demos/et3400/&quot;&gt;Heathkit ET3400&lt;/a&gt; - by Phil Mainwaring. Click &quot;Do&quot; then &quot;0000&quot;. (&lt;a href=&quot;http://phils-place.co.uk/demos/et3400/heathkit_3400_trainer_manual_pages_46_to_104_edit_1.txt&quot;&gt;Instructions&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://norbertkehrer.github.io/ibm_5110/emu5110.html&quot;&gt;IBM 5110 Emulator&lt;/a&gt; by Norbert Kehrer runs Basic or APL.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://js99er.net/&quot;&gt;JS99&apos;er&lt;/a&gt; - TI-99/4A emulator written in JavaScript (&lt;a href=&quot;https://github.com/Rasmus-M/Js99er&quot;&gt;Source&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://heathkit.garlanger.com/emulator/jsH89/&quot;&gt;jsH89&lt;/a&gt; - Heathkit H89 emulator (runs CP/M) by Mark Garlanger&lt;/li&gt; 
 &lt;li&gt;JSGS - Experimental JavaScript implementation of the Pico-8 fantasy console (&lt;a href=&quot;https://github.com/burakcan/jsgs&quot;&gt;Source&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://jsmsx.sourceforge.net/&quot;&gt;jsMSX&lt;/a&gt; - The first MSX emulator 100% written in JavaScript&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://jspspemu.com&quot;&gt;JsPspEmu&lt;/a&gt; - JavaScript PSP emulator (&lt;a href=&quot;https://github.com/jspspemu/jspspemu&quot;&gt;Source&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.twitchasylum.com/jsvecx/&quot;&gt;JSVecX&lt;/a&gt; - JavaScript port of the VecX Vectrex emulator&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://jupiler.zxtres.com&quot;&gt;jupiler&lt;/a&gt; - Jupiter Ace emulator written in JavaScript (&lt;a href=&quot;https://sourceforge.net/p/emuscriptoria/code/HEAD/tree/jupiler.js&quot;&gt;Source&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://hp.vector.co.jp/authors/VA016157/kmz80web10/kmz80web.html&quot;&gt;KM-Z80 web&lt;/a&gt; emulator for Sharp MZ-80K, by Katsumi Morimatsu. GOTO $1200 to start KM-BASIC. (&lt;a href=&quot;http://hp.vector.co.jp/authors/VA016157/kmz80web10/&quot;&gt;More information&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://nippur72.github.io/laser500emu/&quot;&gt;laser500emu&lt;/a&gt; emulator for Video Technology (VTech) Laser 350/500/700, by Antonino Porcino.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://matt.krutar.org/LMC4/&quot;&gt;Little Man Computer&lt;/a&gt; a minimal CPU for teaching - emulator by Matthew Krutar. (&lt;a href=&quot;https://en.wikipedia.org/wiki/Little_man_computer&quot;&gt;Background&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://blog.paulhankin.net/lmc/lmc.html&quot;&gt;Little Man Computer&lt;/a&gt; a minimal CPU for teaching - emulator by Paul Hankin. (&lt;a href=&quot;https://en.wikipedia.org/wiki/Little_man_computer&quot;&gt;Background&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://peterhigginson.co.uk/LMC/&quot;&gt;Little Man Computer&lt;/a&gt; a minimal CPU for teaching - emulator by Peter Higginson. (&lt;a href=&quot;https://en.wikipedia.org/wiki/Little_man_computer&quot;&gt;Background&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://js1k.com/2010-first/details/455&quot;&gt;Machine in a machine&lt;/a&gt; - Turing Machine Implementation in 1k from the &lt;a href=&quot;https://js1k.com/&quot;&gt;JS1k competition&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://js1k.com/2016-elemental/details/2415&quot;&gt;Marmmodore-1K&lt;/a&gt; - minimal 8-bit computer in 1k by Felipe Alfonso&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://nanowasp.org&quot;&gt;NanoWasp&lt;/a&gt; - A MicroBee emulator&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://thorn.ws/jsnascom/jsnascom.html&quot;&gt;Nascom 2 emulator&lt;/a&gt; by Tommy Thorn. (J to start Basic) (&lt;a href=&quot;https://github.com/tommythorn/jsnascom&quot;&gt;Source&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.cs.drexel.edu/~bls96/oisc/OISC.html&quot;&gt;One Instruction Set Computer (OISC)&lt;/a&gt; by Peter Crampton, presented by Brian L. Stuart. (&lt;a href=&quot;https://www.cs.drexel.edu/~bls96/oisc/&quot;&gt;Explanation&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://orao.hrvoje.org/&quot;&gt;Orao&lt;/a&gt; - Orao emulator by Hrvoje Cavrak (&lt;a href=&quot;https://github.com/hrvach/OraoJs&quot;&gt;More information&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://torguet.net/oric/Oricutron.html&quot;&gt;Oricutron&lt;/a&gt; - An emulator for the ORIC series of home computers, by Peter Gordon (&lt;a href=&quot;https://github.com/pete-gordon/oricutron&quot;&gt;Source&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;PC-01 Lviv - An emulator for the PC-01 Lviv (Ukrainian home computer) (&lt;a href=&quot;https://github.com/dolgarev/emulator-pc01-lviv&quot;&gt;Source&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.peterhigginson.co.uk/RISC/&quot;&gt;RISC Simulator&lt;/a&gt; - RISC Simulator with Fetch/Execute and register based CPU model, by Peter Higginson&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://pebble.github.io/rockyjs/&quot;&gt;RockyJS&lt;/a&gt; - Pebble watch interpreter/emulator&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://rk86.ru&quot;&gt;Radio-86RK&lt;/a&gt; Radio-86RK emulator in JavaScript (Intel 8080 based 8-bit Russian home computer) (&lt;a href=&quot;https://github.com/begoon/rk86-js&quot;&gt;Source&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.edmundgriffiths.com/setunka.html&quot;&gt;Setunka&lt;/a&gt; - Ternary computing for the browser&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://ellisgl.github.io/SAP-1-CPU/&quot;&gt;SAP-1&lt;/a&gt; JavaScript emulation of the Simple As Possible TTL machine from Malvino&apos;s book, Digital Computer Electronics. By Kenneth Ellis McCall. (&lt;a href=&quot;https://github.com/ellisgl/SAP-1-CPU&quot;&gt;Source&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.tejotron.com/&quot;&gt;Tejotron&lt;/a&gt; - Virtual breadboard, inspired by Ben Eater&apos;s 6502 computer&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/lkesteloot/turbopascal&quot;&gt;Turbo Pascal&lt;/a&gt; - A web-based Pascal compiler that runs a subset of Turbo Pascal 5.5 code&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://sensi.org/scalar/ware/468/&quot;&gt;Vector06js&lt;/a&gt; - Vector-06C (AKA Вектор-06Ц) JavaScript emulator by Viacheslav Slavinsky. Also runnable &lt;a href=&quot;https://svofski.github.io/vector06js/&quot;&gt;here&lt;/a&gt;. (&lt;a href=&quot;https://github.com/svofski/vector06js&quot;&gt;Source&lt;/a&gt;.)&lt;/li&gt; 
 &lt;li&gt;Virt.js - JavaScript emulation library (&lt;a href=&quot;https://github.com/arcanis/virtjs&quot;&gt;Source&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www1.idc.ac.il/vic/software/computer/&quot;&gt;Visual Computer&lt;/a&gt; a minimal CPU for teaching by Shimon Schocken. (&lt;a href=&quot;https://sites.google.com/site/schocken/thevisualcomputer&quot;&gt;Web site&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://webmsx.org/&quot;&gt;WebMSX&lt;/a&gt; - WebMSX, or simply WMSX, is a new MSX emulator designed for the Web (&lt;a href=&quot;https://github.com/ppeccin/webmsx&quot;&gt;Source&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://dested.com/projects/wire/&quot;&gt;Wireworld computer&lt;/a&gt; - JavaScript port by Salvatore Aiello of the prime-generating computer implemented in the Wireworld cellular automaton, as described &lt;a href=&quot;https://www.quinapalus.com/wi-index.html&quot;&gt;here&lt;/a&gt;.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/neophob/wpc-emu&quot;&gt;WPCEmu&lt;/a&gt; - Williams Pinball Emulator by Michael Vogt&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Adventure Game Engines&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/juj/emscripten-scummvm&quot;&gt;Emscripten ScummVM&lt;/a&gt; - Emscripten fork of the ScummVM engine&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/curiousdannii/ifvms.js&quot;&gt;IFVMS&lt;/a&gt; - Infocom/Inform Web interpreter&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/curiousdannii/parchment&quot;&gt;Parchment&lt;/a&gt; - Infocom/Inform Web interpreter&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/bstreiff/zztjs&quot;&gt;ZZTJS&lt;/a&gt; - ZZT game engine in JavaScript&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/Utodev/ngPAWS&quot;&gt;ngPAWS&lt;/a&gt; - Professional Adventure Writer (PAW) Web interpreter&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;See also (lists of JavaScript emulators elsewhere)&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://archive.vg/blog/a-big-list-of-browser-based-emulators-and-ports-of-classic-games&quot;&gt;A Big List of Browser-Based Emulators&lt;/a&gt; by Richard Moss&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://torinak.com/qaop/links&quot;&gt;Qaop/JS – Emulator links&lt;/a&gt; by Jan Bobrowski&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Java Virtual Machine (JVM)</title>
      <link>https://tedneward.github.io/Research/vms/jvm/index/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">vms/jvm/index/index.html</guid>
      	<description>
	&lt;p&gt;Bytecode interpreted. JIT compiled (depending on implementation). Dynamic code loaded.&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Java_virtual_machine&quot;&gt;Wikipedia&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;/platforms/jvm/specifications&quot;&gt;JVM Specifications&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://github.com/jtransc/jtransc&quot;&gt;JVM conversion&lt;/a&gt;: Bytecode to source converting Java &amp;amp; Kotlin code into JavaScript, C++, D, C#, PHP, AS3, Dart and Haxe and run it everywhere. Also use JVM code in your favourite language as a library. &lt;a href=&quot;https://jtransc.soywiz.com/&quot;&gt;Website&lt;/a&gt;&lt;/p&gt; 
&lt;h2&gt;Articles&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.kdgregory.com/index.php?page=java.refobj&quot;&gt;Java Reference Objects&lt;/a&gt;: One of the best articles on the Java &quot;Reference&quot; types (SoftReference, WeakReference, PhantomReference, ReferenceQueue) that I&apos;ve ever read&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;/reading/memory-management&quot;&gt;General memory mgmt/GC reading and links&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://inside.java/&quot;&gt;Inside Java&lt;/a&gt;: News and views from members of the Java team at Oracle 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://inside.java/sip/&quot;&gt;Sip of Java&lt;/a&gt;: Short takes on interesting Java ideas&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://openjdk.org/projects/babylon/articles/linq&quot;&gt;Emulating C# LINQ using Code Reflection&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Implementations:&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;/vms/jvm/openjdk&quot;&gt;OpenJDK&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.eclipse.org/openj9/&quot;&gt;OpenJ9&lt;/a&gt; (&lt;a href=&quot;https://github.com/eclipse/openj9&quot;&gt;Source&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://adoptopenjdk.net/&quot;&gt;AdoptOpenJDK&lt;/a&gt; builds JDK downloads of OpenJDK and OpenJ9 builds.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;/vms/jvm/graalvm&quot;&gt;GraalVM&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;Zulu&lt;/li&gt; 
 &lt;li&gt;Amazon Coretto&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.oracle.com/java/jrockit.html&quot;&gt;JRockit&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.kaffe.org/&quot;&gt;Kaffe&lt;/a&gt; (&lt;a href=&quot;https://github.com/kaffe/kaffe&quot;&gt;Source&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/alblue/jvmulator&quot;&gt;jvmulator&lt;/a&gt;: &quot;a simple emulator for Java bytecode as well as an in-memory Java compiler to allow bytecode to be generated. The generated code can be executed as well as emulated to allow stepping through bytecode line by line, and seeing what the content of the local variables or stack happens to be.&quot;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;WebAssembly:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/konsoletyper/teavm&quot;&gt;TeaVM&lt;/a&gt; - an ahead-of-time translating compiler (transpiler) of Java bytecode, that&apos;s capable of emitting JavaScript and WebAssembly.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/i-net-software/JWebAssembly&quot;&gt;JWebAssembly&lt;/a&gt; - A Java bytecode to WebAssembly compiler. It can generate the WebAssembly binary or text format. It is written in Java itself and can be integrated with other Java build tools.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/mirkosertic/Bytecoder&quot;&gt;Bytecoder&lt;/a&gt; - A Rich Domain Model for Java Bytecode and Framework to interpret and transpile it to other languages such as JavaScript, OpenCL or WebAssembly.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/leaningtech/cheerpj-meta&quot;&gt;CheerpJ&lt;/a&gt; - A Java compiler for the web that converts any Java client application into standard HTML5/WebAssembly/JavaScript.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/AmazingRise/rise-jvm&quot;&gt;Rise JVM&lt;/a&gt; - Rise JVM is a minimal Java VM based on WASM. You can try it out &lt;a href=&quot;https://risehere.net/rise-jvm&quot;&gt;here&lt;/a&gt;.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;Research/Experiments:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;../maxine-vm&quot;&gt;Maxine&lt;/a&gt;: Research JVM; &quot;meta-circular&quot; (meaning, JVM written in Java)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/tomatsu/squawk&quot;&gt;Squawk&lt;/a&gt;: A JVM for micro-devices &lt;a href=&quot;https://en.wikipedia.org/wiki/Squawk_virtual_machine&quot;&gt;Wikipedia&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.jikesrvm.org/&quot;&gt;Jikes RVM&lt;/a&gt;: Research JVM; &quot;meta-circular&quot; (meaning, JVM written in Java) &lt;a href=&quot;https://en.wikipedia.org/wiki/Jikes_RVM&quot;&gt;Wikipedia&lt;/a&gt; &lt;a href=&quot;https://github.com/JikesRVM&quot;&gt;Source&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/xranby/jamvm&quot;&gt;JamVM&lt;/a&gt;: &quot;JamVM is a new Java Virtual Machine conforming to the JVM specification edition 2 (blue book). (Clone of &lt;a href=&quot;git://git.code.sf.net/p/jamvm/code&quot;&gt;git://git.code.sf.net/p/jamvm/code&lt;/a&gt;)&quot;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://inside.java/&quot;&gt;Inside Java&lt;/a&gt;: News and views from members of the Java team at Oracle&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Support/tooling&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/corretto/heapothesys&quot;&gt;HeapOTheSys&lt;/a&gt;: a heap allocation JVM benchmark developed by the Amazon Corretto team&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>LLJVM (Low Level Java Virtual Machine)</title>
      <link>https://tedneward.github.io/Research/vms/jvm/lljvm/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">vms/jvm/lljvm/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/davidar/lljvm&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Unmaintained but looks like a good source of research/investigation.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>JVM Specifications</title>
      <link>https://tedneward.github.io/Research/vms/jvm/specifications/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">vms/jvm/specifications/index.html</guid>
      	<description>
	&lt;p&gt;(Oracle) Java Virtal Machine Specification (JVMS):&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://docs.oracle.com/javase/specs/jvms/se17/html/index.html&quot;&gt;JVM Spec, Java SE 17&lt;/a&gt; (&lt;a href=&quot;https://docs.oracle.com/javase/specs/jvms/se17/jvms17.pdf&quot;&gt;PDF&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://docs.oracle.com/javase/specs/jvms/se16/html/index.html&quot;&gt;JVM Spec, Java SE 16&lt;/a&gt; (&lt;a href=&quot;https://docs.oracle.com/javase/specs/jvms/se16/jvms16.pdf&quot;&gt;PDF&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://docs.oracle.com/javase/specs/jvms/se15/html/index.html&quot;&gt;JVM Spec, Java SE 15&lt;/a&gt; (&lt;a href=&quot;https://docs.oracle.com/javase/specs/jvms/se15/jvms15.pdf&quot;&gt;PDF&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://docs.oracle.com/javase/specs/jvms/se14/html/index.html&quot;&gt;JVM Spec, Java SE 14&lt;/a&gt; (&lt;a href=&quot;https://docs.oracle.com/javase/specs/jvms/se14/jvms14.pdf&quot;&gt;PDF&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://docs.oracle.com/javase/specs/jvms/se13/html/index.html&quot;&gt;JVM Spec, Java SE 13&lt;/a&gt; (&lt;a href=&quot;https://docs.oracle.com/javase/specs/jvms/se13/jvms13.pdf&quot;&gt;PDF&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://docs.oracle.com/javase/specs/jvms/se12/html/index.html&quot;&gt;JVM Spec, Java SE 12&lt;/a&gt; (&lt;a href=&quot;https://docs.oracle.com/javase/specs/jvms/se12/jvms12.pdf&quot;&gt;PDF&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://docs.oracle.com/javase/specs/jvms/se11/html/index.html&quot;&gt;JVM Spec, Java SE 11&lt;/a&gt; (&lt;a href=&quot;https://docs.oracle.com/javase/specs/jvms/se11/jvms11.pdf&quot;&gt;PDF&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://docs.oracle.com/javase/specs/jvms/se10/html/index.html&quot;&gt;JVM Spec, Java SE 10&lt;/a&gt; (&lt;a href=&quot;https://docs.oracle.com/javase/specs/jvms/se10/jvms10.pdf&quot;&gt;PDF&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://docs.oracle.com/javase/specs/jvms/se9/html/index.html&quot;&gt;JVM Spec, Java SE 9&lt;/a&gt; (&lt;a href=&quot;https://docs.oracle.com/javase/specs/jvms/se9/jvms9.pdf&quot;&gt;PDF&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://docs.oracle.com/javase/specs/jvms/se8/html/index.html&quot;&gt;JVM Spec, Java SE 8&lt;/a&gt; (&lt;a href=&quot;https://docs.oracle.com/javase/specs/jvms/se8/jvms8.pdf&quot;&gt;PDF&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://docs.oracle.com/javase/specs/jls/se7/html/index.html&quot;&gt;JVM Spec, Java SE 7&lt;/a&gt; (&lt;a href=&quot;https://docs.oracle.com/javase/specs/jvms/se7/jvms7.pdf&quot;&gt;PDF&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://docs.oracle.com/javase/specs/jvms/se6/html/VMSpecTOC.doc.html&quot;&gt;JVM Spec, 2nd Edition (Java SE 6)&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;(Previous-to-Java8 versions are on the Oracle website; I don&apos;t know that anybody should care about versions prior to 8. Prior to Java6, the VM was essentially unchanged since Java2/JDK 1.2.)&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Lua VM</title>
      <link>https://tedneward.github.io/Research/vms/luavm/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">vms/luavm/index.html</guid>
      	<description>
	&lt;ul&gt; 
 &lt;li&gt; &lt;p&gt;&lt;a href=&quot;http://luaforge.net/docman/view…/ANoFrillsIntroToLua51VMInstructions.pdf&quot;&gt;A No-Frills Introduction to Lua 5.1 VM Instructions&lt;/a&gt;, by Kein-Hong Man.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;a href=&quot;http://www.lua.org/doc/jucs05.pdf&quot;&gt;The Implementation of Lua 5.0&lt;/a&gt;, by Roberto Ierusalimschy et al.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://sillycross.github.io/2022/11/22/2022-11-22/&quot;&gt;Building the fastest Lua interpreter automatically!&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>MRI (Matz&apos;s Ruby Interpreter)</title>
      <link>https://tedneward.github.io/Research/vms/mri/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">vms/mri/index.html</guid>
      	<description>
	&lt;h2&gt;Articles/Posts&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.rubyguides.com/2016/02/exploring-mri/&quot;&gt;Exploring MRI&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>OMR</title>
      <link>https://tedneward.github.io/Research/vms/omr/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">vms/omr/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.eclipse.org/omr/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/eclipse/omr&quot;&gt;Github&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;From the website:&lt;/p&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;OMR is enterprise-class runtime technology that delivers high performance without sacrificing versatility or robustness. OMR components are built to be extensible. It is easy to get started, and then to incrementally add powerful capabilities to your runtime. OMR takes care of the core capabilities that are common to all runtimes, so that you can focus on the unique requirements of your language.&lt;/p&gt; 
&lt;/blockquote&gt;
	</description>
    </item>
    <item>
      <title>PL/0 Language Tools</title>
      <link>https://tedneward.github.io/Research/vms/pl0/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">vms/pl0/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://programming.dojo.net.nz/study/pl0-language-tools/index&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/oriontransfer/PL0-Language-Tools&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;PL/0 is a collection of tools for learning about parsers, interpreters, compilers and virtual machines. It has been designed from the ground up to be a minimal implementation of several common interpreter and compiler functions, including the following:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Lexical analysis and tokenisation.&lt;/li&gt; 
 &lt;li&gt;Recursive descent parsing to an abstract syntax tree.&lt;/li&gt; 
 &lt;li&gt;Direct syntax-tree interpretation.&lt;/li&gt; 
 &lt;li&gt;Static compilation to a stack based assembly language.&lt;/li&gt; 
 &lt;li&gt;Assembly from symbolic assembly language to virtual op-codes.&lt;/li&gt; 
 &lt;li&gt;Virtual machine execution using a stack-based computer.&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>QuickJS</title>
      <link>https://tedneward.github.io/Research/vms/js/quickjs/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">vms/js/quickjs/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://bellard.org/quickjs/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/bellard/quickjs&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Small and easily embeddable: just a few C files, no external dependency, 210 KiB of x86 code for a simple hello world program. An online demonstration of the QuickJS engine with its mathematical extensions is available at numcalc.com. It was compiled from C to WASM/asm.js with Emscripten. &lt;em&gt;(There is something deeply satisfying about compiling a JS engine to WASM and running JS inside of JS.)&lt;/em&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Avian</title>
      <link>https://tedneward.github.io/Research/vms/jvm/avian/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">vms/jvm/avian/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://readytalk.github.io/avian/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/ReadyTalk/avian&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;No longer maintained or supported.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Java Concurrency in Practice</title>
      <link>https://tedneward.github.io/Research/vms/jvm/jcip/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">vms/jvm/jcip/index.html</guid>
      	<description>
	&lt;p&gt;&lt;em&gt;(by Brian Goetz)&lt;/em&gt;&lt;/p&gt; 
&lt;h4&gt;Chapter 1: Introduction&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;em&gt;Safety&lt;/em&gt; means &quot;nothing bad ever happens,&quot; while &lt;em&gt;liveness&lt;/em&gt; means &quot;something good eventually happens.&quot;&lt;/li&gt; 
 &lt;li&gt;Compromising safety often means compromising correctness. An example is a race condition between multiple threads.&lt;/li&gt; 
 &lt;li&gt;A liveness failure in a single-threaded program can be an infinite loop. In a multithreaded program, it could be deadlock, starvation, or livelock.&lt;/li&gt; 
 &lt;li&gt;While liveness means that something good &lt;em&gt;eventually&lt;/em&gt; happens, performance means that it will happen &lt;em&gt;quickly&lt;/em&gt;.&lt;/li&gt; 
 &lt;li&gt;Context switches have significant costs, including saving and restoring execution context, less of locality, and spending CPU time on scheduling threads instead of running them.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Chapter 2: Thread Safety&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;Writing thread-safe code is, at its core, about managing access to shared, mutable state.&lt;/li&gt; 
 &lt;li&gt;Whenever more than one thread accesses a given state variable, and one of them might write to it, they all must coordinate their access to it using synchronization.&lt;/li&gt; 
 &lt;li&gt;A broken program shares mutable state without synchronization. Either don&apos;t share the state, make it immutable, or use synchronization upon every access.&lt;/li&gt; 
 &lt;li&gt;It is far easier to design a class to be thread-safe than to retrofit it for safety later.&lt;/li&gt; 
 &lt;li&gt;The same object-oriented techniques that help you write well-organized, maintainable classes -- such as encapsulation and data hiding -- can also help you create thread-safe classes.&lt;/li&gt; 
 &lt;li&gt;A program that consists entirely of thread-safe classes may not be thread-safe, and a thread-safe program may contain classes that are not thread-safe.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;2.1: What is thread safety?&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;A class is thread-safe if it behaves correctly when accessed from multiple threads, regardless of their scheduling or interleaving of execution, and with no additional synchronization or coordination by the calling code.&lt;/li&gt; 
 &lt;li&gt;Thread-safe classes encapsulate any needed synchronization so that clients need not provide their own.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;2.2: Atomicity&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;A race condition occurs when the correctness of a computation depends on the relative timing or interleaving of multiple threads.&lt;/li&gt; 
 &lt;li&gt;The most common type of race condition is &lt;em&gt;check-then-act&lt;/em&gt;, where an observation could have become invalid between the time you observed it and the time you acted on it, causing a problem.&lt;/li&gt; 
 &lt;li&gt;Read-modify-write operations require knowing a previous value and ensuring that no one else changes or uses that value while you are in mid-update.&lt;/li&gt; 
 &lt;li&gt;Check-then-act and read-modify-write sequences are compound actions, or sequences that must be executed atomically in order to remain thread-safe.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;2.3: Locking&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;Mutual exclusion locks, or mutexes, means that at most one thread may own a lock. If thread A attempts to acquire a lock by thread B, it blocks until B releases it.&lt;/li&gt; 
 &lt;li&gt;Reentrancy means that locks are acquired on a per-thread rather than per-invocation basis. Each lock is associated with an acquisition count and an owning thread.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;2.4: Guarding state with locks&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;For each mutable state variable that may be accessed by more than one thread, all accesses to that variable must be performed by the same lock held. The variable is &lt;em&gt;guarded&lt;/em&gt; by the lock.&lt;/li&gt; 
 &lt;li&gt;When a class has invariants that involve more than one state variable, we must ensure that each variable participating in the invariant must be guarded by the same lock.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;2.5: Liveness and performance&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;Acquiring and releasing a lock has some overhead, so do not break down guarded blocks too far, even if this would not compromise atomicity.&lt;/li&gt; 
 &lt;li&gt;When implementing a synchronization policy, resist the temptation to prematurely sacrifice simplicity (potentially compromising safety) for the sake of performance.&lt;/li&gt; 
 &lt;li&gt;Avoid holding locks during lengthy computations or operations at risk of not completing quickly, such as when performing disk or network I/O.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Chapter 3: Sharing Objects&lt;/h4&gt; 
&lt;h5&gt;3.1: Visibility&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;To ensure visibility of memory writes across threads, you must use synchronization.&lt;/li&gt; 
 &lt;li&gt;There is no guarantee that operations in one thread will be performed in the order given by the program, as long as the reordering is not detectable from within &lt;em&gt;that&lt;/em&gt; thread.&lt;/li&gt; 
 &lt;li&gt;Because of reordering, attempts to reason about the order in which memory actions &quot;must&quot; happen in insufficiently synchronized multithreaded programs will almost certainly be incorrect.&lt;/li&gt; 
 &lt;li&gt;Unless synchronization is used every time a variable is accessed, it is possible for a thread to read a stale value for that variable.&lt;/li&gt; 
 &lt;li&gt;Stale data can cause serious and confusing failures such as unexpected exceptions, corrupted data structures, inaccurate computations, and infinite loops.&lt;/li&gt; 
 &lt;li&gt;&lt;em&gt;Out-of-thin-air safety&lt;/em&gt; is when a variable reads a thread without synchronization, it reads a value that was actually written by another thread instead of some random value.&lt;/li&gt; 
 &lt;li&gt;With the Java Memory Model, the values of variables that were visible to thread A prior to releasing a lock are guaranteed to be visible to thread B upon acquiring the same lock.&lt;/li&gt; 
 &lt;li&gt;Variables marked with the &lt;code&gt;volatile&lt;/code&gt; keyword are not reordered with other memory operations, and are not put in caches where they are hidden from other processors.&lt;/li&gt; 
 &lt;li&gt;A &lt;code&gt;volatile&lt;/code&gt; variable can be used for a completion, interruption, or status flag, but the semantics are not strong enough to make the increment operation atomic, for example.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;3.2: Publication and escape&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;em&gt;Publishing&lt;/em&gt; an object means making it available to code outside of its current scope. An object that is published when it should not have been is said to have &lt;em&gt;escaped&lt;/em&gt;.&lt;/li&gt; 
 &lt;li&gt;Any object that is &lt;em&gt;reachable&lt;/em&gt; from a published object by following some chain of nonprivate field references and method calls has also been published.&lt;/li&gt; 
 &lt;li&gt;Once an object escapes, you have to assume that another class or thread may, maliciously or carelessly, misuse it. This is a compelling reason to use encapsulation.&lt;/li&gt; 
 &lt;li&gt;An object is in a predictable, consistent state only after its constructor returns, so publishing an object (via &lt;code&gt;this&lt;/code&gt;) from within its constructor can publish an incompletely constructed object.&lt;/li&gt; 
 &lt;li&gt;You can avoid this improper construction by using a private constructor and a public static factory method.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;3.3: Thread confinement&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;If data is only accessed by a single thread, then no synchronization is needed. This technique is called &lt;em&gt;thread confinement&lt;/em&gt;.&lt;/li&gt; 
 &lt;li&gt;&lt;em&gt;Ad-hoc thread confinement&lt;/em&gt; is when the responsibility for maintaining thread confinement falls entirely on the implementation.&lt;/li&gt; 
 &lt;li&gt;Thread confinement is often a consequence of deciding to implement a particular subsystem, such as the GUI, as a single thread. The simplicity benefit of such a system outweighs the fragility of ad-hoc thread confinement.&lt;/li&gt; 
 &lt;li&gt;&lt;em&gt;Stack confinement&lt;/em&gt; is a special case of thread confinement in which an object can only be reached through local variables. Local variables are intrinsically confined to the executing thread.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;3.4: Immutability&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;Immutable objects are simple, because they can only have one state. Immutable objects are also safe, because you can freely share and publish them without the need to make defensive copies.&lt;/li&gt; 
 &lt;li&gt;An object is immutable if its state cannot be modified after construction, all its fields are &lt;code&gt;final&lt;/code&gt;, and it is properly constructed, i.e. the &lt;code&gt;this&lt;/code&gt; reference does not escape during construction.&lt;/li&gt; 
 &lt;li&gt;Whenever a group of related data items but be acted upon atomically, consider creating an immutable holder class for them.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;3.5: Safe publication&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;Simply storing a reference to an object into a public field is not enough to publish that object safely. Improper publication allows another thread to observe a partially constructed object.&lt;/li&gt; 
 &lt;li&gt;However, immutable objects can be used safely by any thread without additional synchronization, even when synchronization is not used to publish them.&lt;/li&gt; 
 &lt;li&gt;To publish an object safely, both the reference to the object and the object&apos;s state must be made visible to other threads at the same time.&lt;/li&gt; 
 &lt;li&gt;Objects that are not technically immutable, but whose state will not be modified after publication, are called &lt;em&gt;effectively immutable&lt;/em&gt;. Such objects, when safely published, can be used safely by any thread without additional synchronization.&lt;/li&gt; 
 &lt;li&gt;While effectively immutable objects must be safely published, mutable objects must be safely published, and mus the either thread-safe or guarded by a lock.&lt;/li&gt; 
 &lt;li&gt;Many concurrency errors stem from failing to understand the &quot;rules of engagement&quot; for a shared object. When you publish an object, document how it should be accessed.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Chapter 4: Composing Objects&lt;/h4&gt; 
&lt;h5&gt;4.1: Designing a thread-safe class&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;Designing a thread-safe class requires identifying the invariants that constrain the state variables, and establishing a policy for managing concurrent access to them.&lt;/li&gt; 
 &lt;li&gt;The smaller the &lt;em&gt;state space&lt;/em&gt; of an object or variable, the easier it is to reason about. Use &lt;code&gt;final&lt;/code&gt; fields to reduce the state space.&lt;/li&gt; 
 &lt;li&gt;Operations with state-based preconditions are called &lt;em&gt;state-dependent&lt;/em&gt;.&lt;/li&gt; 
 &lt;li&gt;Ownership implies control, but once you publish a reference to a mutable object, you no longer have exclusive control, but at best &quot;shared ownership.&quot;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;4.2: Instance confinement&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;Encapsulating data within an object confines access to the data to the object&apos;s methods, making it easier to ensure that the data is always accessed with the appropriate lock held.&lt;/li&gt; 
 &lt;li&gt;Instance confinement also allows different state variables to be held by different locks.&lt;/li&gt; 
 &lt;li&gt;Confined objects can also escape by publishing other objects such as iterators or inner class instances that may indirectly publish the confined objects.&lt;/li&gt; 
 &lt;li&gt;Using a private lock prohibits client code from acquiring it, whereas a publicly accessible lock allows client code to participate in its synchronization policy, perhaps incorrectly.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;4.3: Delegating thread safety&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;A class with multiple independent thread-safe state variables and no operations that have any invalid state transitions can delegate thread safety to the underlying state variables.&lt;/li&gt; 
 &lt;li&gt;If a state variable is thread-safe, does not participate in any invariants that constrain its value, and has no prohibited state transitions for any of its operations, then it can be safely published.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;4.4: Adding functionality to existing thread-safe classes&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;Extending a class to support a thread-safe operation is more fragile than adding code directly to the class, as its synchronization policy is now distributed over multiple source files.&lt;/li&gt; 
 &lt;li&gt;Just as subclassing violates encapsulation of implementation, client-side locking violates encapsulation of synchronization policy.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;4.5: Documenting synchronization policies&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;Document a class&apos;s thread safety guarantees for its clients; document its synchronization policy for its maintainers.&lt;/li&gt; 
 &lt;li&gt;If you want clients to be able to create new atomic operations on your class, you must document which locks they should acquire to do so safely.&lt;/li&gt; 
 &lt;li&gt;If you must guess whether a class is thread-safe, improve the quality of your guess by interpreting the specification by someone who must implement it versus someone who will merely use it.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Chapter 10: Avoiding Liveness Hazards&lt;/h4&gt; 
&lt;h5&gt;10.1: Deadlock&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;When thread A holds lock L and tries to acquire lock M, but at the same time thread B holds lock M and tries to acquire L, this is deadlock, or &lt;em&gt;deadly embrace&lt;/em&gt;.&lt;/li&gt; 
 &lt;li&gt;When a database system detects that a set of transactions has deadlocked by searching the is-waiting-for graph for cycles, it picks a victim and aborts that transaction, thereby releasing its held locks.&lt;/li&gt; 
 &lt;li&gt;A program will be free of lock-ordering deadlocks if all threads acquire the locks they need in a fixed global order. Sometimes we must induce this ordering.&lt;/li&gt; 
 &lt;li&gt;Invoking an alien method with a lock held is asking for liveness trouble. That method might risk deadlock by acquiring other locks, or block for an unexpectedly long time and stall other threads on the held lock.&lt;/li&gt; 
 &lt;li&gt;Calling a method with no locks held is called an &lt;em&gt;open call&lt;/em&gt;, and classes that rely on open calls are more well-behaved and composable than classes that make calls with locks held.&lt;/li&gt; 
 &lt;li&gt;Resource deadlocks occur when thread A holds resource X and tries to acquire resource Y, but at the same time thread B holds resource Y and tries to acquire resource X.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;10.2: Avoiding and diagnosing deadlocks&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;Try acquiring locks with a timeout. By using a timeout that is much longer than you expect acquiring the lock to take, you can regain control when something unexpected happens.&lt;/li&gt; 
 &lt;li&gt;Thread dumps not only include a stack trace for each running thread, but locking information such as which locks are held by a thread, and which lock a thread is waiting to acquire.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;10.3: Other liveness hazards&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;em&gt;Starvation&lt;/em&gt; is when a thread is perpetually denied access to resources it needs in order to make progress; the most commonly starved resource is CPU cycles.&lt;/li&gt; 
 &lt;li&gt;&lt;em&gt;Livelock&lt;/em&gt; is a liveness failure in which a thread, while not blocked, still cannot make progress because it keeps retrying an operation that will always fail.&lt;/li&gt; 
 &lt;li&gt;Livelock can occur when multiple cooperating threads change their state in response to the others in such a way that no thread can ever make progress. The solution is to introduce randomness into the retry mechanism.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Chapter 11: Performance and Scalability&lt;/h3&gt; 
&lt;h5&gt;11.1: Thinking about performance&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;Improving performance means doing more work with fewer resources. When performance of an activity is limited by availability of a particular resource, it is &lt;em&gt;bound&lt;/em&gt; by that resource.&lt;/li&gt; 
 &lt;li&gt;Using concurrency to achieve better performance means using the processing resources we have more effectively, and enable a program to exploit additional processing resources that become available.&lt;/li&gt; 
 &lt;li&gt;&lt;em&gt;Scalability&lt;/em&gt; describes the ability to improve throughput or capacity when additional computing resources (such as CPUs, memory, storage, or I/O bandwidth) are added.&lt;/li&gt; 
 &lt;li&gt;The &quot;how much&quot; aspects like scalability, throughput, and capacity are concern for server applications. The &quot;how fast&quot; aspects like service time or latency are concern for client applications.&lt;/li&gt; 
 &lt;li&gt;Most optimizations are premature because they are often undertaken before a clear set of requirements is available.&lt;/li&gt; 
 &lt;li&gt;Make it right, then make it fast. And if attempting to make it fast, measure. Don&apos;t guess.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;11.2: Amdahl&apos;s law&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;Amdahl&apos;s law describes how much a program can theoretically be sped up by additional computing resources, based on the proportion of parallelizable to serial components.&lt;/li&gt; 
 &lt;li&gt;If F is the faction of the calculation that must be executed serially, then on a machine with N processors, we can achieve a speedup of most: 1/(F+(1-F)/N).&lt;/li&gt; 
 &lt;li&gt;When evaluating an algorithm, thinking &quot;in the limit&quot; about what would happen with hundreds or thousands of processors can offer some insight into where scaling limits might appear.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;11.3: Costs introduced by threads&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;When a new thread is switched in, the data it needs is unlikely to be in the local processor cache, and so a context switch causes a flurry of cache misses and runs a little slower at first.&lt;/li&gt; 
 &lt;li&gt;Schedulers give each runnable thread a certain minimum time quantum, thereby amortizing the cost of the context switch and its consequences over more interrupted execution time.&lt;/li&gt; 
 &lt;li&gt;A program that does more blocking has more of its threads suspended and switched out. The program therefore incurs more context switches, increasing scheduling overhead and reducing throughput.&lt;/li&gt; 
 &lt;li&gt;Special instructions called &lt;em&gt;memory barriers&lt;/em&gt; can flush or invalidate caches and flush hardware write buffers. They inhibit compiler optimizations; most operations cannot be reordered with them.&lt;/li&gt; 
 &lt;li&gt;&lt;em&gt;Lock elision&lt;/em&gt; optimizes away lock acquisitions. &lt;em&gt;Lock coarsening&lt;/em&gt; merges together adjacent blocks holding the same lock, reducing synchronization overhead and helping the optimizer.&lt;/li&gt; 
 &lt;li&gt;When a lock is contended, the losing threads must block. This can be implemented either by &lt;em&gt;spin-waiting&lt;/em&gt; or by &lt;em&gt;suspending&lt;/em&gt; the blocked thread through the operating system.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;11.4: Reducing lock contention&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;Two factors influence the likelihood of contention for a lock: How often that lock is requested, and how long it is held once acquired.&lt;/li&gt; 
 &lt;li&gt;&lt;em&gt;Lock splitting&lt;/em&gt; and &lt;em&gt;lock striping&lt;/em&gt; involve using separate locks to guard multiple independent state variables previously guarded by a single lock.&lt;/li&gt; 
 &lt;li&gt;Splitting a lock into two offers the greatest possibility for improvement when a lock is experiencing moderate but not heavy contention.&lt;/li&gt; 
 &lt;li&gt;Lock striping extends lock splitting by partitioning locking on a variable-sized set of independent objects. But locking the collection for exclusive access is more difficult and costly.&lt;/li&gt; 
 &lt;li&gt;If your class has a small number of hot fields that do not participate in invariants with other variables, then replacing them with atomic variables may improve scalability.&lt;/li&gt; 
 &lt;li&gt;Tools like &lt;code&gt;vmstat&lt;/code&gt; or &lt;code&gt;mpstat&lt;/code&gt; can show whether your application is CPU-bound, while tools like &lt;code&gt;iostat&lt;/code&gt; or &lt;code&gt;perfmon&lt;/code&gt; can show whether your application is I/O-bound.&lt;/li&gt; 
 &lt;li&gt;The tool &lt;code&gt;vmstat&lt;/code&gt; has a column reporting the number of threads that are runnable but not currently running because a CPU is not available.&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Maxine-VM</title>
      <link>https://tedneward.github.io/Research/vms/jvm/maxine-vm/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">vms/jvm/maxine-vm/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/beehive-lab/Maxine-VM&quot;&gt;Github&lt;/a&gt; | &lt;a href=&quot;https://en.wikipedia.org/wiki/Maxine_Virtual_Machine&quot;&gt;Wikipedia&lt;/a&gt; | &lt;a href=&quot;https://maxine-vm.readthedocs.io/_/downloads/en/stable/pdf/&quot;&gt;Docs&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;From the &lt;a href=&quot;https://maxine-vm.readthedocs.io/en/latest/&quot;&gt;docs page&lt;/a&gt;:&lt;/p&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;In this era of modern, managed languages we demand ever more from our virtual machines: better performance, more scalability, and support for the latest new languages. Research and experimentation is essential but challenging in the context of mature, complex, production VMs written in multiple languages. The Maxine VM is a next generation platform that establishes a new standard of productivity in this area of research. It is written entirely in Java, completely compatible with modern Java IDEs and the standard JDK, features a modular architecture that permits alternate implementations of subsystems such as GC and compilation to be plugged in, and is accompanied by a dedicated development tool (the Maxine Inspector) for debugging and visualizing nearly every aspect of the VM’s runtime state.&lt;/p&gt; 
&lt;/blockquote&gt;
	</description>
    </item>
    <item>
      <title>TornadoVM</title>
      <link>https://tedneward.github.io/Research/vms/jvm/tornadovm/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">vms/jvm/tornadovm/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.tornadovm.org/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/beehive-lab/TornadoVM&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>MAME</title>
      <link>https://tedneward.github.io/Research/vms/mame/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">vms/mame/index.html</guid>
      	<description>
	&lt;p&gt;From the website:&lt;/p&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;MAME’s purpose is to preserve decades of software history. As electronic technology continues to rush forward, MAME prevents this important &quot;vintage&quot; software from being lost and forgotten. This is achieved by documenting the hardware and how it functions. The source code to MAME serves as this documentation. The fact that the software is usable serves primarily to validate the accuracy of the documentation (how else can you prove that you have recreated the hardware faithfully?). Over time, MAME (originally stood for Multiple Arcade Machine Emulator) absorbed the sister-project MESS (Multi Emulator Super System), so MAME now documents a wide variety of (mostly vintage) computers, video game consoles and calculators, in addition to the arcade video games that were its initial focus.&lt;/p&gt; 
&lt;/blockquote&gt; 
&lt;p&gt;&lt;a href=&quot;https://www.mamedev.org/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://git.redump.net/mame/tree/&quot;&gt;Source&lt;/a&gt; and &lt;a href=&quot;https://github.com/mamedev/mame&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Mu Micro Virtual Machine</title>
      <link>https://tedneward.github.io/Research/vms/mu/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">vms/mu/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://microvm.github.io/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://gitlab.anu.edu.au/mu/mu-spec&quot;&gt;Specification&lt;/a&gt; | &lt;a href=&quot;https://mu-tutorial.readthedocs.io/en/latest/&quot;&gt;Guide&lt;/a&gt; | &lt;a href=&quot;https://gitlab.anu.edu.au/groups/mu&quot;&gt;Project&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;em&gt;Looks like the project paused/stopped development around 2019 or so&lt;/em&gt;&lt;/p&gt; 
&lt;h2&gt;Implementations&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://gitlab.anu.edu.au/mu/mu-impl-ref2&quot;&gt;Holstein&lt;/a&gt;: reference&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://gitlab.anu.edu.au/mu/mu-impl-fast&quot;&gt;Zebu&lt;/a&gt;: high-perf, in development&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;A large fraction of today’s software is written in managed languages. These languages increase software productivity by offering rich abstractions for managing memory, executing code concurrently, and hiding the complexity of modern hardware. Examples include JavaScript, PHP, Objective-C, Java, C#, Python, and Ruby. These languages are economically important. Unfortunately, most of these languages are inefficient, imposing overheads as large as a factor of fifty compared to orthodox language choices such as C.&lt;/p&gt; 
&lt;p&gt;The project will define, develop, evaluate, and refine the essential components of a new foundation layer for managed language implementation. In doing so, it will address a key source of systemic inefficiency, by pioneering micro virtual machines as an efficient high-performance substrate for managed language implementation. The relationship between a micro virtual machine and existing managed language implementations is analogous to the one between an operating system micro kernel and monolithic operating systems such as Linux. A micro virtual machine captures the insight that there exists a well-defined foundation common to most modern languages that can take responsibility for fundamental abstractions over hardware, concurrency, and memory. By isolating and exposing this substrate, a micro virtual machine embodies state-of-the-art base technology available to language implementers while isolating them from the pernicious complexities of these abstractions, freeing them to focus on all-important language-specific optimizations. This project will enable more efficient software and a distinctly sharper focus for language implementation research and development.&lt;/p&gt; 
&lt;h2&gt;Resources&lt;/h2&gt; 
&lt;h3&gt;Papers&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;Yi Lin, &quot;An efficient implementation of a micro virtual machine&quot;, Ph.D. thesis, College of Engineering and Computer Science, The Australian National University, 2019. &lt;a href=&quot;https://openresearch-repository.anu.edu.au/bitstream/1885/158122/1/Yi%20Lin%20Thesis%202019.pdf&quot; title=&quot;Download pdf&quot;&gt;pdf&lt;/a&gt; &lt;a href=&quot;https://doi.org/10.25911/5ca1dad991dbf&quot;&gt;url&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;K. Wang, S. M. Blackburn, A. L. Hosking, and M. Norrish, &quot;Hop, Skip, &amp;amp; Jump: Practical On-Stack Replacement for a Cross-Platform Language-Neutral VM&quot;, in 14th ACM SIGPLAN/SIGOPS International Conference on Virtual Execution Environments (VEE 2018), 2018. &lt;a href=&quot;https://wks.github.io/downloads/pdf/osr-vee-2018.pdf&quot;&gt;pdf&lt;/a&gt; &lt;a href=&quot;https://doi.org/10.1145/3186411.3186412&quot;&gt;url&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;Kunshan Wang, &quot;Micro Virtual Machines: A Solid Foundation for Managed Language Implementation&quot;, Ph.D. thesis, College of Engineering and Computer Science, The Australian National University, 2017. &lt;a href=&quot;https://openresearch-repository.anu.edu.au/bitstream/1885/147871/1/Wang%20Thesis%202018.pdf&quot; title=&quot;Download pdf&quot;&gt;pdf&lt;/a&gt; &lt;a href=&quot;http://hdl.handle.net/1885/147871&quot;&gt;url&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;Y. Lin, S. M. Blackburn, A. L. Hosking, and M. Norrish, &quot;Rust as a Language for High Performance GC Implementation&quot;, in Proceedings of the Sixteenth ACM SIGPLAN International Symposium on Memory Management, ISMM ‘16, Santa Barbara, CA, June 13, 2016, 2016. &lt;a href=&quot;http://users.cecs.anu.edu.au/~steveb/downloads/pdf/rust-ismm-2016.pdf&quot; title=&quot;Download pdf&quot;&gt;pdf&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;Y. Lin, K. Wang, S. M. Blackburn, M. Norrish, and A. L. Hosking, &quot;Stop and Go: Understanding Yieldpoint Behavior&quot;, in Proceedings of the Fourteenth ACM SIGPLAN International Symposium on Memory Management, ISMM ‘15, Portland, OR, June 14, 2015, 2015. &lt;a href=&quot;http://users.cecs.anu.edu.au/~steveb/downloads/pdf/yieldpoint-ismm-2015.pdf&quot; title=&quot;Download pdf&quot;&gt;pdf&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;K. Wang, Y. Lin, S. M. Blackburn, M. Norrish, and A. L. Hosking, &quot;Draining the Swamp: Micro Virtual Machines as Solid Foundation for Language Development&quot;, in 1st Summit on Advances in Programming Languages (SNAPL 2015), 2015. &lt;a href=&quot;http://drops.dagstuhl.de/opus/volltexte/2015/5034/pdf/24.pdf&quot;&gt;pdf&lt;/a&gt; &lt;a href=&quot;http://drops.dagstuhl.de/opus/frontdoor.php?source_opus=5034&quot;&gt;url&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Open Smalltalk</title>
      <link>https://tedneward.github.io/Research/vms/opensmalltalk/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">vms/opensmalltalk/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;http://opensmalltalk.org/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/OpenSmalltalk/opensmalltalk-vm&quot;&gt;Github&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;First, opensmalltalk-vm (a.k.a. the Cog VM) is the virtual machine beneath the Cuis, Pharo and Squeak Smalltalk dialects.&lt;/p&gt; 
&lt;p&gt;Second, the core VM, which comprises the execution engine and garbage collector, and the core plugins, is developed in Smalltalk, using the VM Simulator. This repository contains the code generated by the Simulator, and the platform support code for the entire VM, its CI infrastructure and so on. The core VM should not be developed by editing the generated code. The core VM should be developed using Smalltalk. The source code repository for the VM is &lt;a href=&quot;http://source.squeak.org/VMMaker.html&quot;&gt;http://source.squeak.org/VMMaker.html&lt;/a&gt;.&lt;/p&gt; 
&lt;p&gt;You can find scripts to build a Smalltalk image in which to do core VM development in the image directory in this repository. You can read about the Simulator here:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.researchgate.net/publication/328509577_Two_Decades_of_Smalltalk_VM_Development_Live_VM_Development_through_Simulation_Tools&quot;&gt;https://www.researchgate.net/publication/328509577_Two_Decades_of_Smalltalk_VM_Development_Live_VM_Development_through_Simulation_Tools&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://hal.archives-ouvertes.fr/hal-01883380/document&quot;&gt;https://hal.archives-ouvertes.fr/hal-01883380/document&lt;/a&gt; Please look at the wiki on this site for a description of on-going projects.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;Cog is an evolution of the Squeak Back-to-the-future Smalltalk virtual machine that provides a number of different Smalltalk virtual machines. The VMs are developed in Smalltalk, using all the dynamic and reflective facilities of the Squeak/Pharo Smalltalk system. As such, developing in Cog is a delight. The Smalltalk framework comprising the various Cog VMs is translated into C by its Slang component to produce VM source that is combined with platform-specific support sources and compiled via a C compiler to obtain a fast production VM. This directory tree includes the output of Slang for various configurations of &quot;Cog VM&quot; and the associated platform support code, plus build directories that can be used to produce production VMs.&lt;/p&gt; 
&lt;p&gt;This directory tree also includes an instance of the Smalltalk Cog development system, suitable for developing the VM in Smalltalk, and for generating new VM sources.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>CoCo</title>
      <link>https://tedneward.github.io/Research/vms/python/coco/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">vms/python/coco/index.html</guid>
      	<description>
	&lt;p&gt;C++: &lt;a href=&quot;https://kentdlee.github.io/CoCoPages/html/index.html&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;http://github.com/kentdlee/CoCo.git&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Java: &lt;a href=&quot;https://kentdlee.github.io/JCoCoPages/_build/html/index.html#&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;http://github.com/kentdlee/JCoCo&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Used as part of Kent Lee&apos;s book on language implementations.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Core War</title>
      <link>https://tedneward.github.io/Research/vms/corewar/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">vms/corewar/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/emilwallner/Corewar&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Core War was inspired by a malicious virus written in the 80’s. To deal with the self-replicating virus, a white hat hacker invented Reaper. It was a virus designed to spread and eliminate the malware. He fought fire with fire.&lt;/p&gt; 
&lt;p&gt;This inspired A. K. Dewdney to coin the idea for Core War.&lt;/p&gt; 
&lt;p&gt;The idea was simple. You compete by designing viruses to overtake a computer. You win by protecting your own program and overwriting your opponent&apos;s programs. This is all happening on a virtual computer. Think, a simple computer within your computer.&lt;/p&gt; 
&lt;p&gt;This is what is looks like in action:&lt;/p&gt; 
&lt;p&gt;&lt;img src=&quot;https://camo.githubusercontent.com/ecdb2786375656c7e085c85e38421ea11946a2f553ce29a6817d2eb482307d85/687474703a2f2f672e7265636f726469742e636f2f7079794167675963576d2e676966&quot; alt=&quot;&quot;&gt;&lt;/p&gt; 
&lt;p&gt;Let’s focus on the high-level game dynamics:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;The game board, the memory of our virtual computer. It’s represented in a 64 X 64 grid of bytes.&lt;/li&gt; 
 &lt;li&gt;The players, small programs represented in different colors. The white parts have blank memory.&lt;/li&gt; 
 &lt;li&gt;Cursors, the moving parts with inverted color. They read from the game board.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;The cursors have a couple of features. They can jump on the game board, store and write values, and clone themselves. The cursors belong to no-one, they just read from the game board.&lt;/p&gt; 
&lt;p&gt;When the game starts, all players have one cursor at the beginning of their program. The game advances as the cursors read the commands stored in their programs. If they end up on a faulty command or a blank memory, it moves to the next byte.&lt;/p&gt; 
&lt;p&gt;Below, we see how the pink player starts by cloning their cursors. It then starts attacking the blue player.&lt;/p&gt; 
&lt;p&gt;&lt;img src=&quot;https://camo.githubusercontent.com/716b61e9b563a2925b9f89d6ba671a7d88c0eb2afceae9f26a7f368d7e7476c8/687474703a2f2f672e7265636f726469742e636f2f593972394537384656592e676966&quot; alt=&quot;&quot;&gt;&lt;/p&gt; 
&lt;p&gt;Let’s get into a little bit more depth.&lt;/p&gt; 
&lt;p&gt;Every byte you see, the pairs of numbers or letters, are represented in hexadecimal. Each hexadecimal has the value of a digit, from 0 - 255.&lt;/p&gt; 
&lt;p&gt;There are 16 operations in the game. The operations decide if the cursor should jump to a different address, clone itself and so on. The first 16 hexadecimal are coding bytes, they all store a different operation. The remaining digits, 17 - 255, are regular numbers.&lt;/p&gt; 
&lt;p&gt;The coding byte decides which operation to execute and how many bytes to read. In the image above, the pink player goes to the hexadecimal 0c. It&apos;s 12 in decimal, telling the cursor to clone itself. The two bytes after decide where the cloned cursor starts.&lt;/p&gt; 
&lt;p&gt;&lt;img src=&quot;https://camo.githubusercontent.com/2998dc8f55ea9e1d22fbb9ce00389d9888e463acfe0852a2e5559b13d013454d/687474703a2f2f672e7265636f726469742e636f2f58516468566d717672562e676966&quot; alt=&quot;&quot;&gt;&lt;/p&gt; 
&lt;p&gt;There are three main components to determine who wins:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Game rounds, every game round is measured in cycles. It determines how much each cursor can read from the game board.&lt;/li&gt; 
 &lt;li&gt;Lives, if a cursor reads a player life from the game board, they are given a life for that round. These are visualized in the colorful progress bars.&lt;/li&gt; 
 &lt;li&gt;Cycle to die, for every game round, the number of bytes a cursor can read from the game board is reduced.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;You win if your program is the last one to receive a life.&lt;/p&gt; 
&lt;p&gt;There are more nuances to the game that I don’t cover. The best way to learn about them is to run it.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>FEX</title>
      <link>https://tedneward.github.io/Research/vms/fex/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">vms/fex/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://fex-emu.com/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/FEX-Emu/FEX&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;FEX allows you to run x86 applications on ARM64 Linux devices, similar to qemu-user and box64. It offers broad compatibility with both 32-bit and 64-bit binaries, and it can be used alongside Wine/Proton to play Windows games.&lt;/p&gt; 
&lt;p&gt;It supports forwarding API calls to host system libraries like OpenGL or Vulkan to reduce emulation overhead. An experimental code cache helps minimize in-game stuttering as much as possible. Furthermore, a per-app configuration system allows tweaking performance per game, e.g. by skipping costly memory model emulation. We also provide a user-friendly FEXConfig GUI to explore and change these settings.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>HashLink</title>
      <link>https://tedneward.github.io/Research/vms/hashlink/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">vms/hashlink/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://hashlink.haxe.org/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/HaxeFoundation/hashlink/&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Can be either executed directly or converted to C.&lt;/p&gt; 
&lt;p&gt;Appears to replace &lt;a href=&quot;./neko&quot;&gt;NekoVM&lt;/a&gt; in practice.&lt;/p&gt; 
&lt;p&gt;Performance-oriented features:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;HL bytecode is strictly typed&lt;/li&gt; 
 &lt;li&gt;Fast anonymous objects access using typed &quot;virtuals&quot;&lt;/li&gt; 
 &lt;li&gt;Static dispatch of object methods when no override exists&lt;/li&gt; 
 &lt;li&gt;Compact memory representation for all values&lt;/li&gt; 
 &lt;li&gt;Inference to reduce null field access checks to the minimum (soon)&lt;/li&gt; 
 &lt;li&gt;Low level access for pointers, single float, 8 and 16 bits integers&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>HLVM</title>
      <link>https://tedneward.github.io/Research/vms/hlvm/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">vms/hlvm/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://forge.ocamlcore.org/projects/hlvm/&quot;&gt;Website&lt;/a&gt; (not much there) | &lt;a href=&quot;https://github.com/Tipoca/hlvm&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Welcome to the High-Level Virtual Machine (HLVM) project. This open source project is designed to provide a virtual machine to support modern statically-typed functional programming languages easily and with performance characteristics ideally suited to scientific computing.&lt;/p&gt; 
&lt;p&gt;HLVM currently sports the following features:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Unit, bool, int and float primitive types.&lt;/li&gt; 
 &lt;li&gt;Tuples.&lt;/li&gt; 
 &lt;li&gt;Arrays.&lt;/li&gt; 
 &lt;li&gt;Union types.&lt;/li&gt; 
 &lt;li&gt;Function pointers.&lt;/li&gt; 
 &lt;li&gt;Tail call elimination of all tail calls.&lt;/li&gt; 
 &lt;li&gt;Generic printing.&lt;/li&gt; 
 &lt;li&gt;Foreign function interface to call C directly.&lt;/li&gt; 
 &lt;li&gt;POSIX threads.&lt;/li&gt; 
 &lt;li&gt;Mark and sweep garbage collector that allows threads to run in parallel.&lt;/li&gt; 
 &lt;li&gt;Incremental JIT compilation to high-performance native code suitable for a REPL.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;HLVM aspires to provide the following features in the future:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Closures.&lt;/li&gt; 
 &lt;li&gt;Parametric polymorphism.&lt;/li&gt; 
 &lt;li&gt;Global variables.&lt;/li&gt; 
 &lt;li&gt;Generic comparison, equality, hashing and serialization functions.&lt;/li&gt; 
 &lt;li&gt;A standard library.&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Hermes</title>
      <link>https://tedneward.github.io/Research/vms/js/hermes/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">vms/js/hermes/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://hermesengine.dev/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/facebook/hermes&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;It features ahead-of-time static optimization and compact bytecode.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Common Language Runtime (CLR)</title>
      <link>https://tedneward.github.io/Research/vms/clr/index/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">vms/clr/index/index.html</guid>
      	<description>
	&lt;p&gt;List of CLR VM implementations:&lt;br&gt; * &lt;a href=&quot;/vms/clr/coreclr&quot;&gt;CoreCLR&lt;/a&gt;, part of &lt;a href=&quot;/platforms/clr/dotnetcore&quot;&gt;.NET Core&lt;/a&gt;&lt;br&gt; * &lt;a href=&quot;https://www.mono-project.com/docs/advanced/runtime/&quot;&gt;Mono&lt;/a&gt;, which was acquired by Microsoft a few years ago | &lt;a href=&quot;https://github.com/mono/mono&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;There used to be more (below), but interest appears to have waned after an early surge.&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt; &lt;p&gt;Shared Source CLI (aka &quot;Rotor&quot;); &lt;a href=&quot;/vms/clr/sscli-essentials&quot;&gt;SSCLI Essentials&lt;/a&gt; is a good place to start to understand the CLR codebase (&quot;runtime&quot;) itself.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://github.com/lap1nou/CLR_Heap_encryption&quot;&gt;CLR Heap Encryption&lt;/a&gt; proof of concept&lt;/p&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Articles&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;Writing a .NET Profiler in C# &lt;a href=&quot;https://minidump.net/writing-a-net-profiler-in-c-part-1-d3978aae9b12&quot;&gt;Part 1&lt;/a&gt; &lt;a href=&quot;https://minidump.net/writing-a-net-profiler-in-c-part-2-8039da001e43&quot;&gt;Part 2&lt;/a&gt; &lt;a href=&quot;https://minidump.net/writing-a-net-profiler-in-c-part-3-7d2c59fc017f&quot;&gt;Part 3&lt;/a&gt; &lt;a href=&quot;https://minidump.net/writing-a-net-profiler-in-c-part-4-c54df903b9ce/&quot;&gt;Part 4&lt;/a&gt; &lt;a href=&quot;https://minidump.net/writing-a-net-profiler-in-c-part-5/&quot;&gt;Part 5&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://minidump.net/2025-28-01-writing-a-net-gc-in-c-part-1/&quot;&gt;Writing a .NET Garbage Collector in C#&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Bytecode Development</title>
      <link>https://tedneward.github.io/Research/vms/dev/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">vms/dev/index.html</guid>
      	<description>
	&lt;h2&gt;Reading&lt;/h2&gt; 
&lt;h3&gt;Articles, Blogs, Essays&lt;/h3&gt; 
&lt;h3&gt;Books&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;Crafting Interpreters: 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;http://craftinginterpreters.com/a-virtual-machine.html#design-note&quot;&gt;A Virtual Machine&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://craftinginterpreters.com/chunks-of-bytecode.html&quot;&gt;Bytecode Chunks&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;References&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;http://wiki.luajit.org/Bytecode-2.0&quot;&gt;LuaJIT Bytecode 2.0&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://docs.python.org/3/library/dis.html&quot;&gt;Python3 dis module&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.complang.tuwien.ac.at/projects/interpreters.html&quot;&gt;Anton Ertl&apos;s page&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://inko-lang.org/manual/virtual-machine/bytecode/&quot;&gt;bytecode format for Inko&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Papers&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.usenix.org/legacy/events/vee05/full_papers/p153-yunhe.pdf&quot;&gt;https://www.usenix.org/legacy/events/vee05/full_papers/p153-yunhe.pdf&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Firecracker</title>
      <link>https://tedneward.github.io/Research/vms/firecracker/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">vms/firecracker/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://firecracker-microvm.github.io/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/firecracker-microvm/firecracker&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Hercules</title>
      <link>https://tedneward.github.io/Research/vms/hercules/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">vms/hercules/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;http://www.hercules-390.eu/&quot;&gt;Website&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>HVM</title>
      <link>https://tedneward.github.io/Research/vms/hvm/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">vms/hvm/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/HigherOrderCO/HVM&quot;&gt;Source&lt;/a&gt; | &lt;a href=&quot;https://github.com/HigherOrderCO/HVM1&quot;&gt;HVM1 Source&lt;/a&gt; | &lt;a href=&quot;https://github.com/HigherOrderCO/HVM/blob/main/paper/PAPER.pdf&quot;&gt;Paper&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;This repository provides a low-level IR language for specifying the HVM2 nets and a compiler from that language to C and CUDA. It is not meant for direct human usage. If you&apos;re looking for a high-level language to interface with HVM2, check Bend instead.&lt;/p&gt; 
&lt;p&gt;HVM is a low-level compile target for high-level languages. It provides a raw syntax for wiring interaction nets. For example:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;@main = a
  &amp;amp; @sum ~ (28 (0 a))

@sum = (?(((a a) @sum__C0) b) b)

@sum__C0 = ({c a} ({$([*2] $([+1] d)) $([*2] $([+0] b))} f))
  &amp;amp;! @sum ~ (a (b $([+] $(e f))))
  &amp;amp;! @sum ~ (c (d e))
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;The file above implements a recursive sum.&lt;/p&gt; 
&lt;hr&gt; 
&lt;h1&gt;HVM1&lt;/h1&gt; 
&lt;p&gt;Pretty hyperbolic:&lt;/p&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;That is possible due to a new model of computation, the Interaction Net, which combines the Turing Machine with the Lambda Calculus. Previous implementations of this model have been inefficient in practice, however, a recent breakthrough has drastically improved its efficiency, giving birth to the HVM. Despite being a prototype, it already beats mature compilers in many cases, and is set to scale towards uncharted levels of performance.&lt;/p&gt; 
&lt;/blockquote&gt; 
&lt;p&gt;Example: &lt;code&gt;main.hvm&lt;/code&gt;; looks like untyped Haskell:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;// Creates a tree with `2^n` elements
(Gen 0) = (Leaf 1)
(Gen n) = (Node (Gen(- n 1)) (Gen(- n 1)))

// Adds all elements of a tree
(Sum (Leaf x))   = x
(Sum (Node a b)) = (+ (Sum a) (Sum b))

// Performs 2^n additions in parallel
(Main n) = (Sum (Gen n))
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;The program above creates a perfect binary tree with 2^n elements and adds them up. Since it is recursive, HVM will parallelize it automatically.&lt;/p&gt; 
&lt;p&gt;Run and compile:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;hvm r main 10                      # runs it with n=10
hvm c main                         # compiles HVM to C
clang -O2 main.c -o main -lpthread # compiles C to BIN
./main 30                          # runs it with n=30
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;The program above runs in about 6.4 seconds in a modern 8-core processor, while the identical Haskell code takes about 19.2 seconds in the same machine with GHC. This is HVM: write a functional program, get a parallel C runtime.&lt;/p&gt; 
&lt;p&gt;Benefits are solely to parallelizable (recursive) work;&lt;/p&gt; 
&lt;h2&gt;Example&lt;/h2&gt; 
&lt;p&gt;HVM is a low-level compile target for high-level languages. It provides a raw syntax for wiring interaction nets. For example:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;@main = a
  &amp;amp; @sum ~ (28 (0 a))

@sum = (?(((a a) @sum__C0) b) b)

@sum__C0 = ({c a} ({$([*2] $([+1] d)) $([*2] $([+0] b))} f))
  &amp;amp;! @sum ~ (a (b $(:[+] $(e f))))
  &amp;amp;! @sum ~ (c (d e))
&lt;/code&gt;&lt;/pre&gt;
	</description>
    </item>
    <item>
      <title>CLR virtual machine/execution engine specifications</title>
      <link>https://tedneward.github.io/Research/vms/clr/specifications/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">vms/clr/specifications/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;/platforms/clr&quot;&gt;CLR/CLI&lt;/a&gt; Specifications:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://www.ecma-international.org/publications-and-standards/standards/ecma-335/&quot;&gt;ECMA-335&lt;/a&gt;: Common Language Infrastructure (CLI) | &lt;a href=&quot;https://www.ecma-international.org/publications/files/ECMA-ST/ECMA-335.pdf&quot;&gt;PDF&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://github.com/dotnet/runtime/blob/main/docs/design/specs/Ecma-335-Augments.md&quot;&gt;&lt;code&gt;dotnet/runtime/docs/design/specs&lt;/code&gt; ECMA-335 CLI Addenda&lt;/a&gt;: Explicitly adds CLI support for C# 8.0 default interface methods, among other things&lt;/p&gt; &lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Dis</title>
      <link>https://tedneward.github.io/Research/vms/dis/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">vms/dis/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.vitanuova.com/inferno/papers/dis.html&quot;&gt;Specification&lt;/a&gt; (&lt;a href=&quot;https://www.vitanuova.com/inferno/papers/dis.pdf&quot;&gt;PDF&lt;/a&gt;) | &lt;a href=&quot;https://www.vitanuova.com/inferno/papers/hotchips.html&quot;&gt;&quot;The Design of the Inferno Virtual Machine&quot;&lt;/a&gt; (&lt;a href=&quot;https://www.vitanuova.com/inferno/papers/hotchips.pdf&quot;&gt;PDF&lt;/a&gt;)&lt;/p&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;The virtual machine models a CISC-like, three operand, memory-to-memory architecture. Code can either be interpreted by a C library or compiled on-the-fly into machine code for the target architecture. ... The Dis machine performs both reference counted and real time mark and sweep garbage collection.&lt;/p&gt; 
&lt;/blockquote&gt;
	</description>
    </item>
    <item>
      <title>Game Boy (Emulator/VM)</title>
      <link>https://tedneward.github.io/Research/vms/gameboy/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">vms/gameboy/index.html</guid>
      	<description>
	&lt;h3&gt;Resources&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://izik1.github.io/gbops/&quot;&gt;gbops&lt;/a&gt;: A table of Game Boy’s instruction set. Information necessary for decoding instructions is summarized here.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://marc.rawer.de/Gameboy/Docs/GBCPUman.pdf&quot;&gt;Game Boy CPU Manual&lt;/a&gt;: CPU manual.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://gbdev.io/pandocs/&quot;&gt;Pandocs&lt;/a&gt;: A wiki with details on how each hardware module should work.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Implementations&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://imrannazar.com/GameBoy-Emulation-in-JavaScript&quot;&gt;&quot;Game Boy Emulation in JavaScript&quot;&lt;/a&gt; (&lt;a href=&quot;http://github.com/Two9A/jsGB&quot;&gt;Source&lt;/a&gt;): A tutorial on how to implement a Game Boy emulator in JavaScript.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://linoscope.github.io/writing-a-game-boy-emulator-in-ocaml/&quot;&gt;&quot;Writing a Game Boy Interpreter in OCaml&quot;&lt;/a&gt; With resource links to:&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>HHVM</title>
      <link>https://tedneward.github.io/Research/vms/hhvm/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">vms/hhvm/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://hhvm.com/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/facebook/hhvm&quot;&gt;Github&lt;/a&gt; | &lt;a href=&quot;languages/hack.html&quot;&gt;Hack&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>IKVM</title>
      <link>https://tedneward.github.io/Research/vms/ikvm/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">vms/ikvm/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/ikvm-revived/ikvm&quot;&gt;GitHub&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;IKVM is an implementation of Java for the Microsoft .NET platform. It can be used to quickly and easily:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Execute compiled Java code (bytecode) on .NET Framework or .NET Core&lt;/li&gt; 
 &lt;li&gt;Convert bytecode to a .NET assembly to directly access its API in a .NET project&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;These tasks can be done without porting source code to .NET.&lt;/p&gt; 
&lt;p&gt;IKVM Components&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;A Java virtual machine (JVM) implemented in .NET&lt;/li&gt; 
 &lt;li&gt;A .NET implementation of the Java class libraries&lt;/li&gt; 
 &lt;li&gt;A tool that translates Java bytecode (JAR files) to .NET IL (DLL or EXE files).&lt;/li&gt; 
 &lt;li&gt;Tools that enable Java and .NET interoperability&lt;/li&gt; 
 &lt;li&gt;A full JRE/JDK 8 runtime image.&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>SSCLI Essentials</title>
      <link>https://tedneward.github.io/Research/vms/clr/sscli-essentials/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">vms/clr/sscli-essentials/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;../SSCLI2Internals-DRAFT.pdf&quot;&gt;SSCLI Essentials 2.0 (Draft) PDF&lt;/a&gt;: This is the last (draft) copy I have of the SSCLI Essentials 2.0 book that Joel Pobar and I worked on for Microsoft Research, as a follow-on to the first edition by David, Geoff, and myself. Most high-level details appear to be in sync with the .NET Core release, although as one might expect, there is some source drift--not unexpected, since this book was done in 2006.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>DolphinVM</title>
      <link>https://tedneward.github.io/Research/vms/dolphinsmalltalk/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">vms/dolphinsmalltalk/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/dolphinsmalltalk/DolphinVM&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;This repository is now obsolete. It has been merged into the main Dolphin repository for Dolphin 7.1.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Glulx</title>
      <link>https://tedneward.github.io/Research/vms/glulx/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">vms/glulx/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.eblong.com/zarf/glulx/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;http://github.com/erkyrath/glulxe&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Glulx is a portable VM, like the Z-machine. Unlike the Z-machine, it uses 32-bit data and addresses, so it can handle game files up to four gigabytes long. Also unlike the Z-machine, it has native support for Glk I/O, so game files can use any capability Glk provides. However, like the Z-machine -- again -- you can write games in the Inform language and compile them to Glulx game files.&lt;/p&gt; 
&lt;hr&gt; 
&lt;h1&gt;Quixe: a Glulx VM interpreter in Javascript&lt;/h1&gt; 
&lt;p&gt;&lt;a href=&quot;http://github.com/erkyrath/quixe&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/erkyrath/lectrote&quot;&gt;Lectrote (Quixe in an Electron app)&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>HiggsJS VM</title>
      <link>https://tedneward.github.io/Research/vms/higgs/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">vms/higgs/index.html</guid>
      	<description>
	&lt;p&gt;[Source]&lt;a href=&quot;https://github.com/higgsjs/Higgs&quot;&gt;https://github.com/higgsjs/Higgs&lt;/a&gt;)&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>JPC (Java PC)</title>
      <link>https://tedneward.github.io/Research/vms/jpc/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">vms/jpc/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/ianopolous/JPC&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>CLR FFI</title>
      <link>https://tedneward.github.io/Research/vms/clr/ffi/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">vms/clr/ffi/index.html</guid>
      	<description>
	&lt;p&gt;-ClrDebug: Managed wrappers around the Unmanaged API&lt;br&gt; - &lt;a href=&quot;https://github.com/lordmilko/ClrDebug&quot;&gt;https://github.com/lordmilko/ClrDebug&lt;/a&gt;&lt;br&gt; - CoreRTDemo: Building a native library in C# and calling it from C++&lt;br&gt; - &lt;a href=&quot;https://github.com/encrypt0r/CoreRTDemo&quot;&gt;https://github.com/encrypt0r/CoreRTDemo&lt;/a&gt;&lt;br&gt; - Writing Native Libraries in C# and using them in other languages&lt;br&gt; - &lt;a href=&quot;https://dev.to/encrypt0r/writing-native-libraries-in-c-3kl&quot;&gt;https://dev.to/encrypt0r/writing-native-libraries-in-c-3kl&lt;/a&gt;&lt;br&gt; - CppSharp&lt;br&gt; - Tools and libraries to glue C/C++ APIs to high-level languages&lt;br&gt; - &lt;a href=&quot;https://github.com/mono/CppSharp&quot;&gt;https://github.com/mono/CppSharp&lt;/a&gt;&lt;br&gt; - P/Invoke: A library containing all P/Invoke code so you don&apos;t have to import it every time. Maintained and updated to support the latest Windows OS.&lt;br&gt; - &lt;a href=&quot;https://github.com/AArnott/pinvoke&quot;&gt;https://github.com/AArnott/pinvoke&lt;/a&gt;&lt;br&gt; - The .NET Inter-Operability Operation&lt;br&gt; - Derbycon 2017; James Forshaw&lt;br&gt; - &lt;a href=&quot;http://www.irongeek.com/i.php?page=videos/derbycon7/s13-the-net-inter-operability-operation-james-forshaw&quot;&gt;http://www.irongeek.com/i.php?page=videos/derbycon7/s13-the-net-inter-operability-operation-james-forshaw&lt;/a&gt;&lt;br&gt; - Using Span for high performance interop with unmanaged libraries&lt;br&gt; - &lt;a href=&quot;https://ericsink.com/entries/utf8z.html&quot;&gt;https://ericsink.com/entries/utf8z.html&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>CoreCLR</title>
      <link>https://tedneward.github.io/Research/vms/clr/coreclr/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">vms/clr/coreclr/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/dotnet/runtime&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;../sscli-essentials&quot;&gt;SSCLI Essentials&lt;/a&gt; is a good place to start to understand the CLR itself.&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://github.com/dotnet/coreclr/tree/master/Documentation/botr&quot;&gt;&quot;Book of the Runtime&quot;&lt;/a&gt;: Guides to the internals of .NET Core. Anything in here that conflicts with SSCLI Essentials should be considered the more accurate of the two.&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://github.com/dotnet/cli/blob/rel/1.0.0/Documentation/specs/corehost.md&quot;&gt;corehost.exe runtime assembly resolution&lt;/a&gt; (Note that the &lt;code&gt;cli&lt;/code&gt; repo has been pulled into the &lt;code&gt;sdk&lt;/code&gt; repo now, so it&apos;s not clear how accurate this link is at this point)&lt;/p&gt; 
&lt;h2&gt;List of blog posts that provide a &apos;deep-dive&apos; into the CoreCLR source code&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://mattwarren.org/2016/07/04/How-the-dotnet-CLI-tooling-runs-your-code/&quot;&gt;&quot;How the &lt;code&gt;dotnet&lt;/code&gt; CLI runs your code&quot;&lt;/a&gt;: Great breakdown of how the &lt;code&gt;dotnet&lt;/code&gt; tool works, particular emphasis to the environment variables mentioned (&lt;code&gt;COREHOST_TRACE&lt;/code&gt; and &lt;code&gt;DOTNET_CLI_CAPTURE_TIMING&lt;/code&gt;)&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Posts that take a high-level overview of releases&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.ageofascent.com/2017/11/05/perfromance-dotnet-core-2-corestart-conference/&quot;&gt;Corestart 2.0: What&apos;s new for performance in .NET Core 2.0&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://devblogs.microsoft.com/dotnet/performance-improvements-in-net-core/&quot;&gt;Performance improvements in .NET Core 2.0&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://devblogs.microsoft.com/dotnet/performance-improvements-in-net-core-2-1/&quot;&gt;Performance improvements in .NET Core 2.1&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://devblogs.microsoft.com/dotnet/performance-improvements-in-net-core-3-0/&quot;&gt;Performance improvements in .NET Core 3.0&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://devblogs.microsoft.com/dotnet/performance-improvements-in-net-5/&quot;&gt;Performance improvements in .NET 5&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Posts that take a high-level look at the entire source:&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;http://mattwarren.org/2017/03/23/Hitchhikers-Guide-to-the-CoreCLR-Source-Code/&quot;&gt;A Hitchhikers Guide to the CoreCLR Source Code&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://mattwarren.org/2017/02/07/The-68-things-the-CLR-does-before-executing-a-single-line-of-your-code/&quot;&gt;The 68 things the CLR does before executing a single line of your code&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://mattwarren.org/2016/12/12/Research-papers-in-the-.NET-source/&quot;&gt;Research papers in the .NET source&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Posts that reference specific parts of the source:&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;http://mattwarren.org/2017/08/02/A-look-at-the-internals-of-boxing-in-the-CLR/&quot;&gt;A look at the internals of &apos;boxing&apos; in the CLR&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://mattwarren.org/2017/07/10/Memory-Usage-Inside-the-CLR/&quot;&gt;Memory Usage Inside the CLR&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://mattwarren.org/2017/06/15/How-the-.NET-Rutime-loads-a-Type/&quot;&gt;How the .NET Runtime loads a Type&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://mattwarren.org/2017/05/19/Adding-a-new-Bytecode-Instruction-to-the-CLR/&quot;&gt;Adding a new Bytecode Instruction to the CLR&lt;/a&gt; (Peter Drayton did this back in the first release of Rotor, and did several conference talks on it; unfortunately his materials were sort of lost to the world when he went into hiding inside Microsoft)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://mattwarren.org/2017/05/08/Arrays-and-the-CLR-a-Very-Special-Relationship/&quot;&gt;Arrays and the CLR - a Very Special Relationship&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://mattwarren.org/2017/04/13/The-CLR-Thread-Pool-Thread-Injection-Algorithm/&quot;&gt;The CLR Thread Pool &apos;Thread Injection&apos; Algorithm&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://mattwarren.org/2017/03/30/The-.NET-IL-Interpreter/&quot;&gt;The .NET IL Interpreter&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://mattwarren.org/2017/01/25/How-do-.NET-delegates-work/&quot;&gt;How do .NET delegates work?&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://mattwarren.org/2016/12/14/Why-is-Reflection-slow/&quot;&gt;Why is reflection slow?&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://mattwarren.org/2016/08/16/Preventing-dotNET-Garbage-Collections-with-the-TryStartNoGCRegion-API/&quot;&gt;Preventing .NET Garbage Collections with the TryStartNoGCRegion API&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://mattwarren.org/2016/08/08/GC-Pauses-and-Safe-Points/&quot;&gt;GC Pauses and Safe Points&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://mattwarren.org/2016/05/31/Strings-and-the-CLR-a-Special-Relationship/&quot;&gt;Strings and the CLR - a Special Relationship&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Atom</title>
      <link>https://tedneward.github.io/Research/vms/atom/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">vms/atom/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://atomvm.sourceforge.net/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://sourceforge.net/projects/atomvm/files/&quot;&gt;Download&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;The VM can be programmed using a neo-assembler language called Atom Assembler. This document discusses the VM and explains each opcode in Atom Assembler.&lt;/p&gt; 
&lt;p&gt;Atom is a register based Virtual Machine (VM). Atom consists of one bank of registers numbered 1 through 64, of type Variant. The VM is programmed with Atom Assembler, a high-level, neo-assembler language.&lt;/p&gt; 
&lt;p&gt;Atom is currently in alpha stage, and as such, lacks a few features. Most notably missing is file I/O and a byte-code compiler. Both of these items are on the to-do list. However, it does have over 100 commands (opcodes), and fairly complex programs can be written in Atom Assembler and executed by the VM.&lt;/p&gt; 
&lt;p&gt;Atom is written in Delphi. It is released under the GPL and the source code can be downloaded from the Sourceforge files section.&lt;/p&gt; 
&lt;p&gt;I created Atom as a learning exercise in building a virtual machine. See my article Why Atom, for more details. At some point in time, after the VM is feature complete, I plan on creating a high-level language (named Atom of course) that will interface with the VM.&lt;/p&gt; 
&lt;p&gt;I hope that eventually, Atom will become useful. Even if it doesn&apos;t though, it will have served the purpose of being a vehicle for learning the intricacies of creating a programming language.&lt;/p&gt; 
&lt;hr&gt; 
&lt;p&gt;Includes Screen Opcodes (!) and File Opcodes, not to mention Widgets. Not your typical VM.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Bochs</title>
      <link>https://tedneward.github.io/Research/vms/bochs/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">vms/bochs/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;http://bochs.sourceforge.net/&quot;&gt;Website&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Dalvik</title>
      <link>https://tedneward.github.io/Research/vms/android/dalvik/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">vms/android/dalvik/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://source.android.com/devices/tech/dalvik&quot;&gt;Dalvik and ART home page&lt;/a&gt;&lt;/p&gt; 
&lt;hr&gt; 
&lt;p&gt;&lt;a href=&quot;https://github.com/jserv/simple-dvm&quot;&gt;Simple-DVM&lt;/a&gt;: A simplified educational Dalvik virtual machine implemetnation&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>ActionScript VM</title>
      <link>https://tedneward.github.io/Research/vms/avmplus/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">vms/avmplus/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/adobe-flash/avmplus&quot;&gt;Source&lt;/a&gt; -- no updates since 2013, research/investigation use only&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://github.com/adobe/avmplus&quot;&gt;Source&lt;/a&gt; -- no updates since 2016, research/investigation use only. Appears to contain all contains of prior link, plus an additional drop of some files three years later.&lt;/p&gt; 
&lt;p&gt;Both appear to be straight source-drop-dumps of the AVM when it was discontinued.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Brainfuck VM</title>
      <link>https://tedneward.github.io/Research/vms/brainfuck-vm/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">vms/brainfuck-vm/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/Dominik-Salawa/Brainfuck-VM&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Smali</title>
      <link>https://tedneward.github.io/Research/vms/android/smali/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">vms/android/smali/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/JesusFreke/smali&quot;&gt;Source&lt;/a&gt; &lt;em&gt;(Last update 2022)&lt;/em&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>BareMetalVMM</title>
      <link>https://tedneward.github.io/Research/vms/baremetalvmm/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">vms/baremetalvmm/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/raesene/baremetalvmm&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;The goal of the project is to be useful in cases where you want something like Docker, but want some more isolation that Docker provides, or you want to do lower level tasks in the VM that don&apos;t suit Docker well. N.B we&apos;re not there yet!&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Chip-8</title>
      <link>https://tedneward.github.io/Research/vms/chip-8/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">vms/chip-8/index.html</guid>
      	<description>
	&lt;h2&gt;Reading&lt;/h2&gt; 
&lt;h3&gt;Articles&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;http://devernay.free.fr/hacks/chip8/C8TECH10.HTM&quot;&gt;Cowgod&apos;s Chip-8 Technical Reference&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>AquaVM</title>
      <link>https://tedneward.github.io/Research/vms/aquavm/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">vms/aquavm/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/fluencelabs/aquavm&quot;&gt;Github&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>BEAM VM</title>
      <link>https://tedneward.github.io/Research/vms/beamvm/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">vms/beamvm/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/erlang/otp/tree/master/erts/emulator/beam&quot;&gt;Source (I think)&lt;/a&gt; - Looks like it&apos;s bundled with language and platform source&lt;/p&gt; 
&lt;h2&gt;Reading&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;http://beam-wisdoms.clau.se/en/latest/&quot;&gt;BEAM Wisdoms&lt;/a&gt; (HTML)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://blog.stenmans.org/theBeamBook&quot;&gt;The BEAM Book&lt;/a&gt; (HTML) / &lt;a href=&quot;https://happi.github.io/theBeamBook/&quot;&gt;https://happi.github.io/theBeamBook/&lt;/a&gt; : Very good book which covers almost all the aspects of the Erlang RunTime System and BEAM subsystems.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://erlang.org/doc/efficiency_guide/introduction.html&quot;&gt;Erlang Efficiency Guide&lt;/a&gt;.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://erlang.org/doc/efficiency_guide/advanced.html#id71365&quot;&gt;How much memory&lt;/a&gt; do native Erlang data types occupy and also some important system limits.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.erlang-factory.com/upload/presentations/247/erlang_vm_1.pdf&quot;&gt;Evolution of the Erlang VM&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://jlouisramblings.blogspot.ch/2013/01/how-erlang-does-scheduling.html&quot;&gt;How Erlang does scheduling&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://webcem01.cem.itesm.mx:8005/erlang/cd/downloads/hopl_erlang.pdf&quot;&gt;A History of Erlang&lt;/a&gt; by Joe Armstrong.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Notes&lt;/h2&gt; 
&lt;p&gt;&lt;a href=&quot;https://happi.github.io/theBeamBook/#CH-Beam_loader&quot;&gt;https://happi.github.io/theBeamBook/#CH-Beam_loader&lt;/a&gt;: A very interesting part from the aforementioned book about the BEAM code loader and transformation from generic to specific instructions. Basically the Erlang bytecode loader does a large amount of work rewriting the generic &quot;transport format&quot; bytecode in the object files into the concrete internal bytecode operations that are actually executed. This recognizes common sequences and replaces them with optimized single-opcode versions.&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;http://gomoripeti.github.io/beam_by_example/&quot;&gt;http://gomoripeti.github.io/beam_by_example/&lt;/a&gt;: A peak into the Erlang compiler and BEAM bytecode. This is an overview of all the intermediate representations of the Erlang code. Steps described in the article are as follows: &lt;code&gt;Erlang source code --&amp;gt; Abstract Syntax Tree (&apos;P&apos;) --&amp;gt; expanded AST (&apos;E&apos;) --&amp;gt; Core Erlang (&apos;to_core&apos;) --&amp;gt; BEAM byte-code&lt;/code&gt;. However I would also add two missing steps namely BEAM generic bytecode --&amp;gt; BEAM specific bytecode and Core Erlang --&amp;gt; Kernel Erlang.&lt;br&gt; So to sum up, the main compilation stages for Erlang are:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;preprocessing (macros, conditional compilation, includes) 
  &lt;ul&gt; 
   &lt;li&gt;source-level expansions, such as records to tuples&lt;/li&gt; 
   &lt;li&gt;translation to Core Erlang + optimizations and optional inlining&lt;/li&gt; 
   &lt;li&gt;translation to &quot;Kernel Erlang&quot; + pattern matching compilation and further optimizations&lt;/li&gt; 
   &lt;li&gt;translation to Beam assembler + some more optimizations&lt;/li&gt; 
   &lt;li&gt;encoding as Beam bytecode&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;StackOverflow question with an interesting answer which contains some details about the Erlang pattern match compiler:&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://stackoverflow.com/questions/587996/erlang-beam-bytecode&quot;&gt;https://stackoverflow.com/questions/587996/erlang-beam-bytecode&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Source code of the Kernel Erlang compiler (&lt;code&gt;v3_kernel.erl&lt;/code&gt;) with useful comments:&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://github.com/erlang/otp/blob/master/lib/compiler/src/v3_kernel.erl#L20&quot;&gt;https://github.com/erlang/otp/blob/master/lib/compiler/src/v3_kernel.erl#L20&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;A nice thread descibing compilation to BEAM bytecode via &lt;code&gt;EAF&lt;/code&gt; (in the context of Elixir). It also contains useful links:&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://elixirforum.com/t/getting-each-stage-of-elixirs-compilation-all-the-way-to-the-beam-bytecode/1873&quot;&gt;https://elixirforum.com/t/getting-each-stage-of-elixirs-compilation-all-the-way-to-the-beam-bytecode/1873&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Erlang &lt;code&gt;compile&lt;/code&gt; module docs:&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;http://erlang.org/doc/man/compile.html#file-2&quot;&gt;http://erlang.org/doc/man/compile.html#file-2&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;BEAM file format:&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;http://rnyingma.synrc.com/publications/cat/Functional%20Languages/Erlang/BEAM.pdf&quot;&gt;http://rnyingma.synrc.com/publications/cat/Functional%20Languages/Erlang/BEAM.pdf&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Erlang abstract format docs:&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;http://erlang.org/doc/apps/erts/absform.html&quot;&gt;http://erlang.org/doc/apps/erts/absform.html&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;The Erlang BEAM Virtual Machine Specification by one of its designers (Björn in the BEAM):&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;http://www.cs-lab.org/historical_beam_instruction_set.html&quot;&gt;http://www.cs-lab.org/historical_beam_instruction_set.html&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;A Peek Inside the Erlang Compiler:&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;http://prog21.dadgum.com/127.html&quot;&gt;http://prog21.dadgum.com/127.html&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;BEAM wisdoms:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;BEAM file format: &lt;a href=&quot;http://beam-wisdoms.clau.se/en/latest/indepth-beam-file.html#&quot;&gt;http://beam-wisdoms.clau.se/en/latest/indepth-beam-file.html#&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;BEAM instructions: &lt;a href=&quot;http://beam-wisdoms.clau.se/en/latest/indepth-beam-instructions.html#&quot;&gt;http://beam-wisdoms.clau.se/en/latest/indepth-beam-instructions.html#&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;Also a nice description of the BEAM instruction set: &lt;a href=&quot;http://erlangonxen.org/more/beam&quot;&gt;http://erlangonxen.org/more/beam&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Thesis which contains some useful information about the Erlang implementation: &lt;a href=&quot;http://uu.diva-portal.org/smash/get/diva2:428121/FULLTEXT01.pdf&quot;&gt;http://uu.diva-portal.org/smash/get/diva2:428121/FULLTEXT01.pdf&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Code of the BEAM loader which was described above: &lt;a href=&quot;https://github.com/erlang/otp/blob/master/erts/emulator/beam/beam_load.c&quot;&gt;https://github.com/erlang/otp/blob/master/erts/emulator/beam/beam_load.c&lt;/a&gt; You might be particularly interested in the &lt;code&gt;static int transform_engine(LoaderState* st)&lt;/code&gt; function.&lt;/p&gt; 
&lt;p&gt;Internal doc in the erts/emulator is a treasure trove of the underlying implementation details: &lt;a href=&quot;https://github.com/erlang/otp/tree/master/erts/emulator/internal_doc&quot;&gt;https://github.com/erlang/otp/tree/master/erts/emulator/internal_doc&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Will put reference to the Erlang garbage collection doc as a separate link: &lt;a href=&quot;https://github.com/erlang/otp/blob/master/erts/emulator/internal_doc/GarbageCollection.md&quot;&gt;https://github.com/erlang/otp/blob/master/erts/emulator/internal_doc/GarbageCollection.md&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Reductions:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt; &lt;p&gt;Current max reductions is &lt;a href=&quot;https://github.com/erlang/otp/blob/OTP-21.3.8.11/erts/emulator/beam/erl_vm.h#L39&quot;&gt;4000&lt;/a&gt;.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Information regarding reduction from the &lt;a href=&quot;https://github.com/happi/theBeamBook/blob/master/chapters/scheduling.asciidoc#reductions&quot;&gt;BeamBook&lt;/a&gt;.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;What counts as a VM reduction: As per Erlang VM maintainer &lt;a href=&quot;https://stackoverflow.com/a/31805391/1744056&quot;&gt;Lukas Larsson&apos;s comment&lt;/a&gt;:&lt;/p&gt; &lt;pre&gt;&lt;code&gt;As a general rule of thumb; a function call (not the return) or anything that may take an unknown amount of time counts reductions. This includes bifs, nifs, gc, sending/receiving messages and probably more that I cannot think of right now.
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Optimisations and monitoring&lt;/h4&gt; 
&lt;ol&gt; 
 &lt;li&gt; &lt;p&gt;Internal OTP doc which contains useful insights regaring the process managements, lock and run queues:&lt;br&gt; &lt;a href=&quot;https://github.com/erlang/otp/blob/master/erts/emulator/internal_doc/ProcessManagementOptimizations.md&quot;&gt;https://github.com/erlang/otp/blob/master/erts/emulator/internal_doc/ProcessManagementOptimizations.md&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Insights by one of the original designers of BEAM SMP support (Rickard Green) into the scheduler &lt;a href=&quot;http://erlang.org/doc/man/erl.html#+scl&quot;&gt;compaction of load mode&lt;/a&gt; taken from this email thread: &lt;a href=&quot;http://erlang.org/pipermail/erlang-questions/2012-October/069585.html&quot;&gt;http://erlang.org/pipermail/erlang-questions/2012-October/069585.html&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
&lt;/ol&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;The runtime system tries to compact the load on as few schedulers as possible without getting run-queues that build up. The runtime system wont wake up new schedulers unless some overload has accumulated. This overload either show up as a quickly growing run-queue or a small run-queue over a longer time. The +swt flags sets the threshold that is used for determining when enough overload has accumulated to wake up another scheduler. This compaction of load onto fewer schedulers is there in order to reduce communication overhead when there aren&apos;t enough work to fully utilize all schedulers. The performance gain of this compaction depends on the hardware. We have gotten reports about problems with this functionality, but we have not found any bugs in this functionality. We have only found that it behaves as expected. That is, if more schedulers aren&apos;t woken this is&lt;br&gt; due to not enough accumulated overload. The +swt switch was introduced in order to give the user the possibility do define what is enough overload for his or her taste. The currently used wakeup strategy is very quick to forget about previously accumulated overload that has disappeared. Maybe even too quick for my taste when &quot;+swt very_low&quot; is used. I&apos;ve therefore implemented an alternative strategy that most likely will be the default in R16. As of R15B02 you can try this strategy out by passing &quot;+sws proposal&quot; as a command line argument. In combination with &quot;+swt very_low&quot;, the runtime system should be even more eager to wake up schedulers than when only using &quot;+swt very_low&quot;.&lt;/p&gt; 
&lt;/blockquote&gt; 
&lt;h2&gt;ETS Table&lt;/h2&gt; 
&lt;p&gt;When access an ETS table, there are wo locks that need to be taken:&lt;/p&gt; 
&lt;ol&gt; 
 &lt;li&gt;A lock to access the meta table, to convert the numeric table identifier to a pointer to the actual table.&lt;/li&gt; 
 &lt;li&gt;The lock for the table itself (either a read or write lock). read and write_concurrency: &lt;a href=&quot;http://erlang.org/doc/man/ets.html#new_2_write_concurrency&quot;&gt;http://erlang.org/doc/man/ets.html#new_2_write_concurrency&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;The default locking is on table-level, allowing only one update operation at a time per table. Table option write_concurrency will enable locking on a more fine grained level, allowing concurrent update operations. In current implementation 16 locks per table is used, which result in a probability of 1/16 that two random keys will collide on the same lock. Option write_concurrency have no effect on ordered_set&apos;s.&lt;/li&gt; 
&lt;/ol&gt; 
&lt;p&gt;ETS Scalability paper: &lt;a href=&quot;http://winsh.me/papers/erlang_workshop_2013.pdf&quot;&gt;http://winsh.me/papers/erlang_workshop_2013.pdf&lt;/a&gt;&lt;br&gt; ETS meta table source code: &lt;a href=&quot;https://github.com/erlang/otp/blob/master/erts/emulator/beam/erl_db.c#L324&quot;&gt;https://github.com/erlang/otp/blob/master/erts/emulator/beam/erl_db.c#L324&lt;/a&gt;&lt;/p&gt; 
&lt;h3&gt;External Term Format&lt;/h3&gt; 
&lt;p&gt;&lt;a href=&quot;http://erlang.org/doc/apps/erts/erl_ext_dist.html&quot;&gt;Official Erlang documentation&lt;/a&gt; on this topic&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;http://erlang.org/doc/man/erlang.html#term_to_binary-2&quot;&gt;term_to_binary/2&lt;/a&gt; docs&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://github.com/erlang/otp/blob/master/erts/emulator/beam/external.c#L2061&quot;&gt;C implementation&lt;/a&gt; of the term_to_binary in ERTS.&lt;/p&gt; 
&lt;h3&gt;Erlang GC&lt;/h3&gt; 
&lt;p&gt;Garbage collect &lt;a href=&quot;https://github.com/erlang/otp/blob/master/erts/emulator/beam/erl_gc.c#L664&quot;&gt;C implementation&lt;/a&gt;.&lt;/p&gt; 
&lt;h3&gt;Erlang processes&lt;/h3&gt; 
&lt;p&gt;&lt;a href=&quot;https://github.com/erlang/otp/blob/master/erts/emulator/beam/erl_process.c#L11391&quot;&gt;erl_create_process&lt;/a&gt; function.&lt;/p&gt; 
&lt;h3&gt;BIFs&lt;/h3&gt; 
&lt;p&gt;We always use BIFs in Erlang such as &lt;code&gt;element&lt;/code&gt; or &lt;code&gt;spawn_link&lt;/code&gt; or whatnot in our code. &lt;code&gt;gen&lt;/code&gt; and &lt;code&gt;gen_server&lt;/code&gt; are based on the &lt;code&gt;erlang:spawn&lt;/code&gt; BIF, hence I think it&apos;s important to know how BIFs are actually implemented: &lt;a href=&quot;https://github.com/erlang/otp/blob/master/lib/stdlib/src/erl_internal.erl#L22&quot;&gt;https://github.com/erlang/otp/blob/master/lib/stdlib/src/erl_internal.erl#L22&lt;/a&gt; &lt;code&gt;stdlib/erl_internal&lt;/code&gt; here is just a BIF-proxy because all the functions are implemented natively in C inside the ERTS/BEAM.&lt;/p&gt; 
&lt;p&gt;Core C implementation of BIFs &lt;a href=&quot;https://github.com/erlang/otp/blob/master/erts/emulator/beam/bif.c#L69&quot;&gt;resides here&lt;/a&gt;&lt;/p&gt; 
&lt;h3&gt;Code Purger&lt;/h3&gt; 
&lt;p&gt;The most important parts from the &lt;a href=&quot;https://github.com/erlang/otp/blob/master/erts/preloaded/src/erts_code_purger.erl#L61&quot;&gt;Erlang code purger&lt;/a&gt; such as &lt;code&gt;purge&lt;/code&gt;, &lt;code&gt;soft_purge&lt;/code&gt;, etc.&lt;/p&gt; 
&lt;h3&gt;Standard Library&lt;/h3&gt; 
&lt;p&gt;&lt;a href=&quot;https://github.com/erlang/otp/blob/master/lib/stdlib/src/lists.erl#L20&quot;&gt;Lists module&lt;/a&gt; functionality. Some of the functions such as &lt;code&gt;keyfind/3&lt;/code&gt;, &lt;code&gt;keymember/3&lt;/code&gt;, etc. are implemented as BIFs and defined in a separate &lt;a href=&quot;https://github.com/erlang/otp/blob/master/erts/emulator/beam/erl_bif_lists.c&quot;&gt;C file inside of BEAM&lt;/a&gt;.&lt;/p&gt; 
&lt;h3&gt;Message Passing&lt;/h3&gt; 
&lt;p&gt;Core functionality of the &lt;a href=&quot;https://github.com/erlang/otp/blob/master/erts/emulator/beam/erl_message.c&quot;&gt;Erlang message passing&lt;/a&gt;&lt;/p&gt; 
&lt;h3&gt;Internal BEAM emulator docs:&lt;/h3&gt; 
&lt;p&gt;&lt;a href=&quot;https://github.com/erlang/otp/tree/master/erts/emulator/internal_doc&quot;&gt;https://github.com/erlang/otp/tree/master/erts/emulator/internal_doc&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>ART (Android RunTime)</title>
      <link>https://tedneward.github.io/Research/vms/android/art/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">vms/android/art/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://source.android.com/devices/tech/dalvik/index.html&quot;&gt;Website&lt;/a&gt; (shared with Dalvik) | &lt;a href=&quot;https://source.android.com/devices/tech/dalvik/art.html&quot;&gt;Source&lt;/a&gt; | &lt;a href=&quot;https://en.wikipedia.org/wiki/Android_Runtime&quot;&gt;Wikipedia&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>aamachine</title>
      <link>https://tedneward.github.io/Research/vms/aamachine/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">vms/aamachine/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.linusakesson.net/dialog/aamachine/index.php&quot;&gt;Website&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;It is designed for stories implemented in the Dialog programming language.&lt;/p&gt; 
&lt;p&gt;In a sense, the Å-machine is to Dialog what Glulx is to Inform 7. It eliminates the tight restrictions on story size, and extends the basic functionality with a carefully balanced set of new features. But the Å-machine is designed to run the same stories on everything from 8-bit systems to modern web browsers. Data structures and encodings are economical, and the overall word size has not increased. Large stories are supported, but small stories still have a very compact binary representation.&lt;/p&gt; 
&lt;p&gt;Compared to the Z-machine and Glulx, the Å-machine operates at a higher level of abstraction. This improves performance on vintage hardware, both by making story files smaller, which improves loading times, and by allowing larger chunks of computation to be implemented as native machine code. The downside is that the virtual machine is more tightly coupled to the idiosyncracies of a particular high-level language, in this case Dialog.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>AIR</title>
      <link>https://tedneward.github.io/Research/vms/air/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">vms/air/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://airsdk.harman.com/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/airsdk&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>XCode Instruments</title>
      <link>https://tedneward.github.io/Research/tools/xcode/instruments/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/xcode/instruments/index.html</guid>
      	<description>
	&lt;h2&gt;Articles&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt; &lt;p&gt;[Instruments Tutorial with Swift: Getting Started](&lt;a href=&quot;https://www.raywenderlich.com/16126261-instruments-tutorial-with-swift-ge&quot;&gt;https://www.raywenderlich.com/16126261-instruments-tutorial-with-swift-ge&lt;/a&gt;&amp;gt; tting-started): In this Xcode tutorial, you’ll learn how to use Instruments to profile and debug performance, memory and reference issues in your iOS apps.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://swiftwithmajid.com/2021/01/20/profiling-swiftui-app-using-instruments/&quot;&gt;Profiling SwiftUI app using Instruments&lt;/a&gt;: Xcode comes with a bunch of tools you need to build, debug and release your apps. One of these tools is the Instruments app. The Instruments app is a great tool for profiling your iOS apps. It provides many profiling templates for debugging Core Data, catching memory leaks, disk read/writes, and much more. This week we will learn how to profile SwiftUI apps using the SwiftUI template.&lt;/p&gt; &lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>XML2RFC</title>
      <link>https://tedneward.github.io/Research/tools/xml2rfc/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/xml2rfc/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://author-tools.ietf.org/&quot;&gt;Website&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;This service allows you to convert an Internet-Draft from one format into another, including rendered outputs. In the background this service uses id2xml, kramdown-rfc, mmark, rst2rfcxml and xml2rfc, chaining them together as needed to deliver the requested conversion.&lt;/p&gt; 
&lt;p&gt;The input must be a valid Internet-Draft in one of the following formats:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;XML as .xml (automatically recognises v3 as defined in RFC 7991 and v2 as defined in RFC 7749)&lt;/li&gt; 
 &lt;li&gt;Markdown as .md or .mkd (kramdown-rfc and mmark dialects are supported)&lt;/li&gt; 
 &lt;li&gt;reStructuredText (RST) as .rst (Author tools uses rst2rfcxml.)&lt;/li&gt; 
 &lt;li&gt;Plain text as .txt&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Zenith</title>
      <link>https://tedneward.github.io/Research/tools/zenith/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/zenith/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/bvaisvil/zenith&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>XCode Playgrounds</title>
      <link>https://tedneward.github.io/Research/tools/xcode/playgrounds/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/xcode/playgrounds/index.html</guid>
      	<description>
	&lt;h2&gt;&lt;a href=&quot;https://stackoverflow.com/questions/39078307/is-it-possible-to-load-a-storyboard-in-an-ios-playground&quot;&gt;Playgrounds loading Storyboards&lt;/a&gt;&lt;/h2&gt; 
&lt;ol&gt; 
 &lt;li&gt; &lt;p&gt;Compile the storyboard using&lt;/p&gt; &lt;pre&gt;&lt;code&gt;ibtool --compile MainMenu.storyboardc MainMenu.storyboard
&lt;/code&gt;&lt;/pre&gt; &lt;p&gt;(Note the &quot;c&quot; at the end of the .storyboard filename is NOT a typo.)&lt;/p&gt; &lt;p&gt;May need to specify module name using --module flag when compiling. Otherwise, your outlets may cause a runtime error. For the playground book, the module name is Book_Sources. For your own playground, the module name is [Playground name]_Sources. Note I didn&apos;t find any of this in Apple&apos;s documentation, so it is subject to change. The final command looks like this:&lt;/p&gt; &lt;pre&gt;&lt;code&gt;ibtool --compile MainMenu.storyboardc MainMenu.storyboard --module Book_Sources
&lt;/code&gt;&lt;/pre&gt; &lt;p&gt;(When I tried this on 11 Apr 2022, it worked w/o the module flag.)&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Place the compiled storyboardc file in the Resources folder of the playground, not the Sources folder&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Instantiate it in the Playground and set the instantiated ViewController to be the one loaded by the Playground:&lt;/p&gt; &lt;pre&gt;&lt;code&gt;let storyboard = UIStoryboard(name: &quot;Main&quot;, bundle: Bundle.main)
PlaygroundPage.current.liveView = storyboard.instantiateInitialViewController()
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
&lt;/ol&gt;
	</description>
    </item>
    <item>
      <title>Xtext</title>
      <link>https://tedneward.github.io/Research/tools/xtext/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/xtext/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.eclipse.org/Xtext/index.html&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/eclipse/xtext&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Zola</title>
      <link>https://tedneward.github.io/Research/tools/zola/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/zola/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.getzola.org/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/getzola/zola&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>XCodebuild (XCode build system)</title>
      <link>https://tedneward.github.io/Research/tools/xcode/xcodebuild/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/xcode/xcodebuild/index.html</guid>
      	<description>
	&lt;ul&gt; 
 &lt;li&gt;xcbuild-debugging-tricks 
  &lt;ul&gt; 
   &lt;li&gt;Xcode new build system debugging tricks&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://gist.github.com/ddunbar/2dda0e836c855ea96759d1d05f086d69&quot;&gt;https://gist.github.com/ddunbar/2dda0e836c855ea96759d1d05f086d69&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://XcodeBuildSettings.com&quot;&gt;https://XcodeBuildSettings.com&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Yaak</title>
      <link>https://tedneward.github.io/Research/tools/yaak/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/yaak/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://yaak.app/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/yaakapp&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Handy import/export to cURL, among other tools.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>XMake</title>
      <link>https://tedneward.github.io/Research/tools/xmake/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/xmake/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://xmake.io/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/xmake-io/xmake/&quot;&gt;Github&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>yUML</title>
      <link>https://tedneward.github.io/Research/tools/yuml/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/yuml/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://yuml.me/&quot;&gt;Website&lt;/a&gt; | Commercial? Has a Python package though? (&lt;code&gt;pip install https://github.com/wandernauta/yuml/zipball/master&lt;/code&gt;)&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Visual Studio Code</title>
      <link>https://tedneward.github.io/Research/tools/vscode/index/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/vscode/index/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/Microsoft/vscode&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://vscodium.com/&quot;&gt;VSCodium&lt;/a&gt;: a community-driven, freely-licensed binary distribution of Microsoft’s editor VS Code. &quot;The VSCodium project exists so that you don’t have to download+build from source. This project includes special build scripts that clone Microsoft’s vscode repo, run the build commands, and upload the resulting binaries for you to GitHub releases. These binaries are licensed under the MIT license. Telemetry is disabled.&quot;&lt;/p&gt; 
&lt;h2&gt;Resources&lt;/h2&gt; 
&lt;h3&gt;Projects&lt;/h3&gt; 
&lt;p&gt;&lt;a href=&quot;https://github.com/coder/code-server&quot;&gt;code-server&lt;/a&gt;: VS Code in the browser. Part of &lt;a href=&quot;https://coder.com/&quot;&gt;coder.com&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Wiki.js</title>
      <link>https://tedneward.github.io/Research/tools/wikijs/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/wikijs/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://js.wiki/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/Requarks/wiki&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Wireit</title>
      <link>https://tedneward.github.io/Research/tools/wireit/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/wireit/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/google/wireit&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Sapphire (Ruby in Steel)</title>
      <link>https://tedneward.github.io/Research/tools/visualstudio/sapphire/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/visualstudio/sapphire/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;http://www.sapphiresteel.com/Products/Ruby-In-Steel/Ruby-In-Steel-Developer-Overview.html&quot;&gt;Website&lt;/a&gt; | Commercial&lt;/p&gt; 
&lt;p&gt;Mentions VS 2010, 2012, 2013, nothing later than that.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Wasm-tools</title>
      <link>https://tedneward.github.io/Research/tools/wasm-tools/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/wasm-tools/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/bytecodealliance/wasm-tools&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;h1&gt;Installation&lt;/h1&gt; 
&lt;p&gt;Installation can be confirmed with:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;$ wasm-tools --version
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Subcommands can be explored with:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;$ wasm-tools help
&lt;/code&gt;&lt;/pre&gt; 
&lt;h1&gt;Examples&lt;/h1&gt; 
&lt;p&gt;Basic validation/printing/parsing:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;# Validate a WebAssembly file
$ wasm-tools validate foo.wasm

# Validate a WebAssembly module in the text format, automatically converting to
# binary.
$ wasm-tools validate foo.wat

# Validate a WebAssembly file enabling an off-by-default feature
$ wasm-tools validate foo.wasm --features=exception-handling

# Validate a WebAssembly file with a default-enabled feature disabled
$ wasm-tools validate foo.wasm --features=-simd

# Print the text format of a module to stdout
$ wasm-tools print foo.wasm

# Convert a binary module to text
$ wasm-tools print foo.wasm -o foo.wat

# Convert a text module to binary
$ wasm-tools parse foo.wat -o foo.wasm
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Simple mutation as well as piping commands together:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;# Mutate a WebAssembly module and print its text representation to stdout
$ wasm-tools mutate foo.wasm -t

# Mutate a WebAssembly module with a non-default seed and validate that the
# output is a valid module.
$ wasm-tools mutate foo.wasm --seed 192 | wasm-tools validate

# Demangle Rust/C++ symbol names in the `name` section, strip all other custom
# sections, and then print out what binary sections remain.
$ wasm-tools demangle foo.wasm | wasm-tools strip | wasm-tools objdump
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Working with components:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;# Print the WIT interface of a component
$ wasm-tools component wit component.wasm

# Convert WIT text files to a binary-encoded WIT package, printing the result to
# stdout
$ wasm-tools component wit ./wit -t

# Convert a WIT document to JSON
$ wasm-tools component wit ./wit --json

# Round trip WIT through the binary-encoded format to stdout.
$ wasm-tools component wit ./wit --wasm | wasm-tools component wit

# Convert a core WebAssembly binary into a component. Note that this requires
# WIT metadata having previously been embedded in the core wasm module.
$ wasm-tools component new my-core.wasm -o my-component.wasm

# Convert a core WebAssembly binary which uses WASI to a component.
$ wasm-tools component new my-core.wasm -o my-component.wasm --adapt wasi_snapshot_preview1.reactor.wasm
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;CLI Conventions&lt;/h3&gt; 
&lt;p&gt;There are a few conventions that all CLI commands adhere to:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;All subcommands print &quot;short help&quot; with &lt;code&gt;-h&lt;/code&gt; and &quot;long help&quot; with &lt;code&gt;--help&lt;/code&gt;.&lt;/li&gt; 
 &lt;li&gt;Input is by default read from stdin if no file input is specified (when applicable).&lt;/li&gt; 
 &lt;li&gt;Output is by default sent to stdout if a &lt;code&gt;-o&lt;/code&gt; or &lt;code&gt;--output&lt;/code&gt; flag is not provided. Binary WebAssembly is not printed to a tty by default, however.&lt;/li&gt; 
 &lt;li&gt;Commands which output WebAssembly binaries all support a &lt;code&gt;-t&lt;/code&gt; or &lt;code&gt;--wat&lt;/code&gt; flag to generate the WebAssembly text format instead.&lt;/li&gt; 
 &lt;li&gt;A &lt;code&gt;-v&lt;/code&gt; or &lt;code&gt;--verbose&lt;/code&gt; flag can be passed to enable log messages throughout the tooling. Verbosity can be turned up by passing the flag multiple times such as &lt;code&gt;-vvv&lt;/code&gt;.&lt;/li&gt; 
 &lt;li&gt;Color in error messages and console output is enabled by default for TTY based outputs and can be configured with a &lt;code&gt;--color&lt;/code&gt; argument.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h1&gt;Tools included&lt;/h1&gt; 
&lt;p&gt;The &lt;code&gt;wasm-tools&lt;/code&gt; binary internally contains a number of subcommands for working with wasm modules and component. Many subcommands also come with Rust crates that can be use programmatically as well:&lt;/p&gt; 
&lt;table&gt; 
 &lt;thead&gt; 
  &lt;tr&gt;
   &lt;th&gt; CLI &lt;/th&gt;
   &lt;th&gt; Rust Crate &lt;/th&gt;
   &lt;th&gt; Playground &lt;/th&gt;
   &lt;th&gt; Description &lt;/th&gt;
  &lt;/tr&gt; 
 &lt;/thead&gt; 
 &lt;tbody&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;wasm-tools validate&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; &lt;a href=&quot;https://crates.io/crates/wasmparser&quot;&gt;wasmparser&lt;/a&gt; &lt;/td&gt;
   &lt;td&gt; &lt;/td&gt;
   &lt;td&gt; Validate a WebAssembly file &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;wasm-tools parse&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; &lt;a href=&quot;https://crates.io/crates/wat&quot;&gt;wat&lt;/a&gt; and &lt;a href=&quot;https://crates.io/crates/wast&quot;&gt;wast&lt;/a&gt; &lt;/td&gt;
   &lt;td&gt; &lt;a href=&quot;https://bytecodealliance.github.io/wasm-tools/parse&quot;&gt;parse&lt;/a&gt; &lt;/td&gt;
   &lt;td&gt; Translate the WebAssembly text format to binary &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;wasm-tools print&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; &lt;a href=&quot;https://crates.io/crates/wasmprinter&quot;&gt;wasmprinter&lt;/a&gt; &lt;/td&gt;
   &lt;td&gt; &lt;a href=&quot;https://bytecodealliance.github.io/wasm-tools/print&quot;&gt;print&lt;/a&gt; &lt;/td&gt;
   &lt;td&gt; Translate the WebAssembly binary format to text &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;wasm-tools smith&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; &lt;a href=&quot;https://crates.io/crates/wasm-smith&quot;&gt;wasm-smith&lt;/a&gt; &lt;/td&gt;
   &lt;td&gt; &lt;/td&gt;
   &lt;td&gt; Generate a valid WebAssembly module from an input seed &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;wasm-tools mutate&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; &lt;a href=&quot;https://crates.io/crates/wasm-mutate&quot;&gt;wasm-mutate&lt;/a&gt; &lt;/td&gt;
   &lt;td&gt; &lt;/td&gt;
   &lt;td&gt; Mutate an input wasm file into a new valid wasm file &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;wasm-tools shrink&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; &lt;a href=&quot;https://crates.io/crates/wasm-shrink&quot;&gt;wasm-shrink&lt;/a&gt; &lt;/td&gt;
   &lt;td&gt; &lt;/td&gt;
   &lt;td&gt; Shrink a wasm file while preserving a predicate &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;wasm-tools dump&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; &lt;/td&gt;
   &lt;td&gt; &lt;/td&gt;
   &lt;td&gt; Print debugging information about the binary format &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;wasm-tools objdump&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; &lt;/td&gt;
   &lt;td&gt; &lt;/td&gt;
   &lt;td&gt; Print debugging information about section headers &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;wasm-tools strip&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; &lt;/td&gt;
   &lt;td&gt; &lt;/td&gt;
   &lt;td&gt; Remove custom sections from a WebAssembly file &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;wasm-tools demangle&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; &lt;/td&gt;
   &lt;td&gt; &lt;/td&gt;
   &lt;td&gt; Demangle Rust and C++ symbol names in the &lt;code&gt;name&lt;/code&gt; section &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;wasm-tools compose&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; &lt;a href=&quot;https://crates.io/crates/wasm-compose&quot;&gt;wasm-compose&lt;/a&gt; &lt;/td&gt;
   &lt;td&gt; &lt;/td&gt;
   &lt;td&gt; Compose wasm components together (&lt;em&gt;deprecated&lt;/em&gt;) &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;wasm-tools component new&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; &lt;a href=&quot;https://crates.io/crates/wit-component&quot;&gt;wit-component&lt;/a&gt; &lt;/td&gt;
   &lt;td&gt; &lt;/td&gt;
   &lt;td&gt; Create a component from a core wasm binary &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;wasm-tools component wit&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; &lt;/td&gt;
   &lt;td&gt; &lt;/td&gt;
   &lt;td&gt; Extract a &lt;code&gt;*.wit&lt;/code&gt; interface from a component &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;wasm-tools component embed&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; &lt;/td&gt;
   &lt;td&gt; &lt;/td&gt;
   &lt;td&gt; Embed a &lt;code&gt;component-type&lt;/code&gt; custom section in a core wasm binary &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;wasm-tools component unbundle&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; &lt;/td&gt;
   &lt;td&gt; &lt;/td&gt;
   &lt;td&gt; Extract core wasm modules from a component &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;wasm-tools metadata show&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; &lt;a href=&quot;https://crates.io/crates/wasm-metadata&quot;&gt;wasm-metadata&lt;/a&gt; &lt;/td&gt;
   &lt;td&gt; &lt;/td&gt;
   &lt;td&gt; Show name and producer metadata in a component or module &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;wasm-tools metadata add&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; &lt;/td&gt;
   &lt;td&gt; &lt;/td&gt;
   &lt;td&gt; Add name or producer metadata to a component or module &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;wasm-tools addr2line&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; &lt;/td&gt;
   &lt;td&gt; &lt;/td&gt;
   &lt;td&gt; Translate wasm offsets to filename/line numbers with DWARF &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;wasm-tools completion&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; &lt;/td&gt;
   &lt;td&gt; &lt;/td&gt;
   &lt;td&gt; Generate shell completion scripts for &lt;code&gt;wasm-tools&lt;/code&gt; &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;wasm-tools json-from-wast&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; &lt;/td&gt;
   &lt;td&gt; &lt;/td&gt;
   &lt;td&gt; Convert a &lt;code&gt;*.wast&lt;/code&gt; file into JSON commands &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;wasm-tools wast&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; &lt;/td&gt;
   &lt;td&gt; &lt;/td&gt;
   &lt;td&gt; Validate the structure of a &lt;code&gt;*.wast&lt;/code&gt; file &lt;/td&gt;
  &lt;/tr&gt; 
 &lt;/tbody&gt; 
&lt;/table&gt; 
&lt;p&gt;The &lt;code&gt;wasm-tools&lt;/code&gt; CLI contains useful tools for debugging WebAssembly modules and components. The various subcommands all have &lt;code&gt;--help&lt;/code&gt; explainer texts to describe more about their functionality as well.&lt;/p&gt; 
&lt;h1&gt;Language support&lt;/h1&gt; 
&lt;h2&gt;JavaScript Tooling&lt;/h2&gt; 
&lt;p&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/WebAssembly&quot;&gt;WebAssembly&lt;/a&gt; was originally developed as a technology for running non-JavaScript workloads in the browser at near-native speed.&lt;/p&gt; 
&lt;p&gt;JavaScript WebAssembly component model support is provided by a combination of tools:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/bytecodealliance/StarlingMonkey&quot;&gt;StarlingMonkey&lt;/a&gt; a WebAssembly component aware Javascript engine&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/bytecodealliance/componentize-js&quot;&gt;&lt;code&gt;componentize-js&lt;/code&gt;&lt;/a&gt; a tool for building WebAssembly components from Javascript files&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/bytecodealliance/jco&quot;&gt;&lt;code&gt;jco&lt;/code&gt;&lt;/a&gt; a multi-tool for componentizing, type generation, and running components in NodeJS and browser contexts&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;Note that &lt;a href=&quot;https://typescriptlang.org&quot;&gt;Typescript&lt;/a&gt; can &lt;em&gt;also&lt;/em&gt; be used, given that it is transpiled to JS first by relevant tooling (&lt;code&gt;tsc&lt;/code&gt;). &lt;code&gt;jco&lt;/code&gt; generates &lt;a href=&quot;https://www.typescriptlang.org/docs/handbook/declaration-files/deep-dive.html#declaration-file-theory-a-deep-dive&quot;&gt;type declaration files (&lt;code&gt;.d.ts&lt;/code&gt;)&lt;/a&gt; by default, and also has a &lt;code&gt;jco types&lt;/code&gt; subcommand which generates typings that can be used with a Typescript codebase.&lt;/p&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;&lt;a href=&quot;#&quot;&gt;!WARNING&lt;/a&gt;&lt;br&gt; While popular projects like &lt;a href=&quot;https://emscripten.org/&quot;&gt;&lt;code&gt;emscripten&lt;/code&gt;&lt;/a&gt; also build WebAssembly modules, those modules are not Component Model aware.&lt;/p&gt; 
 &lt;p&gt;Core WebAssembly modules do not contain the advanced features (rich types, structured language interoperation, composition) that the component model makes available.&lt;/p&gt; 
&lt;/blockquote&gt; 
&lt;h2&gt;Installing &lt;code&gt;jco&lt;/code&gt;&lt;/h2&gt; 
&lt;p&gt;Installing &lt;a href=&quot;https://github.com/bytecodealliance/jco&quot;&gt;&lt;code&gt;jco&lt;/code&gt;&lt;/a&gt; (which uses &lt;a href=&quot;https://github.com/bytecodealliance/componentize-js&quot;&gt;&lt;code&gt;componentize-js&lt;/code&gt;&lt;/a&gt; can be done via standard NodeJS project tooling:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-console&quot;&gt;npm install -g @bytecodealliance/jco
&lt;/code&gt;&lt;/pre&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;&lt;a href=&quot;#&quot;&gt;!NOTE&lt;/a&gt;&lt;br&gt; &lt;code&gt;jco&lt;/code&gt; and &lt;code&gt;componentize-js&lt;/code&gt; can be installed in a project-local manner with &lt;code&gt;npm install -D&lt;/code&gt;&lt;/p&gt; 
&lt;/blockquote&gt; 
&lt;h2&gt;Overview of Building a Component with JavaScript&lt;/h2&gt; 
&lt;p&gt;Building a WebAssembly component with JavaScript often consists of:&lt;/p&gt; 
&lt;ol&gt; 
 &lt;li&gt;Determining which interface our functionality will target (i.e. a &lt;a href=&quot;https://github.com/WebAssembly/component-model/blob/main/design/mvp/WIT.md&quot;&gt;WebAssembly Interface Types (&quot;WIT&quot;)&lt;/a&gt; world)&lt;/li&gt; 
 &lt;li&gt;Writing JavaScript that satisfies the interface&lt;/li&gt; 
 &lt;li&gt;Compiling the interface-compliant JavaScript to WebAssembly&lt;/li&gt; 
&lt;/ol&gt; 
&lt;h3&gt;What is WIT?&lt;/h3&gt; 
&lt;p&gt;&lt;a href=&quot;https://github.com/WebAssembly/component-model/blob/main/design/mvp/WIT.md&quot;&gt;WebAssembly Interface Types (&quot;WIT&quot;)&lt;/a&gt; is a featureful Interface Definition Language (&quot;IDL&quot;) for defining functionality, but most of the time, you shouldn&apos;t need to write WIT from scratch. Often, it&apos;s sufficient to download a pre-existing interface that defines what your component should do.&lt;/p&gt; 
&lt;p&gt;The &lt;a href=&quot;https://github.com/bytecodealliance/component-docs/tree/main/component-model/examples/tutorial/wit/adder/world.wit&quot;&gt;&lt;code&gt;adder&lt;/code&gt; world&lt;/a&gt; contains an interface with a single &lt;code&gt;add&lt;/code&gt; function that sums two numbers:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-wit&quot;&gt;{{#include ../../exmaples/tutorial/wit/adder/world.wit}}
&lt;/code&gt;&lt;/pre&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;&lt;a href=&quot;#&quot;&gt;!NOTE&lt;/a&gt;&lt;br&gt; &lt;code&gt;export&lt;/code&gt;ing the &lt;code&gt;add&lt;/code&gt; interface means that environments that interact with the resulting WebAssembly component&lt;br&gt; will be able to &lt;em&gt;call&lt;/em&gt; the &lt;code&gt;add&lt;/code&gt; function (fully qualified: &lt;code&gt;docs:adder/add.add@0.1.0&lt;/code&gt;).&lt;/p&gt; 
 &lt;p&gt;To learn more about the WIT syntax, check out the &lt;a href=&quot;https://component-model.bytecodealliance.org/design/wit.html&quot;&gt;WIT explainer&lt;/a&gt;&lt;/p&gt; 
&lt;/blockquote&gt; 
&lt;h2&gt;Implementing a JS WebAssembly Component&lt;/h2&gt; 
&lt;p&gt;To implement the &lt;a href=&quot;https://github.com/bytecodealliance/component-docs/tree/main/component-model/examples/tutorial/wit/adder/world.wit&quot;&gt;&lt;code&gt;adder&lt;/code&gt; world&lt;/a&gt;, we can write a &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules&quot;&gt;JavaScript ES module&lt;/a&gt;:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-js&quot;&gt;export const add = {
    add(x, y) {
        return x + y;
    }
};
&lt;/code&gt;&lt;/pre&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;&lt;a href=&quot;#&quot;&gt;!WARNING&lt;/a&gt;&lt;br&gt; When building your JavaScript project, ensure to set the &lt;code&gt;&quot;type&quot;:&quot;module&quot;&lt;/code&gt; option in &lt;code&gt;package.json&lt;/code&gt;, as &lt;code&gt;jco&lt;/code&gt; works exclusively with JavaScript modules.&lt;/p&gt; 
&lt;/blockquote&gt; 
&lt;p&gt;In the code above:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;The &lt;code&gt;adder&lt;/code&gt; world is analogous to the JavaScript module (file) itself&lt;/li&gt; 
 &lt;li&gt;The exported &lt;code&gt;add&lt;/code&gt; object mirrors the &lt;code&gt;export&lt;/code&gt;ed &lt;code&gt;add&lt;/code&gt; interface in WIT&lt;/li&gt; 
 &lt;li&gt;The &lt;code&gt;add&lt;/code&gt; function mirrors the &lt;code&gt;add&lt;/code&gt; function inside the &lt;code&gt;add&lt;/code&gt; interface&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;With the WIT and JavaScript in place, we can use &lt;a href=&quot;https://github.com/bytecodealliance/jco&quot;&gt;&lt;code&gt;jco&lt;/code&gt;&lt;/a&gt; to create a WebAssembly component from the JS module, using &lt;code&gt;jco componentize&lt;/code&gt;.&lt;/p&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;&lt;a href=&quot;#&quot;&gt;!NOTE&lt;/a&gt;&lt;br&gt; You can also call &lt;code&gt;componentize-js&lt;/code&gt; directly -- it supports both API driven usage and has a CLI.&lt;/p&gt; 
&lt;/blockquote&gt; 
&lt;p&gt;Our component is &lt;em&gt;so simple&lt;/em&gt; (reminiscent of &lt;a href=&quot;https://webassembly.github.io/spec/core/&quot;&gt;Core WebAssembly&lt;/a&gt;, which deals only in numeric values) that we&apos;re actually &lt;em&gt;not using&lt;/em&gt; any of the &lt;a href=&quot;https://wasi.dev/&quot;&gt;WebAssembly System Interface&lt;/a&gt; (access to files, network, etc). This means that we can &lt;code&gt;--disable&lt;/code&gt; all unneeded WASI functionality when we invoke &lt;code&gt;jco componentize&lt;/code&gt;:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-console&quot;&gt;jco componentize \
    --wit path/to/adder/world.wit \
    --world-name example \
    --out adder.wasm \
    --disable all \
    path/to/adder.js
&lt;/code&gt;&lt;/pre&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;&lt;a href=&quot;#&quot;&gt;!NOTE&lt;/a&gt;&lt;br&gt; If you&apos;re using &lt;code&gt;jco&lt;/code&gt; as a project-local dependency, you can run &lt;code&gt;npx jco&lt;/code&gt;&lt;/p&gt; 
&lt;/blockquote&gt; 
&lt;p&gt;You should see output like the following:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;OK Successfully written adder.wasm.
&lt;/code&gt;&lt;/pre&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;&lt;a href=&quot;#&quot;&gt;!WARNING&lt;/a&gt;&lt;br&gt; By using &lt;code&gt;--disable all&lt;/code&gt;, your component won&apos;t get access to any WASI interfaces that might be useful for debugging or logging.&lt;/p&gt; 
 &lt;p&gt;For example, you can&apos;t &lt;code&gt;console.log(...)&lt;/code&gt; or &lt;code&gt;console.error(...)&lt;/code&gt; without &lt;code&gt;stdio&lt;/code&gt;; you can&apos;t use &lt;code&gt;Math.random()&lt;/code&gt; without &lt;code&gt;random&lt;/code&gt;; and you can&apos;t use &lt;code&gt;Date.now()&lt;/code&gt; or &lt;code&gt;new Date()&lt;/code&gt; without &lt;code&gt;clocks&lt;/code&gt;.&lt;/p&gt; 
 &lt;p&gt;Please note that calls to &lt;code&gt;Math.random()&lt;/code&gt; or &lt;code&gt;Date.now()&lt;/code&gt; will return seemingly valid outputs, but without actual randomness or timestamp correctness.&lt;/p&gt; 
&lt;/blockquote&gt; 
&lt;h3&gt;Running the Component in the &lt;code&gt;example-host&lt;/code&gt;&lt;/h3&gt; 
&lt;p&gt;To run the component we&apos;ve built, we can use the &lt;a href=&quot;https://github.com/bytecodealliance/component-docs/tree/main/component-model/examples/example-host&quot;&gt;&lt;code&gt;example-host&lt;/code&gt; project&lt;/a&gt;:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-console&quot;&gt;cd component-model/examples/example-host
cargo run --release -- 1 2 ../path/to/adder.wasm
1 + 2 = 3
&lt;/code&gt;&lt;/pre&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;&lt;a href=&quot;#&quot;&gt;!WARNING&lt;/a&gt;&lt;br&gt; The &lt;a href=&quot;https://github.com/bytecodealliance/component-docs/tree/main/component-model/examples/example-host&quot;&gt;&lt;code&gt;example-host&lt;/code&gt; Rust project&lt;/a&gt; uses the &lt;a href=&quot;https://www.rust-lang.org/tools/install&quot;&gt;Rust toolchain&lt;/a&gt;, in particular &lt;a href=&quot;https://doc.rust-lang.org/cargo&quot;&gt;&lt;code&gt;cargo&lt;/code&gt;&lt;/a&gt;,&lt;br&gt; so to run the code in this section you may need to install some more dependencies (like the Rust toolchain).&lt;/p&gt; 
&lt;/blockquote&gt; 
&lt;p&gt;While the output isn&apos;t exciting, the code contained in &lt;code&gt;example-host&lt;/code&gt; does a lot to make it happen:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Loads the WebAssembly binary at the provided path (in the command above, &lt;code&gt;../path/to/adder.wasm&lt;/code&gt;)&lt;/li&gt; 
 &lt;li&gt;Calls the &lt;code&gt;export&lt;/code&gt;ed &lt;code&gt;add&lt;/code&gt; function inside the &lt;code&gt;add&lt;/code&gt; interface with arguments&lt;/li&gt; 
 &lt;li&gt;Prints the result&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;The important Rust code looks something like this:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-rust&quot;&gt;let component = Component::from_file(&amp;amp;engine, path).context(&quot;Component file not found&quot;)?;

let (instance, _) = Example::instantiate_async(&amp;amp;mut store, &amp;amp;component, &amp;amp;linker)
    .await
    .context(&quot;Failed to instantiate the example world&quot;)?;

instance
    .call_add(&amp;amp;mut store, x, y)
    .await
    .context(&quot;Failed to call add function&quot;)
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;A quick reminder on the power and new capabilities afforded by WebAssembly -- we&apos;ve written, loaded,&lt;br&gt; instantiated and executed JavaScript from Rust with a strict interface, without the need&lt;br&gt; for &lt;a href=&quot;https://en.wikipedia.org/wiki/Foreign_function_interface&quot;&gt;FFI&lt;/a&gt;, subprocesses or a network call.&lt;/p&gt; 
&lt;h3&gt;Running a Component from JavaScript Applications (including the Browser)&lt;/h3&gt; 
&lt;p&gt;While JavaScript runtimes available in browsers can execute WebAssembly core modules, they cannot yet execute WebAssembly &lt;em&gt;components&lt;/em&gt;, so WebAssembly components (JavaScript or otherwise) must be &quot;transpiled&quot; into a JavaScript wrapper and one or more &lt;a href=&quot;https://webassembly.github.io/spec/core/binary/modules.html&quot;&gt;WebAssembly core modules&lt;/a&gt; which &lt;em&gt;can&lt;/em&gt; be run by available WebAssembly engines.&lt;/p&gt; 
&lt;p&gt;Given an existing WebAssembly component (e.g. &lt;code&gt;adder.wasm&lt;/code&gt; which implements the &lt;a href=&quot;https://github.com/bytecodealliance/component-docs/tree/main/component-model/examples/tutorial/wit/adder/world.wit&quot;&gt;&lt;code&gt;adder&lt;/code&gt; world&lt;/a&gt;), we can &quot;transpile&quot; the WebAssembly component into runnable JavaScript by using &lt;code&gt;jco transpile&lt;/code&gt;:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-console&quot;&gt;jco transpile adder.wasm -o dist/transpiled
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;You should see output similar to the following:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;  Transpiled JS Component Files:

 - dist/transpiled/adder.core.wasm                   10.1 MiB
 - dist/transpiled/adder.d.ts                         0.1 KiB
 - dist/transpiled/adder.js                          1.57 KiB
&lt;/code&gt;&lt;/pre&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;&lt;a href=&quot;#&quot;&gt;!NOTE&lt;/a&gt;&lt;br&gt; To follow along, see the &lt;a href=&quot;https://github.com/bytecodealliance/jco/tree/main/examples/components/adder&quot;&gt;&lt;code&gt;jco&lt;/code&gt; example &lt;code&gt;adder&lt;/code&gt; component&lt;/a&gt;.&lt;/p&gt; 
 &lt;p&gt;With the project pulled locally, you also run &lt;code&gt;npm run transpile&lt;/code&gt; which outputs to &lt;code&gt;dist/transpiled&lt;/code&gt;&lt;/p&gt; 
&lt;/blockquote&gt; 
&lt;p&gt;Thanks to &lt;code&gt;jco&lt;/code&gt; transpilation, you can import the resulting &lt;code&gt;dist/transpiled/adder.js&lt;/code&gt; file and run it from any JavaScript application using a runtime that supports the &lt;a href=&quot;https://webassembly.github.io/spec/core/&quot;&gt;core WebAssembly specification&lt;/a&gt; as implemented for JavaScript.&lt;/p&gt; 
&lt;p&gt;To use this component from &lt;a href=&quot;https://nodejs.org/en&quot;&gt;NodeJS&lt;/a&gt;, you can write code like the following:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-mjs&quot;&gt;import { add } from &quot;./dist/transpiled/adder.js&quot;;

console.log(&quot;1 + 2 = &quot; + add(1, 2));
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;You can execute the JavaScript module with &lt;code&gt;node&lt;/code&gt; directly:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-console&quot;&gt;node run.js
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;You should see output like the following:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;1 + 2 = 3
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;This is directly comparable to the Rust host code mentioned in the previous section. Here, we are able to use NodeJS as a host for running WebAssembly, thanks to &lt;code&gt;jco&lt;/code&gt;&apos;s ability to transpile components.&lt;/p&gt; 
&lt;p&gt;With &lt;code&gt;jco transpile&lt;/code&gt; any WebAssembly binary (compiled from any language) can be run in JavaScript natively.&lt;/p&gt; 
&lt;h3&gt;Building Reactor Components with &lt;code&gt;jco&lt;/code&gt;&lt;/h3&gt; 
&lt;p&gt;Reactor components are WebAssembly components that are long running and meant to be called repeatedly over time. They&apos;re analogous to libraries of functionality rather than an executable (a &quot;command&quot; component).&lt;/p&gt; 
&lt;p&gt;Components expose their interfaces via &lt;a href=&quot;../design/wit.md&quot;&gt;WebAssembly Interface Types&lt;/a&gt;, hand-in-hand with the &lt;a href=&quot;../design/why-component-model.md&quot;&gt;Component Model&lt;/a&gt; which enables components to use higher level types interchangeably.&lt;/p&gt; 
&lt;h4&gt;Exporting WIT Interfaces with &lt;code&gt;jco&lt;/code&gt;&lt;/h4&gt; 
&lt;p&gt;Packaging reusable functionality into WebAssembly components isn&apos;t useful if we have no way to &lt;em&gt;expose&lt;/em&gt; that functionality.&lt;/p&gt; 
&lt;p&gt;This section offers a slightly deeper dive into the usage of WIT in WebAssembly components that can use the Component Model.&lt;/p&gt; 
&lt;p&gt;As in the previous example, &lt;code&gt;export&lt;/code&gt;ing WIT interfaces for other components (or a WebAssembly host) to use is fundamental to developing WebAssembly programs.&lt;/p&gt; 
&lt;p&gt;Let&apos;s examine a &lt;a href=&quot;https://github.com/bytecodealliance/jco/tree/main/examples/components/string-reverse&quot;&gt;&lt;code&gt;jco&lt;/code&gt; example project called &lt;code&gt;string-reverse&lt;/code&gt;&lt;/a&gt; that exposes functionality for reversing a string.&lt;/p&gt; 
&lt;p&gt;To build a project like &lt;code&gt;string-reverse&lt;/code&gt; from the ground up, first we&apos;d start with a WIT like the following:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-wit&quot;&gt;package example:string-reverse@0.1.0

@since(version = 0.1.0)
interface reverse {
    reverse-string: func(s: string) -&amp;gt; string;
}

world string-reverse {
    export reverse;
}
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;As a slightly deeper crash course on &lt;a href=&quot;https://github.com/WebAssembly/component-model/blob/main/design/mvp/WIT.md&quot;&gt;WIT&lt;/a&gt;, here&apos;s what the above code describes:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;We&apos;ve defined a namespace called &lt;code&gt;example&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;We&apos;ve defined a package called &lt;code&gt;string-reverse&lt;/code&gt; inside the &lt;code&gt;example&lt;/code&gt; namespace&lt;/li&gt; 
 &lt;li&gt;This WIT file corresponds to version &lt;code&gt;0.1.0&lt;/code&gt; of &lt;code&gt;example:string-reverse&lt;/code&gt; package&lt;/li&gt; 
 &lt;li&gt;We&apos;ve defined an interface called &lt;code&gt;reverse&lt;/code&gt; which contains &lt;em&gt;one&lt;/em&gt; function called &lt;code&gt;reverse-string&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;We specify that the &lt;code&gt;reverse&lt;/code&gt; interface has existed &lt;em&gt;since&lt;/em&gt; the &lt;code&gt;0.1.0&lt;/code&gt; version&lt;/li&gt; 
 &lt;li&gt;The &lt;code&gt;reverse-string&lt;/code&gt; function (AKA. &lt;code&gt;example:reverse-string/reverse.reverse-string&lt;/code&gt;) takes a string and returns a string&lt;/li&gt; 
 &lt;li&gt;We&apos;ve defined a &lt;code&gt;world&lt;/code&gt; called &lt;code&gt;string-reverse&lt;/code&gt; which exports the functionality provided by the &lt;code&gt;reverse&lt;/code&gt; interface&lt;/li&gt; 
&lt;/ul&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;&lt;a href=&quot;#&quot;&gt;!WARNING&lt;/a&gt;&lt;br&gt; How do we &lt;em&gt;know&lt;/em&gt; that &lt;code&gt;reverse&lt;/code&gt; actually reverses a string?&lt;/p&gt; 
 &lt;p&gt;Unfortunately, that problem is not really solvable at this level -- this is between you and the writer of the component that implements the WIT interface.&lt;/p&gt; 
 &lt;p&gt;Of course, with WebAssembly, you &lt;em&gt;can&lt;/em&gt; enforce static checks if you&apos;re so inclined, &lt;em&gt;before&lt;/em&gt; you run any given binary.&lt;/p&gt; 
&lt;/blockquote&gt; 
&lt;p&gt;OK now let&apos;s see what the JS code looks like to &lt;em&gt;implement&lt;/em&gt; the &lt;code&gt;component&lt;/code&gt; world:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-js&quot;&gt;/**
 * This module is the JS implementation of the `string-reverse` WIT world
 */

/**
 * This JavaScript will be interpreted by `jco` and turned into a
 * WebAssembly binary with a single export (this `reverse` function).
 */
function reverseString(s) {
  return s.reverse();
}

/**
 * The JavaScript export below represents the export of the `reverse` interface,
 * which which contains `reverse-string` as it&apos;s primary exported function.
 */
export const reverse = {
    reverseString,
};
&lt;/code&gt;&lt;/pre&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;&lt;a href=&quot;#&quot;&gt;!NOTE&lt;/a&gt;&lt;br&gt; To view the full code listing along with instructions, see the &lt;a href=&quot;https://github.com/bytecodealliance/jco/tree/main/examples/components/string-reverse&quot;&gt;&lt;code&gt;examples/tutorials/jco/string-reverse&lt;/code&gt; folder&lt;/a&gt;&lt;/p&gt; 
&lt;/blockquote&gt; 
&lt;p&gt;To use &lt;code&gt;jco&lt;/code&gt; to compile this component, you can run the following from the &lt;code&gt;string-reverse&lt;/code&gt; folder:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-console&quot;&gt;npx jco componentize \
    --wit wit/component.wit \
    --world-name component \
    --out string-reverse.wasm \
    --disable all \
    string-reverse.mjs
&lt;/code&gt;&lt;/pre&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;&lt;a href=&quot;#&quot;&gt;!NOTE&lt;/a&gt;&lt;br&gt; Like the previous example, we&apos;re not using any of the advanced &lt;a href=&quot;https://wasi.dev/&quot;&gt;WebAssembly System Interface&lt;/a&gt; features, so we &lt;code&gt;--disable&lt;/code&gt; all of them&lt;/p&gt; 
 &lt;p&gt;Rather than typing out the &lt;code&gt;jco componentize&lt;/code&gt; command manually, you can also run&lt;br&gt; the build command with &lt;a href=&quot;https://github.com/bytecodealliance/jco/blob/main/examples/components/string-reverse/package.json#L6&quot;&gt;&lt;code&gt;npm run build&lt;/code&gt; from the &lt;code&gt;string-reverse&lt;/code&gt; folder&lt;/a&gt;.&lt;/p&gt; 
&lt;/blockquote&gt; 
&lt;p&gt;You should see output like the following:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;OK Successfully written string-reverse.wasm.
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Now that we have a WebAssembly binary, we can &lt;em&gt;also&lt;/em&gt; use &lt;code&gt;jco&lt;/code&gt; to run it in a native JavaScript context by &lt;em&gt;transpiling&lt;/em&gt; the WebAssembly binary (which could have come from anywhere!) to a JavaScript module.&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-console&quot;&gt;npx jco transpile string-reverse.wasm -o dist/transpiled
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;You should see the following output:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;  Transpiled JS Component Files:

 - dist/transpiled/interfaces/example-string-reverse-reverse.d.ts   0.1 KiB
 - dist/transpiled/string-reverse.core.wasm                        10.1 MiB
 - dist/transpiled/string-reverse.d.ts                             0.15 KiB
 - dist/transpiled/string-reverse.js                               2.55 KiB
&lt;/code&gt;&lt;/pre&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;&lt;a href=&quot;#&quot;&gt;!TIP&lt;/a&gt;&lt;br&gt; A gentle reminder that, transpilation &lt;em&gt;does&lt;/em&gt; produce &lt;a href=&quot;https://www.typescriptlang.org/docs/handbook/declaration-files/deep-dive.html#declaration-file-theory-a-deep-dive&quot;&gt;Typescript declaration file&lt;/a&gt;, for use in Typescript projects.&lt;/p&gt; 
&lt;/blockquote&gt; 
&lt;p&gt;Now that we have a transpiled module, we can run it from any JavaScript context that supports core WebAssembly (whether NodeJS or the browser).&lt;/p&gt; 
&lt;p&gt;For NodeJS, we can use code like the following:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-mjs&quot;&gt;// If this import listed below is missing, please run `npm run transpile`
import { reverse } from &quot;./dist/transpiled/string-reverse.mjs&quot;;

const reversed = reverse.reverseString(&quot;!dlroW olleH&quot;);

console.log(`reverseString(&apos;!dlroW olleH&apos;) = ${reversed}`);
&lt;/code&gt;&lt;/pre&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;&lt;a href=&quot;#&quot;&gt;!NOTE&lt;/a&gt;&lt;br&gt; In the &lt;code&gt;jco&lt;/code&gt; example project, you can run &lt;code&gt;npm run transpiled-js&lt;/code&gt; to build the existing code.&lt;/p&gt; 
&lt;/blockquote&gt; 
&lt;p&gt;Assuming you have the &lt;code&gt;dist/transpiled&lt;/code&gt; folder populated (by running &lt;code&gt;jco transpile&lt;/code&gt; in the previous step), you should see output like the following:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;reverseString(&apos;!dlrow olleh&apos;) = hello world!
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;While it&apos;s somewhat redundant in this context, what we&apos;ve done from NodeJS demonstrates the usefulness of WebAssembly and the &lt;code&gt;jco&lt;/code&gt; toolchain. With the help of &lt;code&gt;jco&lt;/code&gt;, we have:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Compiled JavaScript to a WebAssembly module (&lt;code&gt;jco compile&lt;/code&gt;), adhering to an interface defined via WIT&lt;/li&gt; 
 &lt;li&gt;Converted the compiled WebAssembly module (which could be from &lt;em&gt;any&lt;/em&gt; language) to a module that can be used from any compliant JS runtime (&lt;code&gt;jco transpile&lt;/code&gt;)&lt;/li&gt; 
 &lt;li&gt;Run the transpiled WebAssembly component from a JavaScript native runtime (NodeJS)&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Advanced: Importing and Reusing WIT Interfaces via Composition&lt;/h4&gt; 
&lt;p&gt;Just as &lt;code&gt;export&lt;/code&gt;ing functionality is core to building useful WebAssembly components, and similarly &lt;code&gt;import&lt;/code&gt;ing and reusing functionality is key to using the strengths of WebAssembly.&lt;/p&gt; 
&lt;p&gt;Restated, &lt;strong&gt;WIT and the Component Model enable WebAssembly to &lt;em&gt;compose&lt;/em&gt;&lt;/strong&gt;. This means we can build on top of functionality that already exists and &lt;code&gt;export&lt;/code&gt; &lt;em&gt;new&lt;/em&gt; functionality that depends on existing functionality.&lt;/p&gt; 
&lt;p&gt;Let&apos;s say in addition to the reversing the string (in the previous example) we want to build shared functionality that &lt;em&gt;also&lt;/em&gt; upper cases the text it receives.&lt;/p&gt; 
&lt;p&gt;We can reuse the reversing functionality &lt;em&gt;and&lt;/em&gt; export a new interface which enables us to reverse and upper-case.&lt;/p&gt; 
&lt;p&gt;Let&apos;s examine a &lt;a href=&quot;https://github.com/bytecodealliance/jco/tree/main/examples/components/string-reverse-upper&quot;&gt;&lt;code&gt;jco&lt;/code&gt; example project called &lt;code&gt;string-reverse-upper&lt;/code&gt;&lt;/a&gt; that exposes functionality for reversing &lt;em&gt;and&lt;/em&gt; upper-casing a string.&lt;/p&gt; 
&lt;p&gt;Here&apos;s the WIT one might write to enable this functionality:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-wit&quot;&gt;package example:string-reverse-upper@0.1.0;

@since(version = 0.1.0)
interface reversed-upper {
    reverse-and-uppercase: func(s: string) -&amp;gt; string;
}

world revup {
    //
    // NOTE, the import below translates to:
    // &amp;lt;namespace&amp;gt;:&amp;lt;package&amp;gt;/&amp;lt;interface&amp;gt;@&amp;lt;package version&amp;gt;
    //
    import example:string-reverse/reverse@0.1.0;

    export reversed-upper;
}
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;This time, the &lt;code&gt;world&lt;/code&gt; named &lt;code&gt;revup&lt;/code&gt; that we are building &lt;em&gt;relies&lt;/em&gt; on the interface &lt;code&gt;reverse&lt;/code&gt; in the package &lt;code&gt;string-reverse&lt;/code&gt; from the namespace &lt;code&gt;example&lt;/code&gt;.&lt;/p&gt; 
&lt;p&gt;We can make use of &lt;em&gt;any&lt;/em&gt; WebAssembly component that matches that interface, as long as we &lt;em&gt;compose&lt;/em&gt; their functionality with the component that implements the &lt;code&gt;revup&lt;/code&gt; world.&lt;/p&gt; 
&lt;p&gt;The &lt;code&gt;revup&lt;/code&gt; world &lt;code&gt;import&lt;/code&gt;s (and makes use) of &lt;code&gt;reverse&lt;/code&gt; in order to &lt;code&gt;export&lt;/code&gt; (provide) the &lt;code&gt;reversed-upper&lt;/code&gt; interface, which contains the &lt;code&gt;reverse-and-uppercase&lt;/code&gt; function (in JS, &lt;code&gt;reverseAndUppercase&lt;/code&gt;).&lt;/p&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;&lt;a href=&quot;#&quot;&gt;!NOTE&lt;/a&gt;&lt;br&gt; Functionality is imported via the &lt;code&gt;interface&lt;/code&gt;, &lt;em&gt;not&lt;/em&gt; the &lt;code&gt;world&lt;/code&gt;. &lt;code&gt;world&lt;/code&gt;s can be included/used, but the syntax is slightly different for that.&lt;/p&gt; 
&lt;/blockquote&gt; 
&lt;p&gt;The JavaScript to make this work (&lt;a href=&quot;https://github.com/bytecodealliance/jco/blob/main/examples/components/string-reverse-upper/string-reverse-upper.mjs&quot;&gt;&lt;code&gt;string-reverse-upper.mjs&lt;/code&gt; in &lt;code&gt;jco/examples&lt;/code&gt;&lt;/a&gt;) looks like this:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-js&quot;&gt;/**
 * This module is the JS implementation of the `revup` WIT world
 */

/**
 * The import here is *virtual*. It refers to the `import`ed `reverse` interface in component.wit.
 *
 * These types *do not resolve* when the first `string-reverse-upper` component is built,
 * but the types are relevant for the resulting *composed* component.
 */
import { reverseString } from &apos;example:string-reverse/reverse@0.1.0&apos;;

/**
 * The JavaScript export below represents the export of the `reversed-upper` interface,
 * which which contains `revup` as it&apos;s primary exported function.
 */
export const reversedUpper = {
  /**
   * Represents the implementation of the `reverse-and-uppercase` function in the `reversed-upper` interface
   *
   * This function makes use of `reverse-string` which is *imported* from another WebAssembly binary.
   */
  reverseAndUppercase() {
    return reverseString(s).toLocaleUpperCase();
  },
};
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;We can build the component with &lt;code&gt;jco componentize&lt;/code&gt;:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-console&quot;&gt;npx jco componentize \
    string-reverse-upper.mjs \
    --wit wit/ \
    --world-name revup \
    --out string-reverse-upper.incomplete.wasm \
    --disable all
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;While we&apos;ve successfully built a WebAssembly component, unlike the other examples, ours is &lt;em&gt;not yet complete&lt;/em&gt;.&lt;/p&gt; 
&lt;p&gt;We can see that if we print the WIT of the generated component by running &lt;code&gt;jco wit&lt;/code&gt;:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-console&quot;&gt;npx jco wit string-reverse-upper.incomplete.wasm
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;You should see output like the following:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;package root:component;

world root {
  import example:string-reverse/reverse@0.1.0;

  export example:string-reverse-upper/reversed-upper@0.1.0;
}
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;This tells us that the component still has &lt;em&gt;unfulfilled &lt;code&gt;import&lt;/code&gt;s&lt;/em&gt; -- we &lt;em&gt;use&lt;/em&gt; the &lt;code&gt;reverseString&lt;/code&gt; function that&apos;s in &lt;code&gt;reverse&lt;/code&gt; as if it exists, but it&apos;s not yet a real part of the WebAssembly component (hence we&apos;ve named it &lt;code&gt;.incomplete.wasm&lt;/code&gt;.&lt;/p&gt; 
&lt;p&gt;To compose the two components (&lt;code&gt;string-reverse-upper/string-reverse-upper.incomplete.wasm&lt;/code&gt; and &lt;code&gt;string-reverse/string-reverse.wasm&lt;/code&gt; we built earlier), we&apos;ll need the &lt;a href=&quot;https://github.com/bytecodealliance/wac&quot;&gt;WebAssembly Composition tool (&lt;code&gt;wac&lt;/code&gt;)&lt;/a&gt;. We can use &lt;code&gt;wac plug&lt;/code&gt;:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-console&quot;&gt;wac plug \
    -o string-reverse-upper.wasm \
    --plug ../string-reverse/string-reverse.wasm \
    string-reverse-upper.incomplete.wasm
&lt;/code&gt;&lt;/pre&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;&lt;a href=&quot;#&quot;&gt;!NOTE&lt;/a&gt;&lt;br&gt; You can also run this step with &lt;code&gt;npm run compose&lt;/code&gt;.&lt;/p&gt; 
&lt;/blockquote&gt; 
&lt;p&gt;A new component &lt;code&gt;string-reverse-upper.wasm&lt;/code&gt; should now be present, which is a &quot;complete&quot; component -- we can check the output of &lt;code&gt;jco wit&lt;/code&gt; to ensure that all the imports are satisfied:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-wit&quot;&gt;package root:component;

world root {
  export example:string-reverse-upper/reversed-upper@0.1.0;
}
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;It&apos;s as-if we never imported any functionality at all -- the functionality present in &lt;code&gt;string-reverse.wasm&lt;/code&gt; has been &lt;em&gt;merged into&lt;/em&gt; &lt;code&gt;string-reverse-upper.wasm&lt;/code&gt;, and it now simply &lt;code&gt;export&lt;/code&gt;s the advanced functionality.&lt;/p&gt; 
&lt;p&gt;We can run this completed component with in any WebAssembly-capable native JavaScript environment by using a the transpiled result:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-console&quot;&gt;npx jco transpile string-reverse-upper.wasm -o dist/transpiled
&lt;/code&gt;&lt;/pre&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;&lt;a href=&quot;#&quot;&gt;!NOTE&lt;/a&gt;&lt;br&gt; In the example project, you can run &lt;code&gt;npm run transpile&lt;/code&gt; instead, which will also change the extension on &lt;code&gt;dist/transpiled/string-reverse-upper.js&lt;/code&gt; to &lt;code&gt;.mjs&lt;/code&gt;&lt;/p&gt; 
&lt;/blockquote&gt; 
&lt;p&gt;You should see output like the following:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;  Transpiled JS Component Files:

 - dist/transpiled/interfaces/example-string-reverse-upper-reversed-upper.d.ts  0.12 KiB
 - dist/transpiled/string-reverse-upper.core.wasm                               10.1 MiB
 - dist/transpiled/string-reverse-upper.core2.wasm                              10.1 MiB
 - dist/transpiled/string-reverse-upper.d.ts                                    0.19 KiB
 - dist/transpiled/string-reverse-upper.js                                      6.13 KiB
&lt;/code&gt;&lt;/pre&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;&lt;a href=&quot;#&quot;&gt;!TIP&lt;/a&gt;&lt;br&gt; Notice that there are &lt;em&gt;two&lt;/em&gt; core WebAssembly files? That&apos;s because two core WebAssembly modules were involved&lt;br&gt; in creating the ultimate functionality we needed.&lt;/p&gt; 
&lt;/blockquote&gt; 
&lt;p&gt;To run the transpiled component, we can write code like the following:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-mjs&quot;&gt;/**
 * If this import listed below is missing, please run
 *
 * ```
 * npm run build &amp;amp;&amp;amp; npm run compose &amp;amp;&amp;amp; npm run transpile`
 * ```
 */
import { reversedUpper } from &quot;./dist/transpiled/string-reverse-upper.mjs&quot;;

const result = reversedUpper.reverseAndUppercase(&quot;!dlroW olleH&quot;);

console.log(`reverseAndUppercase(&apos;!dlroW olleH&apos;) = ${result}`);
&lt;/code&gt;&lt;/pre&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;&lt;a href=&quot;#&quot;&gt;!NOTE&lt;/a&gt;&lt;br&gt; In the &lt;a href=&quot;https://github.com/bytecodealliance/jco/tree/main/examples/components/string-reverse-upper&quot;&gt;&lt;code&gt;jco&lt;/code&gt; example project&lt;/a&gt;, you can run &lt;code&gt;npm run transpiled-js&lt;/code&gt;&lt;/p&gt; 
&lt;/blockquote&gt; 
&lt;p&gt;You should see output like the following:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;reverseAndUppercase(&apos;!dlroW olleH&apos;) = HELLO WORLD!
&lt;/code&gt;&lt;/pre&gt; 
&lt;h2&gt;C/C++ Tooling&lt;/h2&gt; 
&lt;p&gt;WebAssembly components can be built from C and C++ using &lt;a href=&quot;https://clang.llvm.org/&quot;&gt;&lt;code&gt;clang&lt;/code&gt;&lt;/a&gt;, the C language family frontend for &lt;a href=&quot;https://llvm.org/&quot;&gt;LLVM&lt;/a&gt;.&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://github.com/bytecodealliance/wit-bindgen&quot;&gt;&lt;code&gt;wit-bindgen&lt;/code&gt;&lt;/a&gt; is a tool to generate guest language bindings from a&lt;br&gt; given &lt;code&gt;.wit&lt;/code&gt; file.&lt;/p&gt; 
&lt;p&gt;Although &lt;code&gt;wit-bindgen&lt;/code&gt; is a standalone tool (whereas some languages have more integrated toolchains like Rust&apos;s &lt;a href=&quot;https://crates.io/crates/cargo-component&quot;&gt;&lt;code&gt;cargo-component&lt;/code&gt;&lt;/a&gt;),&lt;br&gt; &lt;code&gt;wit-bindgen&lt;/code&gt; can generate source-level bindings for &lt;code&gt;Rust&lt;/code&gt;, &lt;code&gt;C&lt;/code&gt;, &lt;code&gt;Java (TeaVM)&lt;/code&gt;, and &lt;code&gt;TinyGo&lt;/code&gt;, with the ability for more&lt;br&gt; language generators to be added in the future.&lt;/p&gt; 
&lt;p&gt;&lt;code&gt;wit-bindgen&lt;/code&gt; can be used to build C applications that can be compiled directly to Wasm modules using &lt;a href=&quot;https://clang.llvm.org/&quot;&gt;&lt;code&gt;clang&lt;/code&gt;&lt;/a&gt; with a &lt;a href=&quot;https://clang.llvm.org/docs/ClangCommandLineReference.html#webassembly&quot;&gt;&lt;code&gt;wasm32-wasi&lt;/code&gt;&lt;/a&gt; target.&lt;/p&gt; 
&lt;h3&gt;1. Download dependencies&lt;/h3&gt; 
&lt;p&gt;First, install the CLI for &lt;a href=&quot;https://github.com/bytecodealliance/wit-bindgen#cli-installation&quot;&gt;&lt;code&gt;wit-bindgen&lt;/code&gt;&lt;/a&gt;, &lt;a href=&quot;https://github.com/bytecodealliance/wasm-tools&quot;&gt;&lt;code&gt;wasm-tools&lt;/code&gt;&lt;/a&gt;, and the &lt;a href=&quot;https://github.com/webassembly/wasi-sdk&quot;&gt;&lt;code&gt;WASI SDK&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt; 
&lt;p&gt;The WASI SDK will install a local version of &lt;code&gt;clang&lt;/code&gt; configured with a wasi-sysroot. Follow &lt;a href=&quot;https://github.com/WebAssembly/wasi-sdk#use&quot;&gt;these instructions&lt;/a&gt; to configure it for use. Note that you can also use your installed system or emscripten &lt;code&gt;clang&lt;/code&gt; by building with &lt;code&gt;--target=wasm32-wasi&lt;/code&gt; but you will need some artifacts from WASI SDK to enable and link that build target (more information is available in WASI SDK&apos;s docs).&lt;/p&gt; 
&lt;h3&gt;2. Generate program skeleton from WIT&lt;/h3&gt; 
&lt;p&gt;Start by generating a C skeleton from &lt;code&gt;wit-bindgen&lt;/code&gt; using the &lt;a href=&quot;https://github.com/bytecodealliance/component-docs/tree/main/examples/tutorial/wit/adder/world.wit&quot;&gt;sample &lt;code&gt;adder/world.wit&lt;/code&gt; file&lt;/a&gt;:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;&amp;gt; wit-bindgen c path/to/adder/world.wit
Generating &quot;adder.c&quot;
Generating &quot;adder.h&quot;
Generating &quot;adder_component_type.o&quot;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;This has generated several files:&lt;/p&gt; 
&lt;p&gt;1.&lt;code&gt;adder.h&lt;/code&gt; (based on the &lt;code&gt;adder&lt;/code&gt; world) with the prototype of the &lt;code&gt;add&lt;/code&gt; function (prefixed by &lt;code&gt;exports_&lt;/code&gt;) - &lt;code&gt;uint32_t exports_docs_adder_add_add(uint32_t x, uint32_t y);&lt;/code&gt;.&lt;br&gt; 2. &lt;code&gt;adder.c&lt;/code&gt; that interfaces with the component model ABI to call your function.&lt;br&gt; 3. &lt;code&gt;adder_component_type.o&lt;/code&gt; which contains object code referenced in &lt;code&gt;adder.c&lt;/code&gt; from an &lt;code&gt;extern&lt;/code&gt; that must be linked via &lt;code&gt;clang&lt;/code&gt;.&lt;/p&gt; 
&lt;h3&gt;3. Write program code&lt;/h3&gt; 
&lt;p&gt;Next, create an &lt;code&gt;component.c&lt;/code&gt; that implements the &lt;code&gt;adder&lt;/code&gt; world (i.e. the interface defined in &lt;code&gt;adder.h&lt;/code&gt;):&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-c&quot;&gt;#include &quot;adder.h&quot;

uint32_t exports_docs_adder_add_add(uint32_t x, uint32_t y)
{
	return x + y;
}
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;4. Compile a WebAssembly module (P1) with &lt;code&gt;clang&lt;/code&gt;&lt;/h3&gt; 
&lt;p&gt;Now, you can compile the function into a Wasm module via clang:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-console&quot;&gt;clang component.c adder.c adder_component_type.o -o adder.wasm -mexec-model=reactor
&lt;/code&gt;&lt;/pre&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;Use the &lt;code&gt;clang&lt;/code&gt; included in the WASI SDK installation, for example at &lt;code&gt;&amp;lt;WASI_SDK_PATH&amp;gt;/bin/clang&lt;/code&gt;.&lt;/p&gt; 
 &lt;p&gt;Alternatively, you can also use the published &lt;a href=&quot;https://github.com/WebAssembly/wasi-sdk/pkgs/container/wasi-sdk&quot;&gt;&lt;code&gt;ghcr.io/webassembly/wasi-sdk&lt;/code&gt; container images&lt;/a&gt;&lt;br&gt; for performing builds.&lt;/p&gt; 
 &lt;p&gt;For example, to enter a container with &lt;code&gt;wasi-sdk&lt;/code&gt; installed:&lt;/p&gt; 
 &lt;pre&gt;&lt;code&gt;docker run --rm -it --mount type=bind,src=path/to/app/src,dst=/app ghcr.io/webassembly/wasi-sdk:wasi-sdk-25
&lt;/code&gt;&lt;/pre&gt; 
 &lt;p&gt;See also: &lt;a href=&quot;https://github.com/WebAssembly/wasi-sdk/blob/main/docker/Dockerfile&quot;&gt;&lt;code&gt;Dockerfile&lt;/code&gt; in &lt;code&gt;wasi-sdk&lt;/code&gt;&lt;/a&gt;&lt;/p&gt; 
&lt;/blockquote&gt; 
&lt;h3&gt;5. Convert the P1 component to a P2 component with &lt;code&gt;wasm-tools&lt;/code&gt;&lt;/h3&gt; 
&lt;p&gt;Next, we need to transform the P1 component to a P2 component. To do this, we can use &lt;code&gt;wasm-tools component new&lt;/code&gt;:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-console&quot;&gt;wasm-tools component new ./adder.wasm -o adder.component.wasm
&lt;/code&gt;&lt;/pre&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;&lt;a href=&quot;#&quot;&gt;!NOTE&lt;/a&gt;&lt;br&gt; The &lt;code&gt;.component.&lt;/code&gt; extension has no special meaning -- &lt;code&gt;.wasm&lt;/code&gt; files can be either modules or components.&lt;/p&gt; 
&lt;/blockquote&gt; 
&lt;h3&gt;6. (optional) Build a WASI-enabled WebAssembly (P2) component with &lt;code&gt;wasm-tools&lt;/code&gt;&lt;/h3&gt; 
&lt;p&gt;Do note &lt;code&gt;wasm-tools component new&lt;/code&gt; may fail if your code references any &lt;a href=&quot;https://wasi.dev/&quot;&gt;WASI&lt;/a&gt; APIs that must be imported, for&lt;br&gt; example via standard library imports like &lt;code&gt;stdio.h&lt;/code&gt;.&lt;/p&gt; 
&lt;p&gt;Using WASI interfaces requires an additional step as the WASI SDK still references &lt;code&gt;wasi_snapshot_preview1&lt;/code&gt; APIs that are not compatible directly with components.&lt;/p&gt; 
&lt;p&gt;For example, modifying the above to reference &lt;code&gt;printf()&lt;/code&gt; would compile:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-c&quot;&gt;#include &quot;adder.h&quot;
#include &amp;lt;stdio.h&amp;gt;

uint32_t exports_docs_adder_add_add(uint32_t x, uint32_t y)
{
	uint32_t result = x + y;
	printf(&quot;%d&quot;, result);
	return result;
}
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;However, the module would fail to transform to a component:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;&amp;gt;wasm-tools component new ./adder.wasm -o adder.component.wasm
error: failed to encode a component from module

Caused by:
    0: failed to decode world from module
    1: module was not valid
    2: module requires an import interface named `wasi_snapshot_preview1`
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;To build a P2 component that uses &lt;a href=&quot;https://wasi.dev/&quot;&gt;WASI&lt;/a&gt; interfaces from a P1 component, we&apos;ll need to make use of adapter modules.&lt;/p&gt; 
&lt;p&gt;Install the appropriate reactor adapter module &lt;a href=&quot;https://github.com/bytecodealliance/wit-bindgen#creating-components-wasi&quot;&gt;as documented here&lt;/a&gt;.&lt;/p&gt; 
&lt;p&gt;You can either get &lt;a href=&quot;https://github.com/bytecodealliance/wasmtime/releases&quot;&gt;the linked release&lt;/a&gt; of &lt;code&gt;wasi_snapshot_preview1.reactor.wasm&lt;/code&gt; and rename it to &lt;code&gt;wasi_snapshot_preview1.wasm&lt;/code&gt;, or build it directly from source in &lt;code&gt;wasmtime&lt;/code&gt; following the &lt;a href=&quot;https://github.com/bytecodealliance/wasmtime/tree/main/crates/wasi-preview1-component-adapter&quot;&gt;instructions here&lt;/a&gt; (make sure you &lt;code&gt;git submodule update --init&lt;/code&gt; first).&lt;/p&gt; 
&lt;p&gt;Now, you can adapt preview1 to preview2 to build a component:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-console&quot;&gt;wasm-tools component new adder.wasm --adapt wasi_snapshot_preview1.wasm -o adder.component.wasm
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;7. Inspect the built component&lt;/h3&gt; 
&lt;p&gt;Finally, you can inspect the embedded wit to see your component (including any WASI imports if necessary):&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;&amp;gt;wasm-tools component wit adder.component.wasm
package root:component;

world root {
  import wasi:io/error@0.2.2;
  import wasi:io/streams@0.2.2;
  import wasi:cli/stdin@0.2.2;
  import wasi:cli/stdout@0.2.2;
  import wasi:cli/stderr@0.2.2;
  import wasi:cli/terminal-input@0.2.2;
  import wasi:cli/terminal-output@0.2.2;
  import wasi:cli/terminal-stdin@0.2.2;
  import wasi:cli/terminal-stdout@0.2.2;
  import wasi:cli/terminal-stderr@0.2.2;
  import wasi:clocks/wall-clock@0.2.2;
  import wasi:filesystem/types@0.2.2;
  import wasi:filesystem/preopens@0.2.2;

  export add: func(x: s32, y: s32) -&amp;gt; s32;
}
...
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;8. Running the component from the example host&lt;/h3&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;&lt;a href=&quot;#&quot;&gt;!WARNING&lt;/a&gt;&lt;br&gt; You must be careful to use a version of the adapter (&lt;code&gt;wasi_snapshot_preview1.wasm&lt;/code&gt;) that is compatible with the version of&lt;br&gt; &lt;code&gt;wasmtime&lt;/code&gt; that will be used, to ensure that WASI interface versions (and relevant implementation) match.&lt;/p&gt; 
&lt;/blockquote&gt; 
&lt;p&gt;This repository contains an &lt;a href=&quot;https://github.com/bytecodealliance/component-docs/tree/main/component-model/examples/example-host&quot;&gt;example WebAssembly host&lt;/a&gt; written in Rust that can run components that implement the &lt;code&gt;adder&lt;/code&gt; world.&lt;/p&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;&lt;a href=&quot;#&quot;&gt;!NOTE&lt;/a&gt;&lt;br&gt; When hosts run components that use WASI interfaces, they must &lt;em&gt;explicitly&lt;/em&gt; &lt;a href=&quot;https://docs.wasmtime.dev/api/wasmtime_wasi/fn.add_to_linker_sync.html&quot;&gt;add WASI to the linker&lt;/a&gt; to run the built component.&lt;/p&gt; 
&lt;/blockquote&gt; 
&lt;p&gt;A successful run should show the following output:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;cargo run --release -- 1 2 adder.component.wasm
   Compiling example-host v0.1.0 (/path/to/component-docs/component-model/examples/example-host)
    Finished `release` profile [optimized] target(s) in 7.85s
     Running `target/debug/example-host 1 2 /tmp/docs/c/adder.component.wasm`
1 + 2 = 3
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;If &lt;em&gt;not&lt;/em&gt; configured correctly, you may see errors like the following:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;cargo run --release -- 1 2 adder.component.wasm
   Compiling example-host v0.1.0 (/path/to/component-docs/component-model/examples/example-host)
    Finished `release` profile [optimized] target(s) in 7.85s
     Running `target/release/example-host 1 2 adder.component.wasm`
Error: Failed to instantiate the example world

Caused by:
    0: component imports instance `wasi:io/error@0.2.2`, but a matching implementation was not found in the linker
    1: instance export `error` has the wrong type
    2: resource implementation is missing
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;This kind of error normally indicates that the host in question does not contain satisfy WASI imports.&lt;/p&gt; 
&lt;h3&gt;9. Running a Component from C/C++ Applications&lt;/h3&gt; 
&lt;p&gt;It is not yet possible to run a WebAssembly Component using the C API of &lt;code&gt;wasmtime&lt;/code&gt; &lt;code&gt;c-api&lt;/code&gt;. See &lt;a href=&quot;https://github.com/bytecodealliance/wasmtime/issues/6987&quot;&gt;&lt;code&gt;wasmtime&lt;/code&gt; issue #6987&lt;/a&gt; for more details.&lt;/p&gt; 
&lt;p&gt;The c-api is preferred over directly using the example host Rust crate in C++.&lt;/p&gt; 
&lt;p&gt;However, C/C++ language guest components can be composed with components written in any other language and run by their toolchains, or even composed with a C language command component and run via the &lt;code&gt;wasmtime&lt;/code&gt; CLI or any other host.&lt;/p&gt; 
&lt;p&gt;See the &lt;a href=&quot;../language-support/rust.md#running-a-component-from-rust-applications&quot;&gt;Rust Tooling guide&lt;/a&gt; for instructions on how to run this component from the Rust &lt;code&gt;example-host&lt;/code&gt; (replacing the path to &lt;code&gt;add.wasm&lt;/code&gt; with your &lt;code&gt;add-component&lt;/code&gt; above).&lt;/p&gt; 
&lt;h2&gt;C# Tooling&lt;/h2&gt; 
&lt;p&gt;WebAssembly components in C# can be built with &lt;a href=&quot;https://github.com/bytecodealliance/componentize-dotnet&quot;&gt;componentize-dotnet&lt;/a&gt;, a a NuGet package that can be used to create a fully AOT-compiled component, giving .NET developers a component experience comparable to those in Rust and TinyGo.&lt;/p&gt; 
&lt;h3&gt;Building a Component with &lt;code&gt;componentize-dotnet&lt;/code&gt;&lt;/h3&gt; 
&lt;p&gt;&lt;a href=&quot;https://github.com/bytecodealliance/componentize-dotnet&quot;&gt;&lt;code&gt;componentize-dotnet&lt;/code&gt;&lt;/a&gt; serves as a one-stop shop, wrapping several tools into one:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/dotnet/runtimelab/tree/feature/NativeAOT-LLVM&quot;&gt;NativeAOT-LLVM&lt;/a&gt; (compilation)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/bytecodealliance/wit-bindgen&quot;&gt;wit-bindgen&lt;/a&gt; (WIT imports and exports)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/bytecodealliance/wasm-tools&quot;&gt;wasm-tools&lt;/a&gt; (component conversion)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/WebAssembly/wasi-sdk&quot;&gt;WASI SDK&lt;/a&gt; (SDK used by NativeAOT-LLVM)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/bytecodealliance/wac&quot;&gt;Wac&lt;/a&gt; (used to compose components)&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;First, install the .NET SDK. For this walkthrough, we’ll use the &lt;a href=&quot;https://dotnet.microsoft.com/en-us/download/dotnet/10.0&quot;&gt;.NET 10 SDK preview&lt;/a&gt;.&lt;br&gt; You should also have &lt;a href=&quot;https://wasmtime.dev/&quot;&gt;wasmtime&lt;/a&gt; installed so you can run the binary that you produce.&lt;/p&gt; 
&lt;h3&gt;1. Create a new project&lt;/h3&gt; 
&lt;p&gt;Once you have the .NET SDK installed, create a new project:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;dotnet new install BytecodeAlliance.Componentize.DotNet.Templates
dotnet new componentize.wasi.cli -o adder
cd adder
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;2. Create or download your WIT world&lt;/h3&gt; 
&lt;p&gt;Next, create or download the WIT world you would like to target.&lt;/p&gt; 
&lt;p&gt;For this example we will use the &lt;a href=&quot;https://github.com/bytecodealliance/component-docs/tree/main/component-model/examples/tutorial/wit/adder/world.wit&quot;&gt;&lt;code&gt;adder&lt;/code&gt; world&lt;/a&gt;, with an &lt;code&gt;add&lt;/code&gt; function (e.g. to &lt;code&gt;wit/component.wit&lt;/code&gt;):&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-wit&quot;&gt;package docs:adder@0.1.0;

interface add {
    add: func(x: u32, y: u32) -&amp;gt; u32;
}

world adder {
    export add;
}
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;In the &lt;code&gt;adder.csproj&lt;/code&gt; project file, add a new &lt;code&gt;&amp;lt;ItemGroup&amp;gt;&lt;/code&gt;:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-xml&quot;&gt;&amp;lt;ItemGroup&amp;gt;
    &amp;lt;Wit Update=&quot;wit/component.wit&quot; World=&quot;adder&quot; /&amp;gt;
&amp;lt;/ItemGroup&amp;gt;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Since this component will only export a function dotnet considers this a library project.&lt;br&gt; Let&apos;s update the &lt;code&gt;&amp;lt;OutputType&amp;gt;&lt;/code&gt; to be a library in the &lt;code&gt;adder.csproj&lt;/code&gt;:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-diff&quot;&gt;- &amp;lt;OutputType&amp;gt;Exe&amp;lt;/OutputType&amp;gt;
+ &amp;lt;OutputType&amp;gt;Library&amp;lt;/OutputType&amp;gt;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;And remove the automatically generated &lt;code&gt;Program.cs&lt;/code&gt; file:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;rm Program.cs
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;3. Write the implementation for the &lt;code&gt;adder&lt;/code&gt; world&lt;/h3&gt; 
&lt;p&gt;If you try to build the project with &lt;code&gt;dotnet build&lt;/code&gt;, you&apos;ll get an error like the following:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;➜ dotnet build
Restore complete (8.6s)
You are using a preview version of .NET. See: https://aka.ms/dotnet-support-policy
  adder failed with 1 error(s) (25.6s)
    /path/to/adder/obj/Debug/net10.0/wasi-wasm/wit_bindgen/AdderWorld.wit.exports.docs.adder.v0_1_0.AddInterop.cs(15,19): error CS0103: The name &apos;AddImpl&apos; does not exist in the current context

Build failed with 1 error(s) in 34.6s
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;This is because we&apos;ve promised an implementation, but haven&apos;t yet written one for the &lt;code&gt;adder&lt;/code&gt; world.&lt;/p&gt; 
&lt;p&gt;To fix this, add the following code to your in a file called &lt;code&gt;Component.cs&lt;/code&gt;:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-csharp&quot;&gt;namespace AdderWorld;

public class AddImpl : IAdderWorld
{
    public static uint Add(uint x, uint y)
    {
        return x + y;
    }
}
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Then, we can build our component:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;dotnet build
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;The component will be available at &lt;code&gt;bin/Debug/net10.0/wasi-wasm/native/adder.wasm&lt;/code&gt;.&lt;/p&gt; 
&lt;h3&gt;4. (optional) the component from the example host&lt;/h3&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;&lt;a href=&quot;#&quot;&gt;!WARNING&lt;/a&gt;&lt;br&gt; You must be careful to use a version of the adapter (&lt;code&gt;wasi_snapshot_preview1.wasm&lt;/code&gt;) that is compatible with the version of&lt;br&gt; &lt;code&gt;wasmtime&lt;/code&gt; that will be used, to ensure that WASI interface versions (and relevant implementation) match.&lt;/p&gt; 
&lt;/blockquote&gt; 
&lt;p&gt;This repository contains an &lt;a href=&quot;https://github.com/bytecodealliance/component-docs/tree/main/component-model/examples/example-host&quot;&gt;example WebAssembly host&lt;/a&gt; written in Rust that can run components that implement the &lt;code&gt;adder&lt;/code&gt; world.&lt;/p&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;&lt;a href=&quot;#&quot;&gt;!NOTE&lt;/a&gt;&lt;br&gt; When hosts run components that use WASI interfaces, they must &lt;em&gt;explicitly&lt;/em&gt; &lt;a href=&quot;https://docs.wasmtime.dev/api/wasmtime_wasi/fn.add_to_linker_sync.html&quot;&gt;add WASI to the linker&lt;/a&gt; to run the built component.&lt;/p&gt; 
&lt;/blockquote&gt; 
&lt;p&gt;A successful run should show the following output:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;cargo run --release -- 1 2 adder.component.wasm
   Compiling example-host v0.1.0 (/path/to/component-docs/component-model/examples/example-host)
    Finished `release` profile [optimized] target(s) in 7.85s
     Running `target/debug/example-host 1 2 /tmp/docs/c/adder.component.wasm`
1 + 2 = 3
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;If &lt;em&gt;not&lt;/em&gt; configured correctly, you may see errors like the following:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;cargo run --release -- 1 2 adder.component.wasm
   Compiling example-host v0.1.0 (/path/to/component-docs/component-model/examples/example-host)
    Finished `release` profile [optimized] target(s) in 7.85s
     Running `target/release/example-host 1 2 adder.component.wasm`
Error: Failed to instantiate the example world

Caused by:
    0: component imports instance `wasi:io/error@0.2.2`, but a matching implementation was not found in the linker
    1: instance export `error` has the wrong type
    2: resource implementation is missing
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;This kind of error normally indicates that the host in question does not contain satisfy WASI imports.&lt;/p&gt; 
&lt;h3&gt;Building a component that exports an interface&lt;/h3&gt; 
&lt;p&gt;The previous example uses a WIT file that exports a function. However, you&apos;ll often prefer to export an interface, either to comply with an existing specification or to capture a set of functions and types that tend to go together. Let&apos;s expand our &lt;code&gt;example&lt;/code&gt; world to export an interface rather than directly export the function. We are also adding the &lt;code&gt;hostapp&lt;/code&gt; world to our WIT file which we will implement in &lt;a href=&quot;#building-a-component-that-imports-an-interface&quot;&gt;the next section&lt;/a&gt; to demonstrate how to build a component that &lt;em&gt;imports&lt;/em&gt; an interface.&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-wit&quot;&gt;// adder/world.wit
package example:component;

interface add {
    add: func(x: u32, y: u32) -&amp;gt; u32;
}

world example {
    export add;
}

world hostapp {
    import add;
}
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;If you peek at the bindings, you&apos;ll notice that we now implement a class for the &lt;code&gt;add&lt;/code&gt; interface rather than for the &lt;code&gt;example&lt;/code&gt; world -- this is a consistent pattern. As you export more interfaces from your world, you implement more classes.&lt;/p&gt; 
&lt;p&gt;Our &lt;code&gt;Component.cs&lt;/code&gt; example gets the slight update of:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-csharp&quot;&gt;namespace ExampleWorld.wit.exports.example.component;

public class AddImpl : IAdd
{
    public static uint Add(uint x, uint y)
    {
        return x + y;
    }
}
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Once again, compile an application to a Wasm component using &lt;code&gt;dotnet build&lt;/code&gt;:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;$ dotnet build
Restore complete (0.4s)
You are using a preview version of .NET. See: https://aka.ms/dotnet-support-policy
  adder succeeded (1.1s) → bin/Debug/net10.0/wasi-wasm/adder.dll

Build succeeded in 2.5s
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;The component will be available at &lt;code&gt;bin/Debug/net10.0/wasi-wasm/native/adder.wasm&lt;/code&gt;.&lt;/p&gt; 
&lt;h3&gt;Building a component that imports an interface&lt;/h3&gt; 
&lt;p&gt;So far, we&apos;ve been dealing with library components. Now we will be creating a command component that implements the &lt;code&gt;hostapp&lt;/code&gt; world. This component will import the &lt;code&gt;add&lt;/code&gt; interface that is exported from our &lt;code&gt;adder&lt;/code&gt; component and call the &lt;code&gt;add&lt;/code&gt; function. We will later compose this command component with the &lt;code&gt;adder&lt;/code&gt; library component we just built.&lt;/p&gt; 
&lt;p&gt;Now we will be taking the &lt;code&gt;adder&lt;/code&gt; component and executing it from another WebAssembly component.&lt;/p&gt; 
&lt;p&gt;&lt;code&gt;dotnet new componentize.wasi.cli&lt;/code&gt; creates a new project that creates an executable.&lt;/p&gt; 
&lt;p&gt;Back out of the current project and create a new one:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;cd ..
dotnet new componentize.wasi.cli -o host-app
cd host-app
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Copy the same WIT file as before into your project:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-wit&quot;&gt;// adder/world.wit
package example:component;

interface add {
    add: func(x: u32, y: u32) -&amp;gt; u32;
}

world example {
    export add;
}

world hostapp {
    import add;
}
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Add it to your &lt;code&gt;host-app.csproj&lt;/code&gt; project file as a new &lt;code&gt;ItemGroup&lt;/code&gt;:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-xml&quot;&gt;&amp;lt;ItemGroup&amp;gt;
    &amp;lt;Wit Update=&quot;adder/add.wit&quot; World=&quot;hostapp&quot; /&amp;gt;
&amp;lt;/ItemGroup&amp;gt;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Notice how the &lt;code&gt;World&lt;/code&gt; changed from &lt;code&gt;example&lt;/code&gt; to &lt;code&gt;hostapp&lt;/code&gt;. The previous examples focused on implementing the class library for this WIT file - the &lt;code&gt;export&lt;/code&gt; functions. Now we&apos;ll be focusing on the executable side of the application - the &lt;code&gt;hostapp&lt;/code&gt; world.&lt;/p&gt; 
&lt;p&gt;Modify &lt;code&gt;Program.cs&lt;/code&gt; to look like this:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-csharp&quot;&gt;// Pull in all imports of the `hostapp` world, namely the `add` interface.
// example.component refers to the package name defined in the WIT file.
using HostappWorld.wit.imports.example.component;

uint left = 1;
uint right = 2;
var result = AddInterop.Add(left, right);
Console.WriteLine($&quot;{left} + {right} = {result}&quot;);
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Once again, compile your component with &lt;code&gt;dotnet build&lt;/code&gt;:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;$ dotnet build
Restore complete (0.4s)
You are using a preview version of .NET. See: https://aka.ms/dotnet-support-policy
  host-app succeeded (1.1s) → bin/Debug/net10.0/wasi-wasm/host-app.dll

Build succeeded in 2.5s
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;At this point, you&apos;ll have two Webassembly components:&lt;/p&gt; 
&lt;ol&gt; 
 &lt;li&gt;A component that implements the &lt;code&gt;example&lt;/code&gt; world.&lt;/li&gt; 
 &lt;li&gt;A component that implements the &lt;code&gt;hostapp&lt;/code&gt; world.&lt;/li&gt; 
&lt;/ol&gt; 
&lt;p&gt;Since the &lt;code&gt;host-app&lt;/code&gt; component depends on the &lt;code&gt;add&lt;/code&gt; function which is defined in the &lt;code&gt;example&lt;/code&gt; world, it needs to be composed the first component. You can compose your &lt;code&gt;host-app&lt;/code&gt; component with your &lt;code&gt;adder&lt;/code&gt; component by running &lt;a href=&quot;https://github.com/bytecodealliance/wac&quot;&gt;&lt;code&gt;wac plug&lt;/code&gt;&lt;/a&gt;:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;wac plug \
    bin/Debug/net10.0/wasi-wasm/native/host-app.wasm \
    --plug ../adder/bin/Debug/net10.0/wasi-wasm/native/adder.wasm \
    -o main.wasm
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;You can also automate the process by adding the following to your &lt;code&gt;host-app.csproj&lt;/code&gt;:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-xml&quot;&gt;&amp;lt;Target Name=&quot;ComposeWasmComponent&quot; AfterTargets=&quot;Publish&quot;&amp;gt;
    &amp;lt;PropertyGroup&amp;gt;
        &amp;lt;EntrypointComponent&amp;gt;bin/$(Configuration)/$(TargetFramework)/wasi-wasm/native/host-app.wasm&amp;lt;/EntrypointComponent&amp;gt;
        &amp;lt;DependencyComponent&amp;gt;../adder/bin/$(Configuration)/$(TargetFramework)/wasi-wasm/native/adder.wasm&amp;lt;/DependencyComponent&amp;gt;
    &amp;lt;/PropertyGroup&amp;gt;
    &amp;lt;MakeDir Directories=&quot;dist&quot; /&amp;gt;
    &amp;lt;Exec Command=&quot;$(WacExe) plug $(EntrypointComponent) --plug $(DependencyComponent) -o dist/main.wasm&quot; /&amp;gt;
&amp;lt;/Target&amp;gt;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Run &lt;code&gt;dotnet build&lt;/code&gt; again you will have a composed component in &lt;code&gt;./dist/main.wasm&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;Then you can run the composed component:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;wasmtime run ./dist/main.wasm
1 + 2 = 3
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Check out the &lt;a href=&quot;https://github.com/bytecodealliance/componentize-dotnet&quot;&gt;componentize-dotnet docs&lt;/a&gt; for more configurations options.&lt;/p&gt; 
&lt;hr&gt; 
&lt;h1&gt;Building a Component with &lt;code&gt;wasm-tools&lt;/code&gt;&lt;/h1&gt; 
&lt;p&gt;&lt;code&gt;wasm-tools&lt;/code&gt; can be used to create a component from WebAssembly Text (WAT). This walks through creating a component from WAT that implements the &lt;a href=&quot;https://github.com/bytecodealliance/component-docs/blob/main/component-model/examples/tutorial/wit/adder/world.wit&quot;&gt;&lt;code&gt;adder&lt;/code&gt; world&lt;/a&gt; and simply adds two numbers.&lt;/p&gt; 
&lt;ol&gt; 
 &lt;li&gt;Install&lt;/li&gt; 
 &lt;li&gt;The &lt;code&gt;add&lt;/code&gt; function is defined inside the following &lt;code&gt;world&lt;/code&gt; world:&lt;/li&gt; 
&lt;/ol&gt; 
&lt;pre&gt;&lt;code class=&quot;language-wit&quot;&gt;package docs:adder@0.1.0;

interface add {
    add: func(x: u32, y: u32) -&amp;gt; u32;
}

world adder {
    export add;
}
&lt;/code&gt;&lt;/pre&gt; 
&lt;ol&gt; 
 &lt;li&gt;Define an &lt;code&gt;add&lt;/code&gt; core module in WAT that exports an &lt;code&gt;add&lt;/code&gt; function that adds two parameters:&lt;/li&gt; 
&lt;/ol&gt; 
&lt;pre&gt;&lt;code class=&quot;language-wat&quot;&gt;(module
  (func $add (param $lhs i32) (param $rhs i32) (result i32)
      local.get $lhs
      local.get $rhs
      i32.add)
  (export &quot;docs:adder/add@0.1.0&quot; (func $add))
)
&lt;/code&gt;&lt;/pre&gt; 
&lt;ol&gt; 
 &lt;li&gt;Use &lt;code&gt;wasm-tools&lt;/code&gt; to create a component from the core module, first embedding component metadata&lt;br&gt; inside the core module and then encoding the WAT to a Wasm binary.&lt;/li&gt; 
&lt;/ol&gt; 
&lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;$ wasm-tools component embed adder/world.wit add.wat -o add.wasm
$ wasm-tools component new add.wasm -o add.component.wasm
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;Running a Component with Wasmtime&lt;/h3&gt; 
&lt;p&gt;You can &quot;run&quot; a component by calling one of its exports. Hosts and runtimes often only support running components with certain exports. The &lt;a href=&quot;https://github.com/bytecodealliance/wasmtime&quot;&gt;&lt;code&gt;wasmtime&lt;/code&gt;&lt;/a&gt; CLI can only run &quot;command&quot; components, so in order to run the &lt;code&gt;add&lt;/code&gt; function above, it first must be composed with a primary &quot;command&quot; component that calls it. See &lt;a href=&quot;./creating-and-consuming/running.md&quot;&gt;documentation on running components&lt;/a&gt; for more details.&lt;/p&gt; 
&lt;h2&gt;Useful links&lt;/h2&gt; 
&lt;p&gt;The following references are helpful in understanding the Component Model and related ecosystem/projects.&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/bytecodealliance/wac&quot;&gt;WebAssembly Composition tool (&lt;code&gt;wac&lt;/code&gt;)&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/bytecodealliance/wasm-pkg-tools&quot;&gt;WebAssembly package tools (notably &lt;code&gt;wkg&lt;/code&gt;)&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/WebAssembly/WASI/tree/main/wasip2&quot;&gt;WASI Preview 2&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/WebAssembly/component-model&quot;&gt;Component Model internals&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/WebAssembly/component-model/blob/main/design/mvp/Explainer.md&quot;&gt;Component Model AST&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/WebAssembly/component-model/blob/main/design/mvp/CanonicalABI.md&quot;&gt;Canonical ABI&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Wikmd</title>
      <link>https://tedneward.github.io/Research/tools/wikmd/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/wikmd/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/Linbreux/wikmd&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>The Witchcraft Compiler Collection</title>
      <link>https://tedneward.github.io/Research/tools/witchcraft/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/witchcraft/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/endrazine/wcc/wiki&quot;&gt;User manual&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;wld: The Witchcraft Linker&lt;br&gt; - wld takes an ELF executable as an input and modifies it to create a shared library.&lt;/p&gt; 
&lt;p&gt;wcc: The Witchcraft Compiler&lt;br&gt; - The wcc compiler takes binaries (ELF, PE, ...) as an input and creates valid ELF binaries as an output. It can be used to create relocatable object files from executables or shared libraries.&lt;/p&gt; 
&lt;p&gt;wsh: The Witchcraft shell&lt;br&gt; - The witchcraft shell accepts ELF shared libraries, ELF ET_DYN executables and Witchcraft Shell Scripts written in Punk-C as an input. It loads all the executables in its own address space and makes their API available for programming in its embedded interpreter. This provides for binaries functionalities similar to those provided via reflection on languages like Java.&lt;/p&gt; 
&lt;p&gt;wldd: print shared libraries compilation flags&lt;/p&gt; 
&lt;p&gt;wcch: generate C headers from binaries&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://github.com/endrazine/wcc&quot;&gt;Github&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>VMLens</title>
      <link>https://tedneward.github.io/Research/tools/vmlens/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/vmlens/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://vmlens.com/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/vmlens/vmlens&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>watc (Where&apos;s All The Code?)</title>
      <link>https://tedneward.github.io/Research/tools/watc/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/watc/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://flak.tedunangst.com/post/watc&quot;&gt;Original Post&lt;/a&gt; | &lt;a href=&quot;https://humungus.tedunangst.com/r/watc&quot;&gt;Source&lt;/a&gt; (Go)&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://nullprogram.com/blog/2022/05/22/&quot;&gt;Another take&lt;/a&gt; (in C) | &lt;a href=&quot;https://github.com/skeeto/scratch/blob/master/misc/watc.c&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>WinBoat</title>
      <link>https://tedneward.github.io/Research/tools/winboat/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/winboat/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.winboat.app/&quot;&gt;Website&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>X11 Tools</title>
      <link>https://tedneward.github.io/Research/tools/x11/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/x11/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;http://cyber.dabamos.de/unix/x11/&quot;&gt;Cool, but obscure, X11 tools&lt;/a&gt;:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt; &lt;p&gt;&lt;a href=&quot;http://www.newbreedsoftware.com/3dpong/index2.php3&quot;&gt;3D Pong&lt;/a&gt; is three-dimensional version of the first arcade game, “Pong”, for the X Window System.&lt;/p&gt; &lt;pre&gt;&lt;code&gt;    # pkg install games/3dpong
&lt;/code&gt;&lt;/pre&gt; &lt;p&gt;To play against the computer, run:&lt;/p&gt; &lt;pre&gt;&lt;code&gt;    $ 3dpong :0 --computer --sound
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Angband: A roguelike game derived from Moria, based loosely on the books of J. R. R. Tolkien. The ultimate aim of the game is to advance in skill and strength, collecting better and more powerful magical items until you are ready to face the Master of the dungeon: Morgoth himself! Start the X11 mode with &lt;code&gt;angband -mx11&lt;/code&gt;.&lt;/p&gt; &lt;pre&gt;&lt;code&gt;# pkg install games/angband
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;AppRes: Prints the resources seen by an application. It can be used to determine which resources a particular program will load.&lt;/p&gt; &lt;pre&gt;&lt;code&gt;# pkg install x11/appres
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;ASClock: AfterStep clock with some language extensions.&lt;/p&gt; &lt;pre&gt;&lt;code&gt;# pkg install x11-clocks/asclock
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Battalion: Battalion is a 3D game from 1994, originally written for the Silicon Graphics Indy UNIX workstation. The player controls a monster to blow up a city. The author dedicated a website to the game.&lt;/p&gt; &lt;p&gt;Depending on the perspective, the controls are a little awkward. You may want to change the camera with key 1, 2, 3, or 4. Use the mouse to rotate and to move forward/backward. The arrow keys only work if the mouse cursor is placed in the center of the screen. Shoot with the left control key or the left mouse button, and tilt the head with A and Z to target helicopters and jets. The camera can be rotated with I, J, K, and L. Alter the rendering details with D. Press G to grab the mouse cursor and P to pause the game.&lt;/p&gt; &lt;p&gt;I made a quick &amp;amp; dirty FreeBSD port based on the Linux version (no sound). Build and run Battalion with:&lt;/p&gt; &lt;pre&gt;&lt;code&gt;$ tar xfvz battalion1.4b-freebsd.tar.gz
$ cd battalion1.4b-freebsd/
$ gmake battalion CC=gcc
$ ./battalion
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Free42: Simulation of the HP-42S scientific calculator and HP-82240 printer.&lt;/p&gt; &lt;pre&gt;&lt;code&gt;# pkg install misc/free42
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;FSV2: A 3D filesystem visualiser, like fsn for SGI IRIX. Prone to crashing (perhaps, UTF-8 issues).&lt;/p&gt; &lt;pre&gt;&lt;code&gt;# pkg install x11-fm/fsv2
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;GLXGears: A simple OpenGL tool for testing your graphics adapter.&lt;/p&gt; &lt;pre&gt;&lt;code&gt;# pkg install graphics/mesa-demos
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;GMixer: Audio mixer for X11, based on now deprecated GTK+ 1.2.&lt;/p&gt; &lt;pre&gt;&lt;code&gt;# pkg install audio/gmixer
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;GVim: Improved version of the vi editor. The graphical front-end can be compiled with either X11, Motif, Xaw, or GTK+ 2/3.&lt;/p&gt; &lt;pre&gt;&lt;code&gt;# pkg install editors/vim
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;HP-15c: Emulator of the HP-15C programmable calculator, written in Tcl/Tk. The source-code is available on the &lt;a href=&quot;https://hp-15c.homepage.t-online.de/&quot;&gt;official website&lt;/a&gt;.&lt;/p&gt; &lt;pre&gt;&lt;code&gt;$ unzip HP-15C_4.1.00_Source.zip
$ wish8.6 ./HP-15C.tcl
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Ico: Displays wire-framed rotating polyhedrons.&lt;/p&gt; &lt;pre&gt;&lt;code&gt;# pkg install x11/ico
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Mgdiff: Motif-based front-end to the Unix diff command. The appearance of mgdiff is based upon a program called gdiff, which runs only on Silicon Graphics workstations and for which source code is not provided.&lt;/p&gt; &lt;pre&gt;&lt;code&gt;# pkg install textproc/mgdiff
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Mxico: Maho’s eXtended Ico is a simple demo for X, rotating polyhedra in the window. See &lt;a href=&quot;https://people.freebsd.org/~maho/mxico/Zalgaller.html&quot;&gt;this table&lt;/a&gt; for reference and start MxIco with, for example, &lt;code&gt;mxico -sleep 1 -obj n65&lt;/code&gt;.&lt;/p&gt; &lt;pre&gt;&lt;code&gt;# pkg install x11/mxico
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Micropolis: Open-source version of the famous computer game SimCity. Available on &lt;a href=&quot;https://github.com/interkosmos/micropolis&quot;&gt;GitHub&lt;/a&gt;.&lt;/p&gt; &lt;pre&gt;&lt;code&gt;$ git clone https://github.com/interkosmos/micropolis
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;NEdit: X11/Motif GUI text editor for programs and plain text files.&lt;/p&gt; &lt;pre&gt;&lt;code&gt;# pkg install editors/nedit
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Plan: Plan is a schedule planner based on X/Motif.&lt;/p&gt; &lt;pre&gt;&lt;code&gt;# pkg install deskutils/plan
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Sunclock: A fancy clock for the X Window system, providing local time (legal time and solar time), sunrise, sunset and various geographical data through a point and click interface.&lt;/p&gt; &lt;pre&gt;&lt;code&gt;# pkg install astro/sunclock
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Ted: A simple RTF editor for X11. Can either be compiled with Motif or GTK+ 2. The binary starts with an upper-case letter (Ted). Prone to crashing.&lt;/p&gt; &lt;pre&gt;&lt;code&gt;# pkg install editors/ted
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;TIEmu: Emulator for Texas Instruments TI-89/TI-92 (Plus)/Voyage 200 graphical calculators. ROM files not included. TIGCC is a compatible C compiler, based on GCC, and available as a FreeBSD port as well.&lt;/p&gt; &lt;pre&gt;&lt;code&gt;# pkg install emulators/tiemu3
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;WordNet: WordNet is a lexical reference system that combines aspects of dictionaries and thesauri with psycholinguistic theories of human lexical memory. It is developed by the Cognitive Science Laboratory at Princeton University.&lt;/p&gt; &lt;p&gt;The graphical WordNet browser wnb depends on Tcl/Tk:&lt;/p&gt; &lt;pre&gt;&lt;code&gt;# pkg install x11-toolkits/tk86 textproc/wordnet
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;X026: X026 is an keypunch emulator, simulating the IBM 026. Perfect for writing FORTRAN code on Hollerith punch cards and getting a clearer picture of how laborious data input back then was. The default character set is BCD-H.&lt;/p&gt; &lt;pre&gt;&lt;code&gt;# pkg install deskutils/x026
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;X48: Emulator of the HP 48GX graphing calculator. ROM image is included.&lt;/p&gt; &lt;pre&gt;&lt;code&gt;# pkg install emulators/x48
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;XAbacus: Simply an abacus for the X Window System.&lt;/p&gt; &lt;pre&gt;&lt;code&gt;# pkg install games/xabacus
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;XAntfarm: Ant hill simulation on the X11 root window.&lt;/p&gt; &lt;pre&gt;&lt;code&gt;# pkg install x11/xantfarm
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;XArchiver: XArchiver is a GTK+ 2 front-end to various archiving tools (tar, zip, 7z, …).&lt;/p&gt; &lt;pre&gt;&lt;code&gt;# pkg install archivers/xarchiver
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;XASCII: XASCII displays the ASCII table in hex, decimal, and octal.&lt;/p&gt; &lt;pre&gt;&lt;code&gt;# pkg install x11/xascii
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;XBiff: XBiff shows a small mailbox with its flag raised when new mail arrives in your inbox. It simply monitors the size of a given file. For instance, the cache of the Sylpheed e-mail client can be watched with:&lt;/p&gt; &lt;pre&gt;&lt;code&gt;$ xbiff -file $HOME/.sylpheed-2.0/imapcache/&amp;lt;server&amp;gt;/&amp;lt;address&amp;gt;/INBOX/.sylpheed_cache
&lt;/code&gt;&lt;/pre&gt; &lt;p&gt;You can change the pixmap in ~/.Xdefaults:&lt;/p&gt; &lt;pre&gt;&lt;code&gt;xbiff*flip: false
xbiff*fullPixmap: mailfull
xbiff*emptyPixmap: mailempty
xbiff*fullPixmapMask: mailfullmsk
xbiff*emptyPixmapMask: mailemptymsk
xbiff*shapeWindow: true
&lt;/code&gt;&lt;/pre&gt; &lt;p&gt;Install it with:&lt;/p&gt; &lt;pre&gt;&lt;code&gt;# pkg install x11/xbiff
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;XBill: XBill is an arcade game from 1994 in which the player has to prevent an evil computer hacker named “Bill” from installing a popular operating system on various machines. The OS can spread over networks and purges existing systems (BSD, Solaris, SGI IRIX, …). A contemporary modification of the game is known as XLennart.&lt;/p&gt; &lt;pre&gt;&lt;code&gt;# pkg install games/xbill
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;XBoard: XBoard is a graphical front-end for chess engines like GNU Chess. Start it with xboard -fcp &apos;gnuchess --xboard&apos;.&lt;/p&gt; &lt;pre&gt;&lt;code&gt;# pkg install games/xboard
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;XCalc: A simple and clean scientific calculator for X11. Additional colour styles imitating the Texas Instruments TI-30 and the Hewlett-Packard 10C are listed in the file /usr/local/share/X11/app-defaults/XCalc-color. Just copy one of the styles into your ~/.Xdefaults.&lt;/p&gt; &lt;pre&gt;&lt;code&gt;# pkg install x11/xcalc
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;XCalendar: A calendar with an integrated notebook.&lt;/p&gt; &lt;pre&gt;&lt;code&gt;# pkg install deskutils/xcalendar
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;XCHM: Microsoft Windows help file viewer for Unix.&lt;/p&gt; &lt;pre&gt;&lt;code&gt;# pkg install deskutils/xchm
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;XChomp: Clone of the famous arcade game Pac-Man for X. See also the unofficial homepage.&lt;/p&gt; &lt;pre&gt;&lt;code&gt;# pkg install games/xchomp
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;XClipboard: A client for clipboard management in X.&lt;/p&gt; &lt;pre&gt;&lt;code&gt;# pkg install x11/xclipboard
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;XClock: An analog and digital clock for X.&lt;/p&gt; &lt;pre&gt;&lt;code&gt;# pkg install x11-clocks/xclock
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;XClock/Cat Clock: A Motif-based variant of MIT xclock from 1990 that features a “cat” mode. Available on GitHub.&lt;/p&gt; &lt;pre&gt;&lt;code&gt;# git clone https://github.com/BarkyTheDog/catclock
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;XColorSel: Grabs the colours of X windows.&lt;/p&gt; &lt;pre&gt;&lt;code&gt;# pkg install x11/xcolorsel
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;XConsole: XConsole shows system console messages.&lt;/p&gt; &lt;pre&gt;&lt;code&gt;# pkg install x11/xconsole
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;XCrySDen: XCrySDen is a crystalline and molecular structure visualisation program aiming at display of isosurfaces and contours, which can be superimposed on crystalline structures and interactively rotated and manipulated.&lt;/p&gt; &lt;pre&gt;&lt;code&gt;# pkg install science/xcrysden
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;XDiary: XDiary will help you keep track of your meetings, appointments and plan your time.&lt;/p&gt; &lt;pre&gt;&lt;code&gt;# pkg install deskutils/xmdiary
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;XDigger: Boulderdash-like game for the X Window System. Originally written for the East-German KC 85/3 and KC 85/4 computers in 1988 (see also the author’s website). Unfortunately, the game suffers from a major bug that prevents the rocks from falling.&lt;/p&gt; &lt;pre&gt;&lt;code&gt;# pkg install games/xdigger
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;XEarth: Renders the earth in 3D on the root window, making itself an animated backdrop. To show it inside a window, run:&lt;/p&gt; &lt;pre&gt;&lt;code&gt;$ xearth -geometry 800x600 -shade -nolabel -wait 1 -timewarp 50 -noroot -twopix
&lt;/code&gt;&lt;/pre&gt; &lt;p&gt;Similiar tools are XWorld, XGlobe and XPlanet, which also texture the earth.&lt;/p&gt; &lt;pre&gt;&lt;code&gt;# pkg install astro/xearth
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;XEdit: A simple text editor for X. The automated backup function for edited files can be disabled by adding xedit*enableBackups: off to ~/.Xdefaults.&lt;/p&gt; &lt;pre&gt;&lt;code&gt;# pkg install x11/xedit
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Xev: Prints contents of X events to the terminal.&lt;/p&gt; &lt;pre&gt;&lt;code&gt;# pkg install x11/xev
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;XEyes: Eyes following the mouse cursor.&lt;/p&gt; &lt;pre&gt;&lt;code&gt;# pkg install x11/xeyes
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;XFishtank: Make fish swim in the background of your screen to waste CPU cycles.&lt;/p&gt; &lt;pre&gt;&lt;code&gt;# pkg install x11/xfishtank
&lt;/code&gt;&lt;/pre&gt; &lt;p&gt;Currently, the port is unfetchable. I patched the Linux version manually to run on FreeBSD:&lt;/p&gt; &lt;pre&gt;&lt;code&gt;$ tar xfvz xfishtank-2.2.tar.gz
$ cd xfishtank2.0/
$ gmake CC=gcc
$ ./xfishtank -d
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;XFontSel: Lists installed fonts and available font options.&lt;/p&gt; &lt;pre&gt;&lt;code&gt;# pkg install x11-fonts/xfontsel
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;XGalaga: Clone of the classic game Galaga for X11.&lt;/p&gt; &lt;pre&gt;&lt;code&gt;# pkg install games/xgalaga
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Xgc: X11 program that demonstrates various features of the X graphics primitives.&lt;/p&gt; &lt;pre&gt;&lt;code&gt;# pkg install x11/xgc
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;XInfocom: Infocom game interpreter for X11.&lt;/p&gt; &lt;pre&gt;&lt;code&gt;# pkg install games/xinfocom
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;XInvaders 3D: A 3D vector-graphics Space Invaders clone for X11.&lt;/p&gt; &lt;pre&gt;&lt;code&gt;# pkg install games/xinvaders3d
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;XKill: Command-line tool to kill X applications.&lt;/p&gt; &lt;pre&gt;&lt;code&gt;# pkg install x11/xkill
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;XLaby: Daemonic X Labyrinth played directly with the mouse pointer.&lt;/p&gt; &lt;pre&gt;&lt;code&gt;# pkg install games/xlaby
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;XLennart: XLennart is a modification of the arcade game XBill. An evil and unpopular computer hacker named “Lennart” tries to install his malicious init system on various BSD and Linux systems. Like in XBill, the player has to hit him and restore infected machines.&lt;/p&gt; &lt;pre&gt;&lt;code&gt;# pkg install games/xlennart
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;XLess: XLess is less for X.&lt;/p&gt; &lt;pre&gt;&lt;code&gt;# pkg install misc/xless
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;XLife: Cellular automaton for X11 simulating Conway’s Game of Life.&lt;/p&gt; &lt;pre&gt;&lt;code&gt;# pkg install games/xlife
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;XLoad: XLoad shows the current CPU load.&lt;/p&gt; &lt;pre&gt;&lt;code&gt;# pkg install x11/xload
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;XLock: XLock locks the screen and optionally shows a screen saver. It can be combined with XAutoLock to activate it after a user defined time of inactivity.&lt;/p&gt; &lt;p&gt;A more simple approach is used by XTransparentLock. Jamie Zawinski, the author of XScreenSaver, has listed some reason why you should use XScreenSaver instead of XLock.&lt;/p&gt; &lt;pre&gt;&lt;code&gt;# pkg install x11/xlockmore
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;XLogo: XLogo simply draws the logo of the X Window System. The background and foreground colours can be altered in ~/.Xdefaults.&lt;/p&gt; &lt;pre&gt;&lt;code&gt;# pkg install x11/xlogo
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;XMahjongg: Classic Mahjongg game for X11. Several tile sets are available.&lt;/p&gt; &lt;pre&gt;&lt;code&gt;# pkg install games/xmahjongg
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;XMan: XMan displays system man pages.&lt;/p&gt; &lt;pre&gt;&lt;code&gt;# pkg install x11/xman
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;XMascot: XMascot displays a moving mascot on your X11 screen. It can talk, set an alarm, or check your mail.&lt;/p&gt; &lt;pre&gt;&lt;code&gt;# pkg install x11/xmascot
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;XMaxima: XMaxima is a Tcl/Tk front-end to Maxima, a Computer Algebra System written in Common Lisp.&lt;/p&gt; &lt;pre&gt;&lt;code&gt;# pkg install math/xmaxima
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;XmBibTeX: XmBibTeX is a Motif reference manager based on the BibTeX file format. It allows to add, delete, and edit references. The references can be saved in the BibTeX file format and also written on a LaTeX file that can be printed using LaTeX and BibTeX. No Unicode support.&lt;/p&gt; &lt;pre&gt;&lt;code&gt;# pkg install print/xmbibtex
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;XMessage: XMessage displays arbitrary text messages.&lt;/p&gt; &lt;pre&gt;&lt;code&gt;# pkg install x11/xmessage
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;XmGrace: A WYSIWYG 2D plotting tool for the X Window System and Motif. Features polynomial regression, splines, running averages, DFT/FFT, and cross/auto-correlation.&lt;/p&gt; &lt;pre&gt;&lt;code&gt;# pkg install math/grace
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;XMH: Graphical user interface to the MH Message Handling System.&lt;/p&gt; &lt;pre&gt;&lt;code&gt;# pkg install x11/xmh
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;XMixer: Audio mixer for X11.&lt;/p&gt; &lt;pre&gt;&lt;code&gt;# pkg install audio/xmixer
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;XmMix: Motif-based audio mixer for X11.&lt;/p&gt; &lt;pre&gt;&lt;code&gt;# pkg install audio/xmmix
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;XMore: XMore is more for X.&lt;/p&gt; &lt;pre&gt;&lt;code&gt;# pkg install x11/xmore
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;XMosaic: NCSA Mosaic, one of the first graphical web browsers, for X. The source code of version 2.7b is available on GitHub.&lt;/p&gt; &lt;pre&gt;&lt;code&gt;# git clone https://github.com/alandipert/ncsa-mosaic
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;XMOTD: XMOTD shows the message of the day. Run it with xmotd -always /etc/motd. The appearance can be altered in ~/.Xdefaults.&lt;/p&gt; &lt;pre&gt;&lt;code&gt;# pkg install x11/xmotd
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;XMountains: XMountains renders a mountain scene into the root window. Also available as an XScreenSaver module.&lt;/p&gt; &lt;pre&gt;&lt;code&gt;# pkg install graphics/xmountains
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;XNeko:Neko (猫) is a cat chasing the mouse cursor all over the screen. Oneko is a modified version of xneko for BSD and Linux. In the port games/oneko-sakura several other creatures can be choosen, like tora-neko, Sakura Kinomoto, Tomoyo Daidouji, the BSD daemon, or a dog.&lt;/p&gt; &lt;pre&gt;&lt;code&gt;# pkg install games/xneko
&lt;/code&gt;&lt;/pre&gt; &lt;p&gt;Or:&lt;/p&gt; &lt;pre&gt;&lt;code&gt;# pkg install games/oneko
&lt;/code&gt;&lt;/pre&gt; &lt;p&gt;Or:&lt;/p&gt; &lt;pre&gt;&lt;code&gt;# pkg install games/oneko-sakura
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;XOdometer: XOdometer tracks the total distance of your pointing device. The source code of the version from January 1996 is available on GitHub&lt;/p&gt; &lt;pre&gt;&lt;code&gt;# git clone https://github.com/interkosmos/xodo
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;XOJ: XOJ lets the O. J. Simpson chase relive on your X root window.&lt;/p&gt; &lt;pre&gt;&lt;code&gt;# pkg install games/xoj
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;XOSView: XOSView is a visual system monitor for X11.&lt;/p&gt; &lt;pre&gt;&lt;code&gt;# pkg install sysutils/xosview
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Xplore: Yet another Motif-based file manager. Prone to crashing (probably, encoding issues).&lt;/p&gt; &lt;pre&gt;&lt;code&gt;# pkg install x11-fm/xplore
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;XPostIt: The most ugly note taking application on earth.&lt;/p&gt; &lt;pre&gt;&lt;code&gt;# pkg install deskutils/xpostit
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;XRoach: XRoach displays disgusting cockroaches on your root window. These creepy crawlies scamper around until they find a window to hide under. Whenever you move or iconify a window, the exposed beetles again scamper for cover.&lt;/p&gt; &lt;pre&gt;&lt;code&gt;# pkg install games/xroach
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;XScreenSaver: Jamie Zawinski’s famous screen saver for X.&lt;/p&gt; &lt;pre&gt;&lt;code&gt;# pkg install x11/xscreensaver
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;XSnow: Let it snow on your desktop. Shows snow flakes, trees, and santa.&lt;/p&gt; &lt;pre&gt;&lt;code&gt;# pkg install x11/xsnow
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;XSol: Motif-based solitaire game from 1998, similar to Klondike. Another implementation with the same name from 1987 had been ported to FreeBSD, but was later removed due to dependencies to the deprecated X10 headers. I haven’t found a port of this XSol, but the game can still be compiled from source:&lt;/p&gt; &lt;pre&gt;&lt;code&gt;$ tar xfvz xsol-0.3.1.tar.gz
$ cd xsol/
$ make
$ ./xsol
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;XSpread: XSpread is a simple spreadsheet application based on math/sc. It can be started without X11 by using the parameter -X.&lt;/p&gt; &lt;pre&gt;&lt;code&gt;# pkg install math/xspread
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;XStarRoll: XStarRoll is a simple demonstration program for X11. Letters and pixmaps fly far, far, far away, optionally on the root window. Start with, for example: ls -al | xstarroll -font &quot;-&lt;em&gt;-courier-medium-r-&lt;/em&gt;-&lt;em&gt;-20-&lt;/em&gt;-&lt;em&gt;-&lt;/em&gt;-&lt;em&gt;-&lt;/em&gt;-&lt;em&gt;-&lt;/em&gt;&quot; -bg &quot;black&quot; -fg &quot;yellow&quot; -geometry 640x400 -noblur.&lt;/p&gt; &lt;pre&gt;&lt;code&gt;# pkg install x11/xstarroll
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Xtacy: A trippy colour-cycling toy for X11. Displays various graphical effects and fractals, like bouncing quadrilaterals, plasma clouds, or phased sine waves. May run too fast on modern computers. See also the official website.&lt;/p&gt; &lt;pre&gt;&lt;code&gt;# pkg install x11/xtacy
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;XTar: XTar is a Motif-based tool for viewing and manipulating (compressed) tar archives.&lt;/p&gt; &lt;pre&gt;&lt;code&gt;# pkg install misc/xtar
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;XTerm: Terminal emulator for the X Window System.&lt;/p&gt; &lt;pre&gt;&lt;code&gt;# pkg install x11/xterm
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;XTide: Harmonic tide clock and tide predictor for X.&lt;/p&gt; &lt;pre&gt;&lt;code&gt;# pkg install astro/xtide
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;XTrojka: A Tetris-like game where the player has to control and place falling blocks to create three patterns or colors in a row, horizontally or diagonally.&lt;/p&gt; &lt;pre&gt;&lt;code&gt;# pkg install games/xtrojka
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Xv: Image viewer that displays various formats.&lt;/p&gt; &lt;pre&gt;&lt;code&gt;# pkg install graphics/xv
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Xvkbd: Virtual keyboard for X applications.&lt;/p&gt; &lt;pre&gt;&lt;code&gt;# pkg install x11/xvkbd
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;XWorld: Earth as seen from the direction of the sun.&lt;/p&gt; &lt;pre&gt;&lt;code&gt;# pkg install astro/xworld
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;XWPE: A Borland-like integrated development environment (IDE).&lt;/p&gt; &lt;pre&gt;&lt;code&gt;# pkg install devel/xwpe
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;XZoom: Tool to magnify, rotate, and mirror a section of the X screen.&lt;/p&gt; &lt;pre&gt;&lt;code&gt;# pkg install x11/xzoom
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Voiceliner</title>
      <link>https://tedneward.github.io/Research/tools/voiceliner/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/voiceliner/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://a9.io/voiceliner/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/maxkrieger/voiceliner&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Whamm</title>
      <link>https://tedneward.github.io/Research/tools/whamm/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/whamm/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/ejrgilbert/whamm&quot;&gt;Source&lt;/a&gt; | &lt;a href=&quot;https://ejrgilbert.github.io/whamm/intro.html&quot;&gt;Book&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Winstall/Winget</title>
      <link>https://tedneward.github.io/Research/tools/winstall/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/winstall/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://winstall.app/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/MehediH/winstall&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>XCode (Development tool/platform)</title>
      <link>https://tedneward.github.io/Research/tools/xcode/index/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/xcode/index/index.html</guid>
      	<description>
	&lt;p&gt;See also &lt;a href=&quot;../xcodebuild&quot;&gt;xcodebuild&lt;/a&gt;, &lt;a href=&quot;/languages/swift&quot;&gt;Swift&lt;/a&gt;, &lt;a href=&quot;/languages/objc&quot;&gt;Objective-C&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://github.com/RobotsAndPencils/xcodes&quot;&gt;xcodes&lt;/a&gt;: Command-line utility to manage multiple XCode installations (multiple versions, locations, etc); install with &lt;code&gt;brew install robotsandpencils/made/xcodes&lt;/code&gt;&lt;/p&gt; 
&lt;h2&gt;Tips and Tricks&lt;/h2&gt; 
&lt;p&gt;Find a list of &lt;a href=&quot;https://xcode-tips.github.io&quot;&gt;useful tips here&lt;/a&gt;.&lt;/p&gt; 
&lt;h2&gt;Xcode build process&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://xcodebuildsettings.com&quot;&gt;Xcode Build Settings&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://www.objc.io/issues/6-build-tools/build-process/&quot;&gt;Xcode Build Process&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://www.avanderlee.com/optimization/analysing-build-performance-xcode/&quot;&gt;Build performance analysis for speeding up Xcode builds&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://www.onswiftwings.com/posts/build-time-optimization-part1/&quot;&gt;Xcode Build Time Optimization&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://github.com/pfandrade/Xconfig&quot;&gt;Xconfig: Simple Mac app to display build settings for the currently open Xcode projects&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://asifmohd.github.io/ios/2021/03/11/xcbuild-debug-info.html&quot;&gt;Digging deeper into xcbuild: Rules and Tasks&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://gist.github.com/ddunbar/2dda0e836c855ea96759d1d05f086d69&quot;&gt;New Build System Tricks&lt;/a&gt;, by Daniel Dunbar&lt;/p&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Automatically setting Xcode project build numbers&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://mokacoding.com/blog/automatic-xcode-versioning-with-git/&quot;&gt;Automated Xcode version and build numbering via Git&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://useyourloaf.com/blog/setting-xcode-build-version-to-git-commit-name/&quot;&gt;Setting Xcode build version to Git commit name&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://useyourloaf.com/blog/setting-iphone-application-build-versions/&quot;&gt;Setting iPhone Application Build Versions&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Static vs Dynamic libraries and frameworks&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://pewpewthespells.com/blog/static_and_dynamic_libraries.html&quot;&gt;Static and Dynamic Libraries, by pewpewthespells&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://www.bignerdranch.com/blog/it-looks-like-you-are-trying-to-use-a-framework/&quot;&gt;It Looks Like You Are Trying to Use a Framework&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://www.runtastic.com/blog/en/frameworks-ios/&quot;&gt;Basic Overview Of Static And Dynamic Frameworks On iOS&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;a href=&quot;http://blog.cocoapods.org/CocoaPods-1.9.0-beta/&quot;&gt;CocoaPods 1.9 Beta&lt;/a&gt;, &lt;code&gt;use_frameworks! :linkage =&amp;gt; :static&lt;/code&gt;&lt;/p&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Cross-platform frameworks in Xcode&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://promisekit.org/news/2016/08/Multiplatform-Single-Scheme-Xcode-Projects/&quot;&gt;Multiplatform, Single-scheme Xcode Projects&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://ilya.puchka.me/xcode-cross-platform-frameworks/&quot;&gt;Xcode &amp;amp; cross-platform frameworks&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Documentation Packages (&quot;DocC&quot;)&lt;/h2&gt; 
&lt;p&gt;XCode Developer Documentation: &lt;code&gt;Developer Tools/DocC&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;Introduced (?) in XCode 13. DocC doc compiler converst Markdown-based text into &quot;rich documentation&quot; for Swift projects, accessible within XCode.&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Add a doc catalog to an existing project: 
  &lt;ul&gt; 
   &lt;li&gt;select project/package in Project Navigator&lt;/li&gt; 
   &lt;li&gt;File &amp;gt; New &amp;gt; File &amp;gt; Documentation Catalog template. Place the doc catalog in the same folder as the source files for DocC to associate the catalog with the library.&lt;/li&gt; 
   &lt;li&gt;&quot;Root&quot; markdown file is for the package-level documentation&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Source files use &lt;code&gt;///&lt;/code&gt; comments (with Markdown tags embedded within them) to provide context documentation&lt;/li&gt; 
 &lt;li&gt;Product &amp;gt; Build Documentation generates the docs&lt;/li&gt; 
 &lt;li&gt;Docs appear in Window &amp;gt; Developer Documentation &amp;gt; Workspace Documentation (at the top)&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;&lt;code&gt;Developer Tools/DocC/Documentation Types/API Documentation&lt;/code&gt; has more on the format of the Markdown&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>uv</title>
      <link>https://tedneward.github.io/Research/tools/uv/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/uv/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://docs.astral.sh/uv/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/astral-sh/uv&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;A single tool to replace pip, pip-tools, pipx, poetry, pyenv, twine, virtualenv, and more.&lt;/li&gt; 
 &lt;li&gt;10-100x faster than pip.&lt;/li&gt; 
 &lt;li&gt;Provides comprehensive project management, with a universal lockfile.&lt;/li&gt; 
 &lt;li&gt;Runs scripts, with support for inline dependency metadata.&lt;/li&gt; 
 &lt;li&gt;Installs and manages Python versions.&lt;/li&gt; 
 &lt;li&gt;Runs and installs tools published as Python packages.&lt;/li&gt; 
 &lt;li&gt;Includes a pip-compatible interface for a performance boost with a familiar CLI.&lt;/li&gt; 
 &lt;li&gt;Supports Cargo-style workspaces for scalable projects.&lt;/li&gt; 
 &lt;li&gt;Disk-space efficient, with a global cache for dependency deduplication.&lt;/li&gt; 
 &lt;li&gt;Installable without Rust or Python via curl or pip.&lt;/li&gt; 
 &lt;li&gt;Supports macOS, Linux, and Windows.&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Verasco</title>
      <link>https://tedneward.github.io/Research/tools/verasco/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/verasco/index.html</guid>
      	<description>
	&lt;ul&gt; 
 &lt;li&gt;static analyzer for the CompCert subset of ISO C 1999 that establishes the absence of run-time errors in analyzed programs&lt;/li&gt; 
 &lt;li&gt;entirely specified and proved sound using the Coq proof assistant&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://compcert.inria.fr/verasco/&quot;&gt;http://compcert.inria.fr/verasco/&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Visual Studio (and related) tools</title>
      <link>https://tedneward.github.io/Research/tools/visualstudio/index/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/visualstudio/index/index.html</guid>
      	<description>
	&lt;ul&gt; 
 &lt;li&gt; &lt;p&gt;Visual C++ documentation&lt;/p&gt; 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://docs.microsoft.com/en-us/cpp/&quot;&gt;https://docs.microsoft.com/en-us/cpp/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/Microsoft/cpp-docs&quot;&gt;https://github.com/Microsoft/cpp-docs&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://msdn.microsoft.com/en-us/library/60k1461a.aspx&quot;&gt;https://msdn.microsoft.com/en-us/library/60k1461a.aspx&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;/analyze (Code analysis)&lt;/p&gt; 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://docs.microsoft.com/en-us/cpp/build/reference/analyze-code-analysis&quot;&gt;https://docs.microsoft.com/en-us/cpp/build/reference/analyze-code-analysis&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Vagrant</title>
      <link>https://tedneward.github.io/Research/tools/vagrant/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/vagrant/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.vagrantup.com/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://www.github.com/hashicorp/vagrant&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Vim</title>
      <link>https://tedneward.github.io/Research/tools/vim/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/vim/index.html</guid>
      	<description>
	&lt;h3&gt;Vim&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.swaroopch.com/notes/vim/&quot;&gt;A Byte of Vim&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/iggredible/Learn-Vim&quot;&gt;Learn Vim (the Smart Way)&lt;/a&gt; (HTML) (:construction: &lt;em&gt;in process&lt;/em&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://danielmiessler.com/study/vim/&quot;&gt;Learn Vim For the Last Time&lt;/a&gt; - Daniel Miessler&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://yannesposito.com/Scratch/en/blog/Learn-Vim-Progressively/&quot;&gt;Learn Vim Progressively&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://learnvimscriptthehardway.stevelosh.com&quot;&gt;Learn Vimscript the Hard Way&lt;/a&gt; - Steve Losh&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://leanpub.com/VimLikeAPro&quot;&gt;Use Vim Like A Pro&lt;/a&gt; - Tim Ottinger &lt;em&gt;(Leanpub account or valid email requested)&lt;/em&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.truth.sk/vim/vimbook-OPL.pdf&quot;&gt;Vi Improved -- Vim&lt;/a&gt; - Steve Oualline (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/mhinz/vim-galore#readme&quot;&gt;VIM-GALORE - All things Vim!&lt;/a&gt; (HTML)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://web.archive.org/web/20130302172911/http://vim.runpaint.org/vim-recipes.pdf&quot;&gt;Vim Recipes&lt;/a&gt; (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://vimregex.com&quot;&gt;Vim Regular Expressions 101&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Umlet</title>
      <link>https://tedneward.github.io/Research/tools/umlet/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/umlet/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.umlet.com/&quot;&gt;Website&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;UMLet is a UML tool aimed at providing a fast way of creating UML diagrams. UML elements are modified using text input instead of pop-up dialogs. Elements can be modified and used as templates; this way, users can easily tailor UMLet to their modeling needs. UMLet supports a variety of UML diagram types: class diagrams, use case diagrams, sequence diagrams, state diagrams, deployment diagrams, activity diagrams -- see some examples.&lt;/p&gt; 
&lt;p&gt;UMLet also allows users to create their own custom UML elements. An element&apos;s look can be modified at run-time by changing a few lines of Java code; UMLet then compiles the new element&apos;s code on the fly. Without leaving UMLet, users can thus create and add new element types to their diagrams.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Valgrind</title>
      <link>https://tedneward.github.io/Research/tools/valgrind/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/valgrind/index.html</guid>
      	<description>
	&lt;p&gt;There are Valgrind tools that can automatically detect many memory management and threading bugs, and profile your programs in detail. You can also use Valgrind to build new tools.&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;http://valgrind.org/&quot;&gt;Website&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;http://valgrind.org/docs/pubs.html&quot;&gt;Valgrind Research Papers&lt;/a&gt;&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Overload Journal; Paul Floyd 
  &lt;ul&gt; 
   &lt;li&gt;Part 1 – Introduction - &lt;a href=&quot;https://accu.org/index.php/journals/1930&quot;&gt;https://accu.org/index.php/journals/1930&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Part 2 – Basic memcheck - &lt;a href=&quot;https://accu.org/index.php/journals/1913&quot;&gt;https://accu.org/index.php/journals/1913&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Part 3 – Advanced memcheck - &lt;a href=&quot;https://accu.org/index.php/journals/1905&quot;&gt;https://accu.org/index.php/journals/1905&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Part 4 – Cachegrind and Callgrind - &lt;a href=&quot;https://accu.org/index.php/journals/1886&quot;&gt;https://accu.org/index.php/journals/1886&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Part 5 – Massif - &lt;a href=&quot;https://accu.org/index.php/journals/1884&quot;&gt;https://accu.org/index.php/journals/1884&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Part 6 – Helgrind and DRD - &lt;a href=&quot;https://accu.org/index.php/journals/1867&quot;&gt;https://accu.org/index.php/journals/1867&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=3l0BQs2ThTo&quot;&gt;C++ Weekly - Episode 86&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://fau.re/blog/20140330_vgdb.html&quot;&gt;gdb + valgrind&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;http://heeris.id.au/2016/valgrind-gdb/&quot;&gt;Valgrind and GDB: Tame the Wild C&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://kristerw.blogspot.com/2020/02/watching-for-software-inefficiencies.html&quot;&gt;Watching for software inefficiencies with Valgrind&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://github.com/kristerw/deadstores&quot;&gt;deadstores: A Valgrind tool for finding redundant loads/stores&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://github.com/rimsa/CFGgrind&quot;&gt;CFGGrind: Dynamic Control Flow Graph Reconstruction&lt;/a&gt;&lt;br&gt; - &lt;a href=&quot;https://compilers.iecc.com/comparch/article/19-11-004&quot;&gt;https://compilers.iecc.com/comparch/article/19-11-004&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://github.com/wmkhoo/taintgrind&quot;&gt;Taintgrind&lt;/a&gt;: A taint-tracking plugin for the Valgrind memory checking tool&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Visidata</title>
      <link>https://tedneward.github.io/Research/tools/visidata/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/visidata/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.visidata.org/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/saulpw/visidata&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;VisiData is an interactive multitool for tabular data. It combines the clarity of a spreadsheet, the efficiency of the terminal, and the power of Python, into a lightweight utility which can handle millions of rows with ease.&lt;/p&gt; 
&lt;p&gt;Dang, this thing is Excel or Access in a terminal with a ton of different data sources.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Unison</title>
      <link>https://tedneward.github.io/Research/tools/unison/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/unison/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/bcpierce00/unison&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;It allows two replicas of a collection of files and directories to be stored on different hosts (or different disks on the same host), modified separately, and then brought up to date by propagating the changes in each replica to the other.&lt;/p&gt; 
&lt;p&gt;Unison has been in use for over 20 years and many people use it to synchronize data they care about.&lt;/p&gt; 
&lt;p&gt;Features:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt; &lt;p&gt;Unison works across platforms, allowing you to synchronize a Windows laptop with a Unix server, for example.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Unlike simple mirroring or backup utilities, Unison can deal with updates to both replicas of a distributed directory structure. Updates that do not conflict can be propagated automatically. Conflicting updates are detected and displayed.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Unlike many network filesystems, Unison copies data so that already-synchronized data can be read and written while offline.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Unlike most distributed filesystems, Unison is a user-level program that simply uses normal systems calls: there is no need to modify the kernel, to have superuser privileges on either host, or to have a FUSE implementation.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Unison works between any pair of machines connected to the internet, typically communicating over ssh, but also directly over TCP. It is careful with network bandwidth, and runs well over slow links. Transfers of small updates to large files are optimized using a compression protocol similar to rsync.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Unison is resilient to failure. It is careful to leave the replicas and its own private structures in a sensible state at all times, even in case of abnormal termination or communication failures.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Unison can run in &quot;repeat&quot; mode with a filesystem monitor, so that changes are synchronized soon after they happen.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Unison has a clear and precise specification.&lt;/p&gt; &lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Ventoy</title>
      <link>https://tedneward.github.io/Research/tools/ventoy/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/ventoy/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.ventoy.net/en/index.html&quot;&gt;Website&lt;/a&gt;&lt;/p&gt; 
&lt;h2&gt;Reading&lt;/h2&gt; 
&lt;h3&gt;Articles, Blogs, Essays&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.xda-developers.com/how-to-turn-an-old-usb-drive-into-the-ultimate-recovery-tool-for-almost-any-pc/&quot;&gt;Turn your old USB drive into a powerful recovery tool&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.xda-developers.com/operating-systems-to-keep-on-a-ventoy-usb-drive/&quot;&gt;I keep these operating systems on a Ventoy USB drive&lt;/a&gt; (Windows, Ubuntu, MX Linux, ZorinOS, Clonezilla, Memtest86+, GParted)&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Visual Python</title>
      <link>https://tedneward.github.io/Research/tools/visualpython/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/visualpython/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://visualpython.ai/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/visualpython/visualpython&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Spoon</title>
      <link>https://tedneward.github.io/Research/tools/spoon/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/spoon/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://spoon.gforge.inria.fr/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/INRIA/spoon&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;It parses source files to build a well-designed AST with powerful analysis and transformation API. It supports modern Java versions up to Java 20. Spoon is an official Inria open-source project, and member of the &lt;a href=&quot;https://www.ow2.org/&quot;&gt;OW2&lt;/a&gt; open-source consortium.&lt;/p&gt; 
&lt;h2&gt;Documentation&lt;/h2&gt; 
&lt;p&gt;The latest official documentation is available at &lt;a href=&quot;http://spoon.gforge.inria.fr/&quot;&gt;http://spoon.gforge.inria.fr/&lt;/a&gt;.&lt;/p&gt; 
&lt;h2&gt;Getting started in 2 seconds&lt;/h2&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;&lt;strong&gt;Java version:&lt;/strong&gt; Spoon version 10 and up requires Java 11 or later. Spoon 9.1.0 is the final Spoon release compatible with Java 8, and we do not plan to backport any bug fixes or features to Spoon 9. Note that Spoon can of course still consume source code for older versions of Java, but it needs JDK 11+ to run.&lt;/p&gt; 
&lt;/blockquote&gt; 
&lt;p&gt;Get latest stable version with Maven, see &lt;a href=&quot;https://search.maven.org/artifact/fr.inria.gforge.spoon/spoon-core&quot;&gt;https://search.maven.org/artifact/fr.inria.gforge.spoon/spoon-core&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;And start using it:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;CtClass l = Launcher.parseClass(&quot;class A { void m() { System.out.println(\&quot;yeah\&quot;);} }&quot;);
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Documentation:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Reference documentation: &lt;a href=&quot;http://spoon.gforge.inria.fr/&quot;&gt;http://spoon.gforge.inria.fr/&lt;/a&gt; (contains the content of the &lt;a href=&quot;https://github.com/INRIA/spoon/tree/master/doc&quot;&gt;doc folder&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;Code examples: &lt;a href=&quot;https://github.com/SpoonLabs/spoon-examples&quot;&gt;https://github.com/SpoonLabs/spoon-examples&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;Videos: &lt;a href=&quot;https://www.youtube.com/watch?v=ZZzdVTIu-OY&quot;&gt;Spoon: Getting Started - Simon Urli @ OW2Con’18 (Paris)&lt;/a&gt;, &lt;a href=&quot;https://www.youtube.com/watch?v=JcCIbjnkfD4&quot;&gt;Generate Test Assertion with Spoon - Benjamin Danglot @ OW2Con’17 (Paris)&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Contributing in 2 seconds&lt;/h2&gt; 
&lt;p&gt;Create your first pull request to improve the documentation, see &lt;a href=&quot;https://github.com/INRIA/spoon/tree/master/doc&quot;&gt;doc&lt;/a&gt;! Proceed with your first bug fix! The community is open-minded, respectful and patient. All external contributions are welcome.&lt;/p&gt; 
&lt;h2&gt;Design Philosophy&lt;/h2&gt; 
&lt;p&gt;R1) The Spoon metamodel is as close as possible to the language concepts.&lt;/p&gt; 
&lt;p&gt;R2) The Spoon model of a program is complete and sound.&lt;/p&gt; 
&lt;p&gt;R3) The text version of a Spoon model is well-formed and semantically equivalent to the original program.&lt;/p&gt; 
&lt;p&gt;R4) The analysis and transformation API is intuitive and regular.&lt;/p&gt; 
&lt;p&gt;R5) Transformation operators are designed to warn as fast as possible about invalid programs. This is done either with static type checking or with dynamic checks when the operators are used.&lt;/p&gt; 
&lt;p&gt;R6) When feasible, the text version of a Spoon model is close to the original one.&lt;/p&gt; 
&lt;h3&gt;Compiling&lt;/h3&gt; 
&lt;p&gt;To compile Spoon, you need a Java Development Kit (JDK) and Maven:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;git clone https://github.com/INRIA/spoon
cd spoon
mvn compile
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;To run the tests:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;mvn test
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;Download&lt;/h3&gt; 
&lt;p&gt;Latest version: &lt;a href=&quot;https://search.maven.org/remote_content?g=fr.inria.gforge.spoon&amp;amp;a=spoon-core&amp;amp;v=LATEST&amp;amp;c=jar-with-dependencies&quot;&gt;https://search.maven.org/remote_content?g=fr.inria.gforge.spoon&amp;amp;a=spoon-core&amp;amp;v=LATEST&amp;amp;c=jar-with-dependencies&lt;/a&gt; - &lt;a href=&quot;http://spoon.gforge.inria.fr/mvnsites/spoon-core/apidocs/index.html&quot;&gt;Javadoc&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Maven:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;&amp;lt;dependency&amp;gt;
    &amp;lt;groupId&amp;gt;fr.inria.gforge.spoon&amp;lt;/groupId&amp;gt;
    &amp;lt;artifactId&amp;gt;spoon-core&amp;lt;/artifactId&amp;gt;
    &amp;lt;!-- See rendered release value at http://spoon.gforge.inria.fr/ --&amp;gt;
    &amp;lt;version&amp;gt;&amp;lt;/version&amp;gt;
&amp;lt;/dependency&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
	</description>
    </item>
    <item>
      <title>Statiq</title>
      <link>https://tedneward.github.io/Research/tools/statiq/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/statiq/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://statiq.dev/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/statiqdev&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>SurfSense</title>
      <link>https://tedneward.github.io/Research/tools/surfsense/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/surfsense/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.surfsense.com/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/MODSetter/SurfSense&quot;&gt;Source&lt;/a&gt; | &lt;a href=&quot;https://www.surfsense.com/docs&quot;&gt;Docs&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Connect any LLM to your internal knowledge sources and chat with it in real time alongside your team. OSS alternative to NotebookLM, Perplexity, and Glean.&lt;/p&gt; 
&lt;p&gt;SurfSense is a highly customizable AI research agent, connected to external sources such as Search Engines (SearxNG, Tavily, LinkUp), Google Drive, Slack, Microsoft Teams, Linear, Jira, ClickUp, Confluence, BookStack, Gmail, Notion, YouTube, GitHub, Discord, Airtable, Google Calendar, Luma, Circleback, Elasticsearch, Obsidian and more to come.&lt;/p&gt; 
&lt;h2&gt;Podcast Sample&lt;/h2&gt; 
&lt;p&gt;&lt;a href=&quot;https://github.com/user-attachments/assets/a0a16566-6967-4374-ac51-9b3e07fbecd7&quot;&gt;https://github.com/user-attachments/assets/a0a16566-6967-4374-ac51-9b3e07fbecd7&lt;/a&gt;&lt;/p&gt; 
&lt;h2&gt;How to Use SurfSense&lt;/h2&gt; 
&lt;h3&gt;Self Hosted&lt;/h3&gt; 
&lt;p&gt;Run SurfSense on your own infrastructure for full data control and privacy.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Prerequisites:&lt;/strong&gt; &lt;a href=&quot;https://www.docker.com/products/docker-desktop/&quot;&gt;Docker Desktop&lt;/a&gt; must be installed and running.&lt;/p&gt; 
&lt;h4&gt;For Linux/MacOS users:&lt;/h4&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;curl -fsSL https://raw.githubusercontent.com/MODSetter/SurfSense/main/docker/scripts/install.sh | bash
&lt;/code&gt;&lt;/pre&gt; 
&lt;h4&gt;For Windows users:&lt;/h4&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;irm https://raw.githubusercontent.com/MODSetter/SurfSense/main/docker/scripts/install.ps1 | iex
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;The install script sets up &lt;a href=&quot;https://github.com/nicholas-fedor/watchtower&quot;&gt;Watchtower&lt;/a&gt; automatically for daily auto-updates. To skip it, add the &lt;code&gt;--no-watchtower&lt;/code&gt; flag.&lt;/p&gt; 
&lt;p&gt;For Docker Compose, manual installation, and other deployment options, see the &lt;a href=&quot;https://www.surfsense.com/docs/&quot;&gt;docs&lt;/a&gt;.&lt;/p&gt; 
&lt;h3&gt;How to Realtime Collaborate (Beta)&lt;/h3&gt; 
&lt;ol&gt; 
 &lt;li&gt;Go to Manage Members page and create an invite.&lt;/li&gt; 
&lt;/ol&gt; 
&lt;p align=&quot;center&quot;&gt;&lt;img src=&quot;https://github.com/user-attachments/assets/40ed7683-5aa6-48a0-a3df-00575528c392&quot; alt=&quot;Invite Members&quot;&gt;&lt;/p&gt; 
&lt;ol&gt; 
 &lt;li&gt;Teammate joins and that SearchSpace becomes shared.&lt;/li&gt; 
&lt;/ol&gt; 
&lt;p align=&quot;center&quot;&gt;&lt;img src=&quot;https://github.com/user-attachments/assets/ea4e1057-4d2b-4fd2-9ca0-cd19286a285e&quot; alt=&quot;Invite Join Flow&quot;&gt;&lt;/p&gt; 
&lt;ol&gt; 
 &lt;li&gt;Make chat shared.&lt;/li&gt; 
&lt;/ol&gt; 
&lt;p align=&quot;center&quot;&gt;&lt;img src=&quot;https://github.com/user-attachments/assets/17b93904-0888-4c3a-ac12-51a24a8ea26a&quot; alt=&quot;Make Chat Shared&quot;&gt;&lt;/p&gt; 
&lt;ol&gt; 
 &lt;li&gt;Your team can now chat in realtime.&lt;/li&gt; 
&lt;/ol&gt; 
&lt;p align=&quot;center&quot;&gt;&lt;img src=&quot;https://github.com/user-attachments/assets/83803ac2-fbce-4d93-aae3-85eb85a3053a&quot; alt=&quot;Realtime Chat&quot;&gt;&lt;/p&gt; 
&lt;ol&gt; 
 &lt;li&gt;Add comment to tag teammates.&lt;/li&gt; 
&lt;/ol&gt; 
&lt;p align=&quot;center&quot;&gt;&lt;img src=&quot;https://github.com/user-attachments/assets/3b04477d-8f42-4baa-be95-867c1eaeba87&quot; alt=&quot;Realtime Comments&quot;&gt;&lt;/p&gt; 
&lt;h2&gt;Key Features&lt;/h2&gt; 
&lt;table&gt; 
 &lt;thead&gt; 
  &lt;tr&gt;
   &lt;th&gt; Feature &lt;/th&gt;
   &lt;th&gt; Description &lt;/th&gt;
  &lt;/tr&gt; 
 &lt;/thead&gt; 
 &lt;tbody&gt; 
  &lt;tr&gt;
   &lt;td&gt; OSS Alternative &lt;/td&gt;
   &lt;td&gt; Drop in replacement for NotebookLM, Perplexity, and Glean with real time team collaboration &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; 50+ File Formats &lt;/td&gt;
   &lt;td&gt; Upload documents, images, videos via LlamaCloud, Unstructured, or Docling (local) &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; Hybrid Search &lt;/td&gt;
   &lt;td&gt; Semantic + Full Text Search with Hierarchical Indices and Reciprocal Rank Fusion &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; Cited Answers &lt;/td&gt;
   &lt;td&gt; Chat with your knowledge base and get Perplexity style cited responses &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; Deep Agent Architecture &lt;/td&gt;
   &lt;td&gt; Powered by &lt;a href=&quot;https://docs.langchain.com/oss/python/deepagents/overview&quot;&gt;LangChain Deep Agents&lt;/a&gt; planning, subagents, and file system access &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; Universal LLM Support &lt;/td&gt;
   &lt;td&gt; 100+ LLMs, 6000+ embedding models, all major rerankers via OpenAI spec &amp;amp; LiteLLM &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; Privacy First &lt;/td&gt;
   &lt;td&gt; Full local LLM support (vLLM, Ollama) your data stays yours &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; Team Collaboration &lt;/td&gt;
   &lt;td&gt; RBAC with Owner / Admin / Editor / Viewer roles, real time chat &amp;amp; comment threads &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; Podcast Generation &lt;/td&gt;
   &lt;td&gt; 3 min podcast in under 20 seconds; multiple TTS providers (OpenAI, Azure, Kokoro) &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; Browser Extension &lt;/td&gt;
   &lt;td&gt; Cross browser extension to save any webpage, including auth protected pages &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; 25+ Connectors &lt;/td&gt;
   &lt;td&gt; Search Engines, Google Drive, Slack, Teams, Jira, Notion, GitHub, Discord &amp;amp; &lt;a href=&quot;#external-sources&quot;&gt;more&lt;/a&gt; &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; Self Hostable &lt;/td&gt;
   &lt;td&gt; Open source, Docker one liner or full Docker Compose for production &lt;/td&gt;
  &lt;/tr&gt; 
 &lt;/tbody&gt; 
&lt;/table&gt; 
&lt;details&gt; &lt;summary&gt;&lt;b&gt;Full list of External Sources&lt;/b&gt;&lt;/summary&gt; &lt;a id=&quot;external-sources&quot;&gt;&lt;/a&gt; 
 &lt;p&gt;Search Engines (Tavily, LinkUp) · SearxNG · Google Drive · Slack · Microsoft Teams · Linear · Jira · ClickUp · Confluence · BookStack · Notion · Gmail · YouTube Videos · GitHub · Discord · Airtable · Google Calendar · Luma · Circleback · Elasticsearch · Obsidian, and more to come.&lt;/p&gt; 
&lt;/details&gt;
	</description>
    </item>
    <item>
      <title>Syncthing</title>
      <link>https://tedneward.github.io/Research/tools/syncthing/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/syncthing/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;http://syncthing.net/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/syncthing/syncthing&quot;&gt;Source&lt;/a&gt; | &lt;a href=&quot;https://docs.syncthing.net/intro/getting-started.html&quot;&gt;Getting Started&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Syncthing is a continuous file synchronization program. It synchronizes files between two or more computers. We strive to fulfill the goals below. The goals are listed in order of importance, the most important ones first.&lt;/p&gt; 
&lt;p&gt;Syncthing should be:&lt;/p&gt; 
&lt;ol&gt; 
 &lt;li&gt;Safe From Data Loss: Protecting the user&apos;s data is paramount. We take every reasonable precaution to avoid corrupting the user&apos;s files.&lt;/li&gt; 
 &lt;li&gt;Secure Against Attackers: Again, protecting the user&apos;s data is paramount. Regardless of our other goals, we must never allow the user&apos;s data to be susceptible to eavesdropping or modification by unauthorized parties.&lt;/li&gt; 
 &lt;li&gt;Easy to Use: Syncthing should be approachable, understandable, and inclusive.&lt;/li&gt; 
 &lt;li&gt;Automatic: User interaction should be required only when absolutely necessary.&lt;/li&gt; 
 &lt;li&gt;Universally Available: Syncthing should run on every common computer. We are mindful that the latest technology is not always available to every individual.&lt;/li&gt; 
 &lt;li&gt;For Individuals: Syncthing is primarily about empowering the individual user with safe, secure, and easy to use file synchronization.&lt;/li&gt; 
 &lt;li&gt;Everything Else: There are many things we care about that don&apos;t make it on to the list. It is fine to optimize for these values, as long as they are not in conflict with the stated goals above.&lt;/li&gt; 
&lt;/ol&gt;
	</description>
    </item>
    <item>
      <title>Terraform</title>
      <link>https://tedneward.github.io/Research/tools/terraform/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/terraform/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.terraform.io/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/hashicorp/terraform&quot;&gt;Source&lt;/a&gt; | &lt;a href=&quot;https://developer.hashicorp.com/terraform/tutorials?product_intent=terraform&quot;&gt;Tutorials&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Officially joins IBM as of 28 Feb 2025.&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://woodruff.dev/?s=terraform&amp;amp;e_search_props=e533c5b-883&quot;&gt;Woody&apos;s blogs&lt;/a&gt;:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;101: &lt;a href=&quot;https://woodruff.dev/terraform-101-your-first-steps-into-infrastructure-as-code/&quot;&gt;https://woodruff.dev/terraform-101-your-first-steps-into-infrastructure-as-code/&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;Crash course in HCL: &lt;a href=&quot;https://woodruff.dev/speaking-terraform-a-crash-course-in-hcl/&quot;&gt;https://woodruff.dev/speaking-terraform-a-crash-course-in-hcl/&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Reading&lt;/h2&gt; 
&lt;h3&gt;Articles/Blogs/Essays&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://dev.to/arbythecoder/my-first-week-with-terraform-the-struggles-nobody-talks-about-and-how-i-overcame-them-4m32&quot;&gt;My First Week with Terraform: The Struggles Nobody Talks About (And How I Overcame Them)&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Books&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://learning.oreilly.com/library/view/terraform-up-and/9781098116736/&quot;&gt;Terraform: Up &amp;amp; Running&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Tools&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/GoogleCloudPlatform/terraformer&quot;&gt;terraformer&lt;/a&gt;: CLI tool to generate terraform files from existing infrastructure (reverse Terraform); Infrastructure to Code 
  &lt;ul&gt; 
   &lt;li&gt;Article: &lt;a href=&quot;https://blog.cloudtechner.com/terraformer-write-back-your-infrastructure-to-code-9b86ca930457&quot;&gt;&quot;Terraformer: Write back your infrastructure to code&quot;&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>tldx</title>
      <link>https://tedneward.github.io/Research/tools/tldx/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/tldx/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://brandonyoung.dev/blog/introducing-tldx/&quot;&gt;Blog post&lt;/a&gt; | &lt;a href=&quot;https://github.com/brandonyoungdev/tldx&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;You give it some keywords, optionally add prefixes, suffixes, or TLDs. Then it checks what’s available.&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;$ tldx google
❌ google.com is not available
$ tldx openai -p get,use -s ly,hub -t com,io,ai --only-available
✔️ getopenaily.com is available
✔️ useopenaihub.io is available
   ...
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;&lt;strong&gt;Features&lt;/strong&gt;&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Keyword-based domain permutations (prefixes, suffixes, TLDs)&lt;/li&gt; 
 &lt;li&gt;Fast and concurrent RDAP availability checks&lt;/li&gt; 
 &lt;li&gt;Streams results as they’re found&lt;/li&gt; 
 &lt;li&gt;Optional filtering by domain length&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Quick Start&lt;/h2&gt; 
&lt;p&gt;&lt;code&gt;brew install brandonyoungdev/tldx/tldx&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;or&lt;/p&gt; 
&lt;p&gt;&lt;code&gt;brew tap brandonyoungdev/tldx; brew install tldx&lt;/code&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Tree-Sitter</title>
      <link>https://tedneward.github.io/Research/tools/treesitter/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/treesitter/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://tree-sitter.github.io/tree-sitter/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/tree-sitter/tree-sitter&quot;&gt;Source&lt;/a&gt; | &lt;a href=&quot;https://tree-sitter.github.io/tree-sitter/playground&quot;&gt;Playground&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Tree-sitter is a parser generator tool and an incremental parsing library. It can build a concrete syntax tree for a source file and efficiently update the syntax tree as the source file is edited. Tree-sitter aims to be:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;General enough to parse any programming language&lt;/li&gt; 
 &lt;li&gt;Fast enough to parse on every keystroke in a text editor&lt;/li&gt; 
 &lt;li&gt;Robust enough to provide useful results even in the presence of syntax errors&lt;/li&gt; 
 &lt;li&gt;Dependency-free so that the runtime library (which is written in pure C) can be embedded in any application&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;Language Bindings: C#, Go, Guile, Haskell, Java, Java (Android), JavaScript (Node.js), JavaScript (Wasm), Kotlin, Lua, OCaml, Odin, Perl, Python, Ruby, Rust, Swift&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Tuple (app)</title>
      <link>https://tedneward.github.io/Research/tools/tuple/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/tuple/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://tuple.app/&quot;&gt;Website&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>SpotBugs</title>
      <link>https://tedneward.github.io/Research/tools/spotbugs/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/spotbugs/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://spotbugs.github.io/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/spotbugs/spotbugs&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://spotbugs.github.io/&quot;&gt;SpotBugs&lt;/a&gt; is the spiritual successor of &lt;a href=&quot;https://github.com/findbugsproject/findbugs&quot;&gt;FindBugs&lt;/a&gt;, carrying on from the point where it left off with support of its community.&lt;/p&gt; 
&lt;p&gt;Bug descriptions found by SpotBugs can be found &lt;a href=&quot;https://spotbugs.readthedocs.io/en/latest/bugDescriptions.html&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Structurizr</title>
      <link>https://tedneward.github.io/Research/tools/structurizr/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/structurizr/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://structurizr.com/help/code&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/structurizr&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://structurizr.com/help/lite&quot;&gt;Structurizr Lite&lt;/a&gt;:&lt;/p&gt; 
&lt;p&gt;From a &lt;a href=&quot;https://dev.to/simonbrown/getting-started-with-structurizr-lite-27d0&quot;&gt;Dev.to post&lt;/a&gt;:&lt;/p&gt; 
&lt;ol&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Create a new directory:&lt;/strong&gt; First we need to create a directory somewhere to store our workspace.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Create a workspace.dsl file:&lt;/strong&gt; Next we need to create a file called workspace.dsl inside that directory, with the following content.&lt;/p&gt; &lt;/li&gt; 
&lt;/ol&gt; 
&lt;pre&gt;&lt;code&gt;workspace {

    model {
        user = person &quot;User&quot;
        softwareSystem = softwareSystem &quot;Software System&quot;

        user -&amp;gt; softwareSystem &quot;Uses&quot;
    }

    views {
        systemContext softwareSystem &quot;Diagram1&quot; {
            include *
            autoLayout
        }

        theme default
    }

}
&lt;/code&gt;&lt;/pre&gt; 
&lt;pre&gt;&lt;code&gt;![](https://static.structurizr.com/img/help/multiple-diagrams-1.png) 

and

![](https://static.structurizr.com/img/help/multiple-diagrams-2.png)


You can find more about the Structurizr DSL at https://github.com/structurizr/dsl, but essentially this DSL file says:

* Create a model with a user and a software system, where the user uses the software system.
* Create a system context view for the software system, adding the default set of elements, using auto-layout.
* Use the default theme for styling elements and relationships.
&lt;/code&gt;&lt;/pre&gt; 
&lt;ol&gt; 
 &lt;li&gt;&lt;strong&gt;Start Structurizr Lite:&lt;/strong&gt; Assuming that you have Docker installed, you can now start Structurizr Lite with the following commands:&lt;/li&gt; 
&lt;/ol&gt; 
&lt;pre&gt;&lt;code&gt;docker pull structurizr/lite
docker run -it --rm -p 8080:8080 -v PATH:/usr/local/structurizr structurizr/lite
&lt;/code&gt;&lt;/pre&gt; 
&lt;pre&gt;&lt;code&gt;Be sure to replace PATH with the full path to the directory created in step 1. For example, if the directory is located at /Users/alice/structurizr, the commands would be:
&lt;/code&gt;&lt;/pre&gt; 
&lt;pre&gt;&lt;code&gt;docker pull structurizr/lite
docker run -it --rm -p 8080:8080 -v /Users/alice/structurizr:/usr/local/structurizr structurizr/lite
&lt;/code&gt;&lt;/pre&gt; 
&lt;ol&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;View the diagram:&lt;/strong&gt; Open the workspace in a web browser by heading to &lt;a href=&quot;http://localhost:8080&quot;&gt;http://localhost:8080&lt;/a&gt; and you should see your diagram. If you make a change to the DSL file and save it, you should see that change immediately reflected when you refresh your web browser.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Add some documentation:&lt;/strong&gt; Let&apos;s add some documentation to describe our software system. To do this, create a subdirectory named docs and create a file named 01-context.md inside that subdirectory, with the following content:&lt;/p&gt; &lt;/li&gt; 
&lt;/ol&gt; 
&lt;pre&gt;&lt;code&gt;## Context

Here is a description of my software system...

![](embed:Diagram1)
&lt;/code&gt;&lt;/pre&gt; 
&lt;pre&gt;&lt;code&gt;Now change the content of the workspace.dsl file to be as follows (notice the addition of the !docs line):
&lt;/code&gt;&lt;/pre&gt; 
&lt;pre&gt;&lt;code&gt;workspace {

    model {
        user = person &quot;User&quot;
        softwareSystem = softwareSystem &quot;Software System&quot; {
            !docs docs
        }

        user -&amp;gt; softwareSystem &quot;Uses&quot;
    }

    views {
        systemContext softwareSystem &quot;Diagram1&quot; {
            include *
            autoLayout
        }

        theme default
    }

}
&lt;/code&gt;&lt;/pre&gt; 
&lt;pre&gt;&lt;code&gt;  Save all files, refresh your web browser, and click on the top-left button with the icon that looks like a book. You should now see the Markdown documentation page that we just created, which itself is embedding our existing system context diagram.
&lt;/code&gt;&lt;/pre&gt;
	</description>
    </item>
    <item>
      <title>Swagger to UML</title>
      <link>https://tedneward.github.io/Research/tools/swagger_to-uml/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/swagger_to-uml/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/nlohmann/swagger_to_uml&quot;&gt;Source&lt;/a&gt; &lt;em&gt;(Note: last update circa 2020)&lt;/em&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>SystemRescue</title>
      <link>https://tedneward.github.io/Research/tools/systemrescue/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/systemrescue/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.system-rescue.org/&quot;&gt;Website&lt;/a&gt;&lt;/p&gt; 
&lt;h2&gt;Reading&lt;/h2&gt; 
&lt;h3&gt;Articles&lt;/h3&gt; 
&lt;p&gt;&lt;a href=&quot;https://www.makeuseof.com/tools-always-keep-on-windows-rescue-usb-saved-countless-pcs/&quot;&gt;https://www.makeuseof.com/tools-always-keep-on-windows-rescue-usb-saved-countless-pcs/&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>(time)keeper</title>
      <link>https://tedneward.github.io/Research/tools/timekeeper/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/timekeeper/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://keeper.sh/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/ridafkih/keeper.sh&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Toad</title>
      <link>https://tedneward.github.io/Research/tools/toad/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/toad/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.batrachian.ai/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/batrachianai/toad&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;h2&gt;Resources&lt;/h2&gt; 
&lt;h3&gt;Articles, Blogs, Essays&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://willmcgugan.github.io/toad-released/&quot;&gt;Toad is a unified experience for AI in the terminal&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Tundra</title>
      <link>https://tedneward.github.io/Research/tools/tundra/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/tundra/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/deplinenoise/tundra&quot;&gt;Github&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>TurboSharp</title>
      <link>https://tedneward.github.io/Research/tools/turbosharp/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/turbosharp/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/Open-Inventions/TurboSharp&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Inspired by Borland&apos;s Turbo Pascal/Turbo C IDEs.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>SQLC</title>
      <link>https://tedneward.github.io/Research/tools/sqlc/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/sqlc/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://sqlc.dev/?utm_source=tldrwebdev&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/sqlc-dev/sqlc&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Subversion (SVN)</title>
      <link>https://tedneward.github.io/Research/tools/subversion/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/subversion/index.html</guid>
      	<description>
	&lt;h2&gt;Reading&lt;/h2&gt; 
&lt;h3&gt;Articles/Blogs/Essays&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://bobbrowning.me.uk/2025/12/23/why-svn-still-makes-sense-for-most-development-teams/&quot;&gt;Why SVN Still Makes Sense for Most Development Teams&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>SymmetricDS</title>
      <link>https://tedneward.github.io/Research/tools/symmetricds/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/symmetricds/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://symmetricds.org&quot;&gt;Website&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Tap</title>
      <link>https://tedneward.github.io/Research/tools/tap/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/tap/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.tatatap.com/&quot;&gt;Website&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>tldraw</title>
      <link>https://tedneward.github.io/Research/tools/tldraw/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/tldraw/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://tldraw.dev/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/tldraw/tldraw&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Tracer</title>
      <link>https://tedneward.github.io/Research/tools/tracer/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/tracer/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/SideChannelMarvels/Tracer&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://insinuator.net/2016/03/how-to-crack-a-white-box-without-much-effort/&quot;&gt;https://insinuator.net/2016/03/how-to-crack-a-white-box-without-much-effort/&lt;/a&gt;&lt;br&gt; - TracerPIN: TracerPin is a Intel PIN tool for generating execution traces of a running process.&lt;br&gt; - TracerGrind: TracerGrind is a Valgrind tool for generating execution traces of a running process.&lt;br&gt; - TraceGraph: TraceGraph is a GUI for visualizing execution traces produced by TracerGrind and TracerPin.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Tunneling tools</title>
      <link>https://tedneward.github.io/Research/tools/tunneling/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/tunneling/index.html</guid>
      	<description>
	&lt;h1&gt;Recommendations&lt;/h1&gt; 
&lt;p&gt;&lt;em&gt;(according to &lt;a href=&quot;https://github.com/anderspitman/awesome-tunneling&quot;&gt;https://github.com/anderspitman/awesome-tunneling&lt;/a&gt;)&lt;/em&gt;&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;For most people, I currently recommend &lt;a href=&quot;https://developers.cloudflare.com/cloudflare-one/connections/connect-apps/&quot;&gt;CloudFlare Tunnel&lt;/a&gt;. Although it&apos;s closed source, this is the production-quality service that gets the closest to achieving the dream. It&apos;s also a loss-leader for CloudFlare&apos;s other products which means they can offer it for free.&lt;/li&gt; 
 &lt;li&gt;If you want to self-host, there are many options. For something production ready &lt;a href=&quot;https://github.com/fatedier/frp&quot;&gt;frp&lt;/a&gt; is probably what you want. If you&apos;re a developer, I&apos;d recommend starting with my own &lt;a href=&quot;https://github.com/anderspitman/SirTunnel&quot;&gt;SirTunnel&lt;/a&gt; project and modifying it for your needs. For non-developers and those wanting more of a GUI experience, I created &lt;a href=&quot;https://boringproxy.io/&quot;&gt;boringproxy&lt;/a&gt;. It&apos;s my take on a comprehensive tunnel proxy solution. It&apos;s in beta but currently solves almost everything I want. Once the server is running this is a very easy tool to use and has some nice features.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h1&gt;Open source (at least with a reasonably permissive license)&lt;/h1&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/robbie-cahill/tunnelmole-client/&quot;&gt;Tunnelmole&lt;/a&gt; - Open source and optionally self hostable. The client and server are both written in TypeScript.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://telebit.cloud/&quot;&gt;Telebit&lt;/a&gt; - Written in JS. &lt;a href=&quot;https://git.coolaj86.com/coolaj86/telebit.js&quot;&gt;Code&lt;/a&gt;.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://tunnel.pyjam.as/&quot;&gt;tunnel.pyjam.as&lt;/a&gt; - No custom client; uses WireGuard directly instead. Written in Python. &lt;a href=&quot;https://gitlab.com/pyjam.as/tunnel&quot;&gt;source code&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://bitbucket.org/ValdikSS/dropbear-sshj/&quot;&gt;SSH-J.com&lt;/a&gt; - Public SSH Jump &amp;amp; Port Forwarding server. No software, no registration, just an anonymous SSH server for forwarding. Users are encouraged to use it for SSH exposure only, to preserve end-to-end encryption. No public ports, only in-SSH connectivity. Run &lt;code&gt;ssh ssh-j.com&lt;/code&gt; and it will display usage information.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/fatedier/frp&quot;&gt;frp&lt;/a&gt; &lt;a href=&quot;https://github.com/fatedier/frp/stargazers&quot;&gt;&lt;img src=&quot;https://img.shields.io/github/stars/fatedier/frp?style=flat&quot; alt=&quot;frp github stars badge&quot;&gt;&lt;/a&gt; - Comprehensive open alternative to ngrok. Supports UDP, and has a P2P mode. Supports multiplexing over TCP (single connection or pool), QUIC, and KCP.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/inconshreveable/ngrok&quot;&gt;ngrok 1.0&lt;/a&gt; &lt;a href=&quot;https://github.com/inconshreveable/ngrok/stargazers&quot;&gt;&lt;img src=&quot;https://img.shields.io/github/stars/inconshreveable/ngrok?style=flat&quot; alt=&quot;ngrok 1.0 github stars badge&quot;&gt;&lt;/a&gt; - Original version of ngrok. No longer developed in favor of the commercial 2.0 version.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/localtunnel&quot;&gt;localtunnel&lt;/a&gt; &lt;a href=&quot;https://github.com/localtunnel/localtunnel/stargazers&quot;&gt;&lt;img src=&quot;https://img.shields.io/github/stars/localtunnel/localtunnel?style=flat&quot; alt=&quot;localtunnel github stars badge&quot;&gt;&lt;/a&gt; - Written in node. Popular suggestion.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/sshuttle/sshuttle&quot;&gt;sshuttle&lt;/a&gt; &lt;a href=&quot;https://github.com/sshuttle/sshuttle/stargazers&quot;&gt;&lt;img src=&quot;https://img.shields.io/github/stars/sshuttle/sshuttle?style=flat&quot; alt=&quot;sshuttle github stars badge&quot;&gt;&lt;/a&gt; - Open source project originally from one of the founders of Tailscale. Server doesn&apos;t require root; client does. Explicitly designed to avoid TCP-over-TCP issues.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/jpillora/chisel&quot;&gt;chisel&lt;/a&gt; &lt;a href=&quot;https://github.com/jpillora/chisel/stargazers&quot;&gt;&lt;img src=&quot;https://img.shields.io/github/stars/jpillora/chisel?style=flat&quot; alt=&quot;chisel github stars badge&quot;&gt;&lt;/a&gt; - SSH under the hood, but still uses a custom client binary. Supports auto certs from LetsEncrypt. Written in Go.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/ekzhang/bore&quot;&gt;bore&lt;/a&gt; &lt;a href=&quot;https://github.com/ekzhang/bore/stargazers&quot;&gt;&lt;img src=&quot;https://img.shields.io/github/stars/ekzhang/bore?style=flat&quot; alt=&quot;bore github stars badge&quot;&gt;&lt;/a&gt; - Minimal tunneling solution. MIT Licensed. Written in Rust.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/rapiz1/rathole&quot;&gt;rathole&lt;/a&gt; &lt;a href=&quot;https://github.com/rapiz1/rathole/stargazers&quot;&gt;&lt;img src=&quot;https://img.shields.io/github/stars/rapiz1/rathole?style=flat&quot; alt=&quot;rathole github stars badge&quot;&gt;&lt;/a&gt; - Similar to frp, including the config format, but with improved performance. Low resource consumption. Hot reload. Written in Rust.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/beyondcode/expose&quot;&gt;expose&lt;/a&gt; &lt;a href=&quot;https://github.com/beyondcode/expose/stargazers&quot;&gt;&lt;img src=&quot;https://img.shields.io/github/stars/beyondcode/expose?style=flat&quot; alt=&quot;expose github stars badge&quot;&gt;&lt;/a&gt; - ngrok alternative written in PHP.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/antoniomika/sish&quot;&gt;sish&lt;/a&gt; &lt;a href=&quot;https://github.com/antoniomika/sish/stargazers&quot;&gt;&lt;img src=&quot;https://img.shields.io/github/stars/antoniomika/sish?style=flat&quot; alt=&quot;sish github stars badge&quot;&gt;&lt;/a&gt; - Open source ngrok/serveo alternative. SSH-based but uses a custom server written in Go. Supports WebSocket tunneling.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/mmatczuk/go-http-tunnel&quot;&gt;go-http-tunnel&lt;/a&gt; &lt;a href=&quot;https://github.com/mmatczuk/go-http-tunnel/stargazers&quot;&gt;&lt;img src=&quot;https://img.shields.io/github/stars/mmatczuk/go-http-tunnel?style=flat&quot; alt=&quot;go-http-tunnel github stars badge&quot;&gt;&lt;/a&gt; - Uses a single HTTP/2 connection for muxing. Need to manually generate certs for server and clients.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/pgrok/pgrok&quot;&gt;pgrok/pgrok&lt;/a&gt; &lt;a href=&quot;https://github.com/pgrok/pgrok/stargazers&quot;&gt;&lt;img src=&quot;https://img.shields.io/github/stars/pgrok/pgrok?style=flat&quot; alt=&quot;pgrok github stars badge&quot;&gt;&lt;/a&gt; - A multi-tenant HTTP reverse tunnel solution through SSH remote port forwarding.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://tunnelto.dev/&quot;&gt;tunnelto&lt;/a&gt; &lt;a href=&quot;https://github.com/agrinman/tunnelto/stargazers&quot;&gt;&lt;img src=&quot;https://img.shields.io/github/stars/agrinman/tunnelto?style=flat&quot; alt=&quot;tunnelto github stars badge&quot;&gt;&lt;/a&gt; - Open source (MIT). Written in Rust.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/erebe/wstunnel&quot;&gt;wstunnel&lt;/a&gt; &lt;a href=&quot;https://github.com/erebe/wstunnel/stargazers&quot;&gt;&lt;img src=&quot;https://img.shields.io/github/stars/erebe/wstunnel?style=flat&quot; alt=&quot;wstunnel github stars badge&quot;&gt;&lt;/a&gt; - Proxies over WebSockets. Focus on proxying from behind networks that block certain protocols. Written in Haskell with executables provided.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://zrok.io/&quot;&gt;zrok&lt;/a&gt; &lt;a href=&quot;https://github.com/openziti/zrok/stargazers&quot;&gt;&lt;img src=&quot;https://img.shields.io/github/stars/openziti/zrok?style=flat&quot; alt=&quot;zrok github stars badge&quot;&gt;&lt;/a&gt; - Aims for effortless sharing both publicly and privately. Supports multiple types of resources, including HTTP endpoints and files. Built on OpenZiti (see overlay section below). Apache 2 License. Written in Go.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://boringproxy.io/&quot;&gt;boringproxy&lt;/a&gt; &lt;a href=&quot;https://github.com/boringproxy/boringproxy/stargazers&quot;&gt;&lt;img src=&quot;https://img.shields.io/github/stars/boringproxy/boringproxy?style=flat&quot; alt=&quot;boringproxy github stars badge&quot;&gt;&lt;/a&gt; - Designed to be very easy to use. No config files. Clients can be remote-controlled through a simple WebUI and/or REST API on the server.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/anderspitman/SirTunnel&quot;&gt;SirTunnel&lt;/a&gt; &lt;a href=&quot;https://github.com/anderspitman/SirTunnel/stargazers&quot;&gt;&lt;img src=&quot;https://img.shields.io/github/stars/anderspitman/SirTunnel?style=flat&quot; alt=&quot;SirTunnel github stars badge&quot;&gt;&lt;/a&gt; - Minimal, self-hosted, 0-config alternative to ngrok. Similar to sish but leverages Caddy+OpenSSH rather than custom server code.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/azimjohn/jprq&quot;&gt;jprq&lt;/a&gt; &lt;a href=&quot;https://github.com/azimjohn/jprq/stargazers&quot;&gt;&lt;img src=&quot;https://img.shields.io/github/stars/azimjohn/jprq?style=flat&quot; alt=&quot;jprq github stars badge&quot;&gt;&lt;/a&gt; - Proxies over WebSockets. Written in Python.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://pagekite.net/&quot;&gt;PageKite&lt;/a&gt; &lt;a href=&quot;https://github.com/pagekite/PyPagekite/stargazers&quot;&gt;&lt;img src=&quot;https://img.shields.io/github/stars/pagekite/PyPagekite?style=flat&quot; alt=&quot;pagekite github stars badge&quot;&gt;&lt;/a&gt; - Comprehensive open source solution with hosted options.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/sandialabs/wiretap&quot;&gt;Wiretap&lt;/a&gt; &lt;a href=&quot;https://github.com/sandialabs/wiretap/stargazers&quot;&gt;&lt;img src=&quot;https://img.shields.io/github/stars/sandialabs/wiretap?style=flat&quot; alt=&quot;wiretap github stars badge&quot;&gt;&lt;/a&gt; - Transparent tunneling over WireGuard (UDP) using userspace network stack. Root not required on server. Supports multiple clients and servers. Written in Go.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/q3k/crowbar&quot;&gt;Crowbar&lt;/a&gt; &lt;a href=&quot;https://github.com/q3k/crowbar/stargazers&quot;&gt;&lt;img src=&quot;https://img.shields.io/github/stars/q3k/crowbar?style=flat&quot; alt=&quot;crowbar github stars badge&quot;&gt;&lt;/a&gt; - Tunnels TCP connections over HTTP GET and POST requests.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/skx/tunneller&quot;&gt;tunneller&lt;/a&gt; &lt;a href=&quot;https://github.com/skx/tunneller/stargazers&quot;&gt;&lt;img src=&quot;https://img.shields.io/github/stars/skx/tunneller?style=flat&quot; alt=&quot;tunneller github stars badge&quot;&gt;&lt;/a&gt; - Open source. Written in Go.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/cmars/onionpipe&quot;&gt;onionpipe&lt;/a&gt; &lt;a href=&quot;https://github.com/cmars/onionpipe/stargazers&quot;&gt;&lt;img src=&quot;https://img.shields.io/github/stars/cmars/onionpipe?style=flat&quot; alt=&quot;onionpipe github stars badge&quot;&gt;&lt;/a&gt; - Onion addresses for anything. &lt;code&gt;onionpipe&lt;/code&gt; forwards ports on the local host to remote Onion addresses as Tor hidden services and vice-versa. Written in Go.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/koding/tunnel&quot;&gt;tunnel&lt;/a&gt; &lt;a href=&quot;https://github.com/koding/tunnel/stargazers&quot;&gt;&lt;img src=&quot;https://img.shields.io/github/stars/koding/tunnel?style=flat&quot; alt=&quot;tunnel github stars badge&quot;&gt;&lt;/a&gt; - This one is a Golang library, not a program you can just run. However, it looks easy to use for creating custom solutions. Uses a single TCP socket, and &lt;a href=&quot;https://github.com/hashicorp/yamux&quot;&gt;yamux&lt;/a&gt; for multiplexing.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.proxy.jetzt/&quot;&gt;jerson/pgrok&lt;/a&gt; &lt;a href=&quot;https://github.com/jerson/pgrok/stargazers&quot;&gt;&lt;img src=&quot;https://img.shields.io/github/stars/jerson/pgrok?style=flat&quot; alt=&quot;pgrok github stars badge&quot;&gt;&lt;/a&gt; - Fork of ngrok 1.0, with more recent commits. Archived.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/vitobotta/docker-tunnel&quot;&gt;docker-tunnel&lt;/a&gt; &lt;a href=&quot;https://github.com/vitobotta/docker-tunnel/stargazers&quot;&gt;&lt;img src=&quot;https://img.shields.io/github/stars/vitobotta/docker-tunnel?style=flat&quot; alt=&quot;docker-tunnel github stars badge&quot;&gt;&lt;/a&gt; - Simple Docker-based nginx+SSH solution.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/fasmide/remotemoe&quot;&gt;remotemoe&lt;/a&gt; &lt;a href=&quot;https://github.com/fasmide/remotemoe/stargazers&quot;&gt;&lt;img src=&quot;https://img.shields.io/github/stars/fasmide/remotemoe?style=flat&quot; alt=&quot;remotemoe github stars badge&quot;&gt;&lt;/a&gt; - SSH-based, with custom golang server. Does some cool unique things. Instead of just plain tunnels, it drops you into a basic CLI UI that offers several useful commands interactively, such as adding a custom hostname. Also allows end-to-end encryption for both HTTPS and upstream SSH. Doesn&apos;t appear to offer non-e2e HTTPS, ie no auto Let&apos;s Encrypt support.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/berstend/hypertunnel&quot;&gt;hypertunnel&lt;/a&gt; &lt;a href=&quot;https://github.com//berstend/hypertunnel/stargazers&quot;&gt;&lt;img src=&quot;https://img.shields.io/github/stars/berstend/hypertunnel?style=flat&quot; alt=&quot;frp github stars badge&quot;&gt;&lt;/a&gt; - Public server appears to be down. MIT Licensed. Written in JavaScript.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/ntnj/tunwg&quot;&gt;tunwg&lt;/a&gt; &lt;a href=&quot;https://github.com/ntnj/tunwg/stargazers&quot;&gt;&lt;img src=&quot;https://img.shields.io/github/stars/ntnj/tunwg?style=flat&quot; alt=&quot;tunwg github stars badge&quot;&gt;&lt;/a&gt; - Wireguard in userspace based. Offers end to end encrypted TLS with LetsEncrypt certificates generated automatically by clients, with support for custom domains. Server can be self-hosted and doesn&apos;t require storing any data.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/ao-space/gt&quot;&gt;gt&lt;/a&gt;&lt;a href=&quot;https://github.com/ao-space/gt/stargazers&quot;&gt;&lt;img src=&quot;https://img.shields.io/github/stars/ao-space/gt?style=flat&quot; alt=&quot;gt github stars badge&quot;&gt;&lt;/a&gt; - Supports peer-to-peer direct connection (P2P) and Internet relay. Focus on performance. Written in Go.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/CypherpunkArmory/holepunch&quot;&gt;holepunch&lt;/a&gt; &lt;a href=&quot;https://github.com/CypherpunkArmory/holepunch/stargazers&quot;&gt;&lt;img src=&quot;https://img.shields.io/github/stars/CypherpunkArmory/holepunch?style=flat&quot; alt=&quot;holepunch github stars badge&quot;&gt;&lt;/a&gt; - Has nice hosted solution. Uses SSH for muxing.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://tunnel.staqlab.com/&quot;&gt;StaqLab Tunnel&lt;/a&gt; &lt;a href=&quot;https://github.com/abhishekq61/tunnel-client/stargazers&quot;&gt;&lt;img src=&quot;https://img.shields.io/github/stars/abhishekq61/tunnel-client?style=flat&quot; alt=&quot;staqlab github stars badge&quot;&gt;&lt;/a&gt; - SSH-based. Client is open source. Server doesn&apos;t appear to be.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/LiljebergXYZ/tnnlink&quot;&gt;tnnlink&lt;/a&gt; &lt;a href=&quot;https://github.com/LiljebergXYZ/tnnlink/stargazers&quot;&gt;&lt;img src=&quot;https://img.shields.io/github/stars/LiljebergXYZ/tnnlink?style=flat&quot; alt=&quot;tnnlink github stars badge&quot;&gt;&lt;/a&gt; - SSH-based. Golang. Not maintained.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/DigitallyRefined/docker-wireguard-tunnel&quot;&gt;docker-wireguard-tunnel&lt;/a&gt; &lt;a href=&quot;https://github.com/DigitallyRefined/docker-wireguard-tunnel/stargazers&quot;&gt;&lt;img src=&quot;https://img.shields.io/github/stars/DigitallyRefined/docker-wireguard-tunnel?style=flat&quot; alt=&quot;ngtor github stars badge&quot;&gt;&lt;/a&gt; - Connect two or more Docker servers together sharing container ports between them via a WireGuard tunnel.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/theborakompanioni/ngtor&quot;&gt;ngtor&lt;/a&gt; &lt;a href=&quot;https://github.com/theborakompanioni/ngtor/stargazers&quot;&gt;&lt;img src=&quot;https://img.shields.io/github/stars/theborakompanioni/ngtor?style=flat&quot; alt=&quot;ngtor github stars badge&quot;&gt;&lt;/a&gt; - Easily expose local services via Tor. Written in Java.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/Degola/punchmole/&quot;&gt;Punchmole&lt;/a&gt; &lt;a href=&quot;https://github.com/Degola/punchmole/stargazers&quot;&gt;&lt;img src=&quot;https://img.shields.io/github/stars/Degola/punchmole?style=flat&quot; alt=&quot;punchmole github stars badge&quot;&gt;&lt;/a&gt; - Can be integrated directly into an existing Node.js project. Written in JavaScript.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h1&gt;Commercial/Closed source&lt;/h1&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://ngrok.com/&quot;&gt;ngrok 2.0&lt;/a&gt; - Probably the gold standard and most popular. Closed source. Lots of features, including TLS and TCP tunnels. Doesn&apos;t require root to run client.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://developers.cloudflare.com/cloudflare-one/connections/connect-apps/install-and-setup&quot;&gt;CloudFlare Tunnel&lt;/a&gt; - Excellent free option. Nicely integrates tunneling with the rest of Cloudflare&apos;s products, which include DNS and auto HTTPS. Client &lt;a href=&quot;https://github.com/cloudflare/cloudflared&quot;&gt;source code&lt;/a&gt; is Apache 2.0 licensed and written in Golang.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://beeceptor.com/&quot;&gt;Beeceptor&lt;/a&gt; - Goes beyond tunneling. Rest API mocking and intercepting tool. You can view the live requests and send mocked response. Written in JavaScript.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://pinggy.io/&quot;&gt;Pinggy&lt;/a&gt; - SSH based single command HTTPS / TCP / TLS tunnels, no downloads required. Rich terminal interface and a web debugger. Free tier - 60 min timeout. Paid tier allows custom domains with built-in Let&apos;s Encrypt certificates.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://loophole.cloud/&quot;&gt;Loophole&lt;/a&gt; - Offers end-to-end TLS encryption with the client automatically getting certs from Let&apos;s Encrypt. QR codes for URL sharing. Client is open source. Can serve a local directory over WebDAV. MIT License. Written in Go.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://localhost.run/&quot;&gt;localhost.run&lt;/a&gt; - Simple hosted SSH option. Supports custom domains for a cost.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://packetriot.com&quot;&gt;Packetriot&lt;/a&gt; - Comprehensive alternative to ngrok. HTTP Inspector, Let&apos;s Encrypt integration, doesn&apos;t require root and Linux repos for apt, yum and dnf. Enterprise licenses and self-hosted option.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://hoppy.network/&quot;&gt;Hoppy&lt;/a&gt; - WireGuard-based. Provides static IPv4 and IPv6 addresses for your machines, which is a simple and useful level of abstraction. Targeted towards self-hosters and people behind NATs.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://gw.run/&quot;&gt;gw.run&lt;/a&gt; - Specifically focusing on securely exposing internal web apps to a group of people; not for publicly facing apps. Share access via email address then allow users to log in with common login providers like Google.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://sshreach.me/&quot;&gt;SSHReach.me&lt;/a&gt; - Paid SSH-based option. Uses a simple python script.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://kubesail.com/&quot;&gt;KubeSail&lt;/a&gt; - Company offering tunneling, dynamic DNS, and other services for self-hosting with Kubernetes.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://inlets.dev/&quot;&gt;inlets&lt;/a&gt; - Used to be &lt;a href=&quot;https://github.com/inlets/inlets-archived&quot;&gt;open source&lt;/a&gt;; now focused on a polished commercial offering. Designed to work well with Kubernetes.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://localtonet.com/&quot;&gt;LocalToNet&lt;/a&gt; - Supports UDP. Free for a single tunnel. Paid supports custom domains.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://localxpose.io&quot;&gt;LocalXpose&lt;/a&gt; - Looks like a solid paid option, with a limited free tier.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://tabserve.dev&quot;&gt;Tabserve.dev&lt;/a&gt; - Web UI that runs entirely in the browser and uses a Cloudflare Worker for https.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://serveo.net&quot;&gt;Serveo&lt;/a&gt; - SSH-based, signup optional, offering HTTP(S) and TCP tunneling and SSH jump host forwarding capabilities.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h1&gt;Overlay networks and other advanced tools&lt;/h1&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/juanfont/headscale&quot;&gt;headscale&lt;/a&gt; &lt;a href=&quot;https://github.com/juanfont/headscale/stargazers&quot;&gt;&lt;img src=&quot;https://img.shields.io/github/stars/juanfont/headscale?style=flat&quot; alt=&quot;headscale github stars badge&quot;&gt;&lt;/a&gt; - Open source implementation of Tailscale control server. Can be used with Tailscale&apos;s official open source client. Written in Go.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.tailscale.com/&quot;&gt;Tailscale&lt;/a&gt; &lt;a href=&quot;https://github.com/tailscale/tailscale/stargazers&quot;&gt;&lt;img src=&quot;https://img.shields.io/github/stars/tailscale/tailscale?style=flat&quot; alt=&quot;tailscale github stars badge&quot;&gt;&lt;/a&gt; - Built on WireGuard. Easy to use. Control server is closed source. Client &lt;a href=&quot;https://github.com/tailscale&quot;&gt;code&lt;/a&gt; available with a BSD3 license + separate patents file.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://goteleport.com/&quot;&gt;Teleport&lt;/a&gt; &lt;a href=&quot;https://github.com/gravitational/teleport&quot;&gt;&lt;img src=&quot;https://img.shields.io/github/stars/gravitational/teleport?style=flat&quot; alt=&quot;teleport github stars badge&quot;&gt;&lt;/a&gt; - Comprehensive control plane tool, but also supports &lt;a href=&quot;https://goteleport.com/docs/application-access/introduction/&quot;&gt;accessing apps&lt;/a&gt; behind NATs. Written in Go.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/slackhq/nebula&quot;&gt;Nebula&lt;/a&gt; - &lt;a href=&quot;https://github.com/zerotier/slackhq/nebula&quot;&gt;&lt;img src=&quot;https://img.shields.io/github/stars/slackhq/nebula?style=flat&quot; alt=&quot;nebula github stars badge&quot;&gt;&lt;/a&gt; Peer-to-peer overlay network. Developed and used internally by Slack. Similar to Tailscale but completely open source. Doesn&apos;t use WireGuard. Written in Go.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.zerotier.com/&quot;&gt;ZeroTier&lt;/a&gt; - &lt;a href=&quot;https://github.com/zerotier/ZeroTierOne/stargazers&quot;&gt;&lt;img src=&quot;https://img.shields.io/github/stars/zerotier/ZeroTierOne?style=flat&quot; alt=&quot;zerotier github stars badge&quot;&gt;&lt;/a&gt; Layer 2 overlay network. They take decentralization seriously, and like to say &quot;decentralize until it hurts, then centralize until it works.&quot; Written in C++.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/gravitl/netmaker&quot;&gt;Netmaker&lt;/a&gt; &lt;a href=&quot;https://github.com/gravitl/netmaker/stargazers&quot;&gt;&lt;img src=&quot;https://img.shields.io/github/stars/gravitl/netmaker?style=flat&quot; alt=&quot;netmaker github stars badge&quot;&gt;&lt;/a&gt; - Layer 3 peer-to-peer overlay network and private DNS. Similar to Tailscale, but with a self-hosted server/admin UI. Runs kernel WireGuard so very fast. Not FOSS, but source is available. Written in Go.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/netbirdio/netbird&quot;&gt;NetBird&lt;/a&gt; &lt;a href=&quot;https://github.com/netbirdio/netbird/stargazers&quot;&gt;&lt;img src=&quot;https://img.shields.io/github/stars/netbirdio/netbird?style=flat&quot; alt=&quot;netbird github stars badge&quot;&gt;&lt;/a&gt; - NetBird is an open-source VPN management platform built on top of WireGuard® making it easy to create secure private networks for your organization or home.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.firezone.dev/&quot;&gt;Firezone&lt;/a&gt; &lt;a href=&quot;https://github.com/firezone/firezone&quot;&gt;&lt;img src=&quot;https://img.shields.io/github/stars/firezone/firezone?style=flat&quot; alt=&quot;firezone github stars badge&quot;&gt;&lt;/a&gt; - Layer 3/4 overlay network. Runs on kernel WireGuard® and supports SSO using generic OIDC/SAML connectors. Distributed under apache 2.0 license and written in Elixir/Rust.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/tonarino/innernet&quot;&gt;innernet&lt;/a&gt; &lt;a href=&quot;https://github.com/tonarino/innernet/stargazers&quot;&gt;&lt;img src=&quot;https://img.shields.io/github/stars/tonarino/innernet?style=flat&quot; alt=&quot;innernet github stars badge&quot;&gt;&lt;/a&gt; - Similar to Netmaker, nebula, and Tailscale. Takes advantage of existing networking concepts like CIDRs and the security properties of WireGuard to turn your computer&apos;s basic IP networking into more powerful ACL primitives. Written in Rust.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://pritunl.com/&quot;&gt;Pritunl&lt;/a&gt; &lt;a href=&quot;https://github.com/pritunl/pritunl/stargazers&quot;&gt;&lt;img src=&quot;https://img.shields.io/github/stars/pritunl/pritunl?style=flat&quot; alt=&quot;pritunl github stars badge&quot;&gt;&lt;/a&gt; - Seems quite comprehensive and complicated. OpenVPN, WireGuard, and IPSec support.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/gsliepen/tinc&quot;&gt;Tinc&lt;/a&gt; &lt;a href=&quot;https://github.com/gsliepen/tinc/stargazers&quot;&gt;&lt;img src=&quot;https://img.shields.io/github/stars/gsliepen/tinc?style=flat&quot; alt=&quot;tinc github stars badge&quot;&gt;&lt;/a&gt; - Tinc is a peer-to-peer VPN daemon that supports VPNs with an arbitrary number of nodes. Instead of configuring tunnels, you give tinc the location and public key of a few nodes in the VPN. After making the initial connections to those nodes, tinc will learn about all other nodes on the VPN, and will make connections automatically. When direct connections are not possible, data will be forwarded by intermediate nodes. Written in C.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://openziti.github.io&quot;&gt;OpenZiti&lt;/a&gt; - &lt;a href=&quot;https://github.com/openziti/ziti/stargazers&quot;&gt;&lt;img src=&quot;https://img.shields.io/github/stars/openziti/ziti?style=flat&quot; alt=&quot;OpenZiti github stars badge&quot;&gt;&lt;/a&gt; - Overlay network. The goal of OpenZiti is to extend zero trust all the way into your application, not just to your network. Apache 2.0 license. Written in Go.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/zufardhiyaulhaq/ngrok-operator&quot;&gt;Ngrok-operator&lt;/a&gt; &lt;a href=&quot;https://github.com/zufardhiyaulhaq/ngrok-operator/stargazers&quot;&gt;&lt;img src=&quot;https://img.shields.io/github/stars/zufardhiyaulhaq/ngrok-operator?style=flat&quot; alt=&quot;ngrok operator github stars badge&quot;&gt;&lt;/a&gt; - Ngrok but integrated with Kubernetes, allows developers on private kubernetes to easily access their services via Ngrok.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/FyraLabs/chisel-operator/&quot;&gt;chisel-operator&lt;/a&gt; &lt;a href=&quot;https://github.com/FyraLabs/chisel-operator/stargazers&quot;&gt;&lt;img src=&quot;https://img.shields.io/github/stars/FyraLabs/chisel-operator?style=flat&quot; alt=&quot;chisel operator github stars badge&quot;&gt;&lt;/a&gt; - Kubernetes integration for Chisel. Similar functionality to inlets. MIT License. Written in Rust.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h1&gt;Reference&lt;/h1&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://jerrington.me/posts/2019-01-29-self-hosted-ngrok.html&quot;&gt;Roll your own Ngrok with Nginx, Letsencrypt, and SSH reverse tunnelling&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://dev.to/k4ml/poor-man-ngrok-with-tcp-proxy-and-ssh-reverse-tunnel-1fm&quot;&gt;Poor man&apos;s ngrok with tcp proxy and ssh reverse tunnel&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://dev.to/azimjohn/how-i-built-ngrok-alternative-3n0g&quot;&gt;How I built Ngrok Alternative (jprq)&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://stackoverflow.com/a/52614266/943814&quot;&gt;Great SO answer by AJ ONeal about how these things work&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://youtu.be/E1Q2MWGCADo&quot;&gt;Talk by AJ ONeal about tunneling tech&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://morph027.gitlab.io/blog/localtunnel-ngrok/&quot;&gt;ngrok alternative: localtunnel + Caddy + Lets Encrypt&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Spoofax Language Workbench</title>
      <link>https://tedneward.github.io/Research/tools/spoofax/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/spoofax/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;http://www.metaborg.org/en/latest&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/metaborg&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;The platform provides the following ingredients:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Meta-languages for high-level declarative language definition&lt;/li&gt; 
 &lt;li&gt;An interactive environment for developing languages using these meta-languages&lt;/li&gt; 
 &lt;li&gt;Code generators that produces parsers, type checkers, compilers, interpreters, and other tools from language definitions&lt;/li&gt; 
 &lt;li&gt;Generation of full-featured Eclipse editor plugins from language definitions&lt;/li&gt; 
 &lt;li&gt;Generation of full-featured IntelliJ editor plugins from language definitions (experimental)&lt;/li&gt; 
 &lt;li&gt;An API for programmatically combining the components of a language implementation&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;With Spoofax you can focus on the essence of language definition and ignore irrelevant implementation details.&lt;/p&gt; 
&lt;p&gt;Spoofax is the integration of many different tools, compilers, (meta-)languages, (meta-)libraries, and runtime components. This integration is made concrete in the spoofax-releng Git repository on GitHub. This repository contains all components via Git submodules, which are updated by our build farm that builds Spoofax whenever one of its components in a submodule changes.&lt;/p&gt; 
&lt;p&gt;Spoofax currently contains the following subcomponents as submodules:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;releng - release engineering scripts for managing and building the spoofax-releng repostory.&lt;/li&gt; 
 &lt;li&gt;Java libraries and runtimes 
  &lt;ul&gt; 
   &lt;li&gt;mb-rep - libraries for program representation such as abstract terms&lt;/li&gt; 
   &lt;li&gt;mb-exec - Stratego interpreter and utilities&lt;/li&gt; 
   &lt;li&gt;jsglr - JSGLR parser&lt;/li&gt; 
   &lt;li&gt;spoofax - Spoofax Core, a cross platform API to Spoofax languages&lt;/li&gt; 
   &lt;li&gt;spoofax-maven - Maven integration for Spoofax Core&lt;/li&gt; 
   &lt;li&gt;spoofax-sunshine - Command-line integration for Spoofax Core&lt;/li&gt; 
   &lt;li&gt;spoofax-eclipse - Eclipse plugin for Spoofax Core&lt;/li&gt; 
   &lt;li&gt;spoofax-intellij - IntelliJ plugin for Spoofax Core&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Meta-languages and libraries 
  &lt;ul&gt; 
   &lt;li&gt;esv - Editor service language&lt;/li&gt; 
   &lt;li&gt;sdf - &lt;a href=&quot;/formats/sdf&quot;&gt;Syntax Definition Formalisms&lt;/a&gt;, containing the SDF2 and SDF 3 languages&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://strategoxt.org/Stratego/StrategoLanguage.html&quot;&gt;stratego and strategoxt&lt;/a&gt; - Stratego compiler, runtime, and editor - &quot;Stratego is a small and efficient domain-specific language for program transformation. It is based on the paradigm of programmable rewriting strategies, which makes it extremely well-suited for traversing and transforming all kinds of tree structures. Its library and supporting tools are geared towards processing computer programs in the form of concrete or abstract syntax trees, as produced by text parsers.&quot;&lt;/li&gt; 
   &lt;li&gt;nabl - Name binding languages, containing the NaBL and NaBL2 languages, and support libraries for NaBL2&lt;/li&gt; 
   &lt;li&gt;ts - Type system language&lt;/li&gt; 
   &lt;li&gt;dynsem - Dynamic semantics language&lt;/li&gt; 
   &lt;li&gt;metaborg-coq - Coq signatures and syntax definition&lt;/li&gt; 
   &lt;li&gt;spt - Spoofax testing language&lt;/li&gt; 
   &lt;li&gt;runtime-libraries - NaBL support libraries, incremental task engine for incremental name and type analysis&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Sql+NET</title>
      <link>https://tedneward.github.io/Research/tools/sqlplusnet/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/sqlplusnet/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://sqlplusweb.azurewebsites.net/&quot;&gt;Website&lt;/a&gt; | Commercial, no source&lt;/p&gt; 
&lt;p&gt;Write SQL, generate .NET&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Superagent</title>
      <link>https://tedneward.github.io/Research/tools/superagent/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/superagent/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://superagent.com/&quot;&gt;Website&lt;/a&gt; | Commercial?&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>symtool</title>
      <link>https://tedneward.github.io/Research/tools/symtool/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/symtool/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/calebzulawski/symtool&quot;&gt;Github&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Changing symbol visibility. Renaming symbols. Actions are performed in-place, leaving the rest of the binary untouched.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>termsvg</title>
      <link>https://tedneward.github.io/Research/tools/termsvg/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/termsvg/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/MrMarble/termsvg&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;TermSVG is an all in one cli tool to record, replay and export your terminal session to svg. It uses the same format as asciinema so you can convert asciicast files to SVG or use the asciinema player with a TermSVG recording.&lt;/p&gt; 
&lt;h2&gt;Installation&lt;/h2&gt; 
&lt;h3&gt;Manually&lt;/h3&gt; 
&lt;p&gt;You can download a pre compiled binary directly from the &lt;a href=&quot;https://github.com/mrmarble/termsvg/releases&quot;&gt;releases&lt;/a&gt; for your OS/Architecture.&lt;/p&gt; 
&lt;h3&gt;Go cli&lt;/h3&gt; 
&lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;go install github.com/mrmarble/termsvg/cmd/termsvg@latest # or target a specific version @v0.6.0
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;Install script&lt;/h3&gt; 
&lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;curl -sL https://raw.githubusercontent.com/MrMarble/termsvg/master/scripts/install-termsvg.sh | sudo -E bash -
# or with wget
wget -O - https://raw.githubusercontent.com/MrMarble/termsvg/master/scripts/install-termsvg.sh | sudo -E bash -
&lt;/code&gt;&lt;/pre&gt; 
&lt;h2&gt;Usage&lt;/h2&gt; 
&lt;p&gt;termsvg is composed of multiple commands, similar to &lt;code&gt;git&lt;/code&gt;, &lt;code&gt;docker&lt;/code&gt; or &lt;code&gt;asciinema&lt;/code&gt;.&lt;/p&gt; 
&lt;p&gt;When you run &lt;code&gt;termsvg&lt;/code&gt; with no arguments help message is displayed, listing all available commands with their options.&lt;/p&gt; 
&lt;h3&gt;&lt;code&gt;rec &amp;lt;filename&amp;gt;&lt;/code&gt;&lt;/h3&gt; 
&lt;p&gt;&lt;strong&gt;Record terminal session.&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;By running &lt;code&gt;termsvg rec &amp;lt;filename&amp;gt;&lt;/code&gt; you start a new recording session. The command (process) that is recorded can be specified with &lt;code&gt;-c&lt;/code&gt; option (see below), and defaults to &lt;code&gt;$SHELL&lt;/code&gt; which is what you want in most cases.&lt;/p&gt; 
&lt;p&gt;You can temporarily pause recording of terminal by pressing &lt;kbd&gt;Ctrl+P&lt;/kbd&gt;. This is useful when you want to execute some commands during the recording session that should not be captured (e.g. pasting secrets). Resume by pressing &lt;kbd&gt;Ctrl+P&lt;/kbd&gt; again.&lt;/p&gt; 
&lt;p&gt;Recording finishes when you exit the shell (hit &lt;kbd&gt;Ctrl+D&lt;/kbd&gt; or type &lt;code&gt;exit&lt;/code&gt;). If the recorded process is not a shell then recording finishes when the process exits.&lt;/p&gt; 
&lt;p&gt;The resulting recording (called &lt;a href=&quot;doc/asciicast-v2.md&quot;&gt;asciicast&lt;/a&gt;) is saved to a local file. It can later be replayed with &lt;code&gt;termsvg play &amp;lt;filename&amp;gt;&lt;/code&gt; and/or exported to svg with &lt;code&gt;termsvg export -i &amp;lt;filename&amp;gt;&lt;/code&gt;.&lt;/p&gt; 
&lt;p&gt;Available options:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;code&gt;-c, --command=&amp;lt;command&amp;gt;&lt;/code&gt; - Specify command to record, defaults to $SHELL&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;&lt;code&gt;play &amp;lt;filename&amp;gt;&lt;/code&gt;&lt;/h3&gt; 
&lt;p&gt;&lt;strong&gt;Replay recorded asciicast in a terminal.&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;This command replays given asciicast (as recorded by &lt;code&gt;rec&lt;/code&gt; command) directly in your terminal.&lt;/p&gt; 
&lt;p&gt;Playing from a local file:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;termsvg play /path/to/asciicast.cast
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Available options:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;code&gt;-i, --idle-time-limit=&amp;lt;sec&amp;gt;&lt;/code&gt; - Limit replayed terminal inactivity to max &lt;code&gt;&amp;lt;sec&amp;gt;&lt;/code&gt; seconds&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;-s, --speed=&amp;lt;factor&amp;gt;&lt;/code&gt; - Playback speed (can be fractional)&lt;/li&gt; 
&lt;/ul&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;For the best playback experience it is recommended to run &lt;code&gt;termsvg play&lt;/code&gt; in&lt;br&gt; a terminal of dimensions not smaller than the one used for recording, as&lt;br&gt; there&apos;s no &quot;transcoding&quot; of control sequences for new terminal size.&lt;/p&gt; 
&lt;/blockquote&gt; 
&lt;h3&gt;&lt;code&gt;export &amp;lt;filename&amp;gt;&lt;/code&gt;&lt;/h3&gt; 
&lt;p&gt;&lt;strong&gt;Export recorded asciicast to svg.&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;This command exports given asciicast (as recorded by &lt;code&gt;rec&lt;/code&gt; command) to svg.&lt;/p&gt; 
&lt;p&gt;Exporting from a local file:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;termsvg export /path/to/asciicast.cast
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Available options:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;code&gt;-o, --output=&amp;lt;file&amp;gt;&lt;/code&gt; - Output svg to be created. Defaults to [input].svg&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;-m, --minify&lt;/code&gt; - Minify svg using &lt;a href=&quot;https://github.com/tdewolff/minify&quot;&gt;Minify&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>tldw (Too Long; Didn&apos;t Watch)</title>
      <link>https://tedneward.github.io/Research/tools/tldw/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/tldw/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://tldwproject.com/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/the-crypt-keeper/tldw&quot;&gt;Source&lt;/a&gt; | &lt;a href=&quot;https://github.com/rmusser01/tldw_server&quot;&gt;Source (Forked, ahead)&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>TreeSheets</title>
      <link>https://tedneward.github.io/Research/tools/treesheets/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/treesheets/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://strlen.com/treesheets/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/aardappel/treesheets&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;A &quot;hierarchical spreadsheet&quot; that is a great replacement for spreadsheets, mind mappers, outliners, PIMs, text editors and small databases.&lt;/p&gt; 
&lt;p&gt;Suitable for any kind of data organization, such as todo lists, calendars, project management, brainstorming, organizing ideas, planning, requirements gathering, presentation of information, etc.&lt;/p&gt; 
&lt;p&gt;It&apos;s like a spreadsheet, immediately familiar, but much more suitable for complex data because it&apos;s hierarchical.&lt;br&gt; It&apos;s like a mind mapper, but more organized and compact.&lt;br&gt; It&apos;s like an outliner, but in more than one dimension.&lt;br&gt; It&apos;s like a text editor, but with structure.&lt;/p&gt; 
&lt;p&gt;Have a quick look at what the application looks like on the &lt;a href=&quot;https://strlen.com/treesheets/docs/screenshots.html&quot;&gt;screenshots&lt;/a&gt; page, see how easy it is to use in the &lt;a href=&quot;https://strlen.com/treesheets/docs/tutorial.html&quot;&gt;tutorial&lt;/a&gt;, then give it a download (above). A &lt;a href=&quot;https://www.youtube.com/watch?v=UB-saQZfrsw&quot;&gt;video&lt;/a&gt; someone made (on Linux)&lt;/p&gt; 
&lt;p&gt;TreeSheets is exceptionally small &amp;amp; fast, so can sit in your system tray at all times: with several documents loaded representing the equivalent of almost 100 pages of text, it uses only 5MB of memory on Windows 7 (!)&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Tup</title>
      <link>https://tedneward.github.io/Research/tools/tup/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/tup/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;http://gittup.org/tup/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/gittup/tup&quot;&gt;Github&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;http://hdl.handle.net/2078.1/223053&quot;&gt;Lessons and Pitfalls in Building Firefox with Tup&lt;/a&gt; by Guillaume Maudoux and Kim Mens (12th Seminar on Advanced Techniques &amp;amp; Tools for Software Evolution (SATToSE) 2019)&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>rumdl</title>
      <link>https://tedneward.github.io/Research/tools/rumdl/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/rumdl/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/rvben/rumdl&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;rumdl is a high-performance Markdown linter and formatter that helps ensure consistency and best practices in your Markdown files. Inspired by &lt;a href=&quot;https://github.com/astral-sh/ruff&quot;&gt;ruff&lt;/a&gt; &apos;s approach to Python linting, rumdl brings similar speed and developer experience improvements to the Markdown ecosystem.&lt;/p&gt; 
&lt;p&gt;It offers:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;⚡️ &lt;strong&gt;Built for speed&lt;/strong&gt; with Rust - significantly faster than alternatives&lt;/li&gt; 
 &lt;li&gt;🔍 &lt;strong&gt;54 lint rules&lt;/strong&gt; covering common Markdown issues&lt;/li&gt; 
 &lt;li&gt;🛠️ &lt;strong&gt;Automatic formatting&lt;/strong&gt; with &lt;code&gt;--fix&lt;/code&gt; for files and stdin/stdout&lt;/li&gt; 
 &lt;li&gt;📦 &lt;strong&gt;Zero dependencies&lt;/strong&gt; - single binary with no runtime requirements&lt;/li&gt; 
 &lt;li&gt;🔧 &lt;strong&gt;Highly configurable&lt;/strong&gt; with TOML-based config files&lt;/li&gt; 
 &lt;li&gt;🌐 &lt;strong&gt;Multiple installation options&lt;/strong&gt; - Rust, Python, standalone binaries&lt;/li&gt; 
 &lt;li&gt;🐍 &lt;strong&gt;Installable via pip&lt;/strong&gt; for Python users&lt;/li&gt; 
 &lt;li&gt;📏 &lt;strong&gt;Modern CLI&lt;/strong&gt; with detailed error reporting&lt;/li&gt; 
 &lt;li&gt;🔄 &lt;strong&gt;CI/CD friendly&lt;/strong&gt; with non-zero exit code on errors&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>sbt (Scala Build Tool)</title>
      <link>https://tedneward.github.io/Research/tools/sbt/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/sbt/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.scala-sbt.org/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/sbt/sbt&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>sed</title>
      <link>https://tedneward.github.io/Research/tools/sed/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/sed/index.html</guid>
      	<description>
	&lt;h3&gt;Reading&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://learnbyexample.github.io/learn_gnused/&quot;&gt;GNU sed&lt;/a&gt; - Sundeep Agarwal&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.grymoire.com/Unix/Sed.html&quot;&gt;Sed - An Introduction and Tutorial&lt;/a&gt; - Bruce Barnett&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Sherlock (Project)</title>
      <link>https://tedneward.github.io/Research/tools/sherlock/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/sherlock/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://sherlockproject.xyz/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/sherlock-project/sherlock&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>SophiaScript</title>
      <link>https://tedneward.github.io/Research/tools/sophiascript/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/sophiascript/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/farag2/Sophia-Script-for-Windows&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Spec-Kit</title>
      <link>https://tedneward.github.io/Research/tools/spec-kit/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/spec-kit/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/github/spec-kit&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;h2&gt;Reading&lt;/h2&gt; 
&lt;h3&gt;Articles&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.blog/ai-and-ml/generative-ai/spec-driven-development-with-ai-get-started-with-a-new-open-source-toolkit/&quot;&gt;Spec-driven development with AI: Get started with a new open source toolkit&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://medium.com/@abhinav.dobhal/revolutionizing-ai-powered-development-a-complete-guide-to-githubs-speckit-a85a39f0e2ee&quot;&gt;Revolutionizing AI-Powered Development: A Complete Guide to GitHub’s SpecKit&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Ropper</title>
      <link>https://tedneward.github.io/Research/tools/ropper/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/ropper/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://scoding.de/ropper/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/sashs/ropper&quot;&gt;Github&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Runway</title>
      <link>https://tedneward.github.io/Research/tools/runway/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/runway/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.runway.team/&quot;&gt;Website&lt;/a&gt; | Commercial, cloud&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>scc (Sloc, Cloc, and Code)</title>
      <link>https://tedneward.github.io/Research/tools/scc/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/scc/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/boyter/scc&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;A tool similar to cloc, sloccount and tokei. For counting the lines of code, blank lines, comment lines, and physical lines of source code in many programming languages.&lt;/p&gt; 
&lt;p&gt;Goal is to be the fastest code counter possible, but also perform COCOMO calculation like sloccount, estimate code complexity similar to cyclomatic complexity calculators and produce unique lines of code or DRYness metrics. In short one tool to rule them all.&lt;/p&gt; 
&lt;p&gt;Why use &lt;code&gt;scc&lt;/code&gt;?&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;It is very fast and gets faster the more CPU you throw at it&lt;/li&gt; 
 &lt;li&gt;Accurate&lt;/li&gt; 
 &lt;li&gt;Works very well across multiple platforms without slowdown (Windows, Linux, macOS)&lt;/li&gt; 
 &lt;li&gt;Large language support&lt;/li&gt; 
 &lt;li&gt;Can ignore duplicate files&lt;/li&gt; 
 &lt;li&gt;Has complexity estimations&lt;/li&gt; 
 &lt;li&gt;You need to tell the difference between Coq and Verilog in the same directory&lt;/li&gt; 
 &lt;li&gt;cloc yaml output support so potentially a drop in replacement for some users&lt;/li&gt; 
 &lt;li&gt;Can identify or ignore minified files&lt;/li&gt; 
 &lt;li&gt;Able to identify many #! files ADVANCED! &lt;a href=&quot;https://github.com/boyter/scc/issues/115&quot;&gt;https://github.com/boyter/scc/issues/115&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;Can ignore large files by lines or bytes&lt;/li&gt; 
 &lt;li&gt;Can calculate the ULOC or unique lines of code by file, language or project&lt;/li&gt; 
 &lt;li&gt;Supports multiple output formats for integration, CSV, SQL, JSON, HTML and more&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;Why not use &lt;code&gt;scc&lt;/code&gt;?&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;You don&apos;t like Go for some reason&lt;/li&gt; 
 &lt;li&gt;It cannot count D source with different nested multi-line comments correctly &lt;a href=&quot;https://github.com/boyter/scc/issues/27&quot;&gt;https://github.com/boyter/scc/issues/27&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Differences&lt;/h3&gt; 
&lt;p&gt;There are some important differences between &lt;code&gt;scc&lt;/code&gt; and other tools that are out there. Here are a few important ones for you to consider.&lt;/p&gt; 
&lt;p&gt;Blank lines inside comments are counted as comments. While the line is technically blank the decision was made that&lt;br&gt; once in a comment everything there should be considered a comment until that comment is ended. As such the following,&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;/* blank lines follow


*/
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Would be counted as 4 lines of comments. This is noticeable when comparing scc&apos;s output to other tools on large&lt;br&gt; repositories.&lt;/p&gt; 
&lt;p&gt;&lt;code&gt;scc&lt;/code&gt; is able to count verbatim strings correctly. For example in C# the following,&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;private const string BasePath = @&quot;a:\&quot;;
// The below is returned to the user as a version
private const string Version = &quot;1.0.0&quot;;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Because of the prefixed @ this string ends at the trailing &quot; by ignoring the escape character \ and as such should be&lt;br&gt; counted as 2 code lines and 1 comment. Some tools are unable to&lt;br&gt; deal with this and instead count up to the &quot;1.0.0&quot; as a string which can cause the middle comment to be counted as&lt;br&gt; code rather than a comment.&lt;/p&gt; 
&lt;p&gt;&lt;code&gt;scc&lt;/code&gt; will also tell you the number of bytes it has processed (for most output formats) allowing you to estimate the&lt;br&gt; cost of running some static analysis tools.&lt;/p&gt; 
&lt;h3&gt;Usage&lt;/h3&gt; 
&lt;p&gt;Command line usage of &lt;code&gt;scc&lt;/code&gt; is designed to be as simple as possible.&lt;br&gt; Full details can be found in &lt;code&gt;scc --help&lt;/code&gt; or &lt;code&gt;scc -h&lt;/code&gt;. Note that the below reflects the state of master not a release, as such&lt;br&gt; features listed below may be missing from your installation.&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;Sloc, Cloc and Code. Count lines of code in a directory with complexity estimation.
Version 3.3.4
Ben Boyter &amp;lt;ben@boyter.org&amp;gt; + Contributors

Usage:
  scc [flags] [files or directories]

Flags:
      --avg-wage int                 average wage value used for basic COCOMO calculation (default 56286)
      --binary                       disable binary file detection
      --by-file                      display output for every file
  -m, --character                    calculate max and mean characters per line
      --ci                           enable CI output settings where stdout is ASCII
      --cocomo-project-type string   change COCOMO model type [organic, semi-detached, embedded, &quot;custom,1,1,1,1&quot;] (default &quot;organic&quot;)
      --count-as string              count extension as language [e.g. jsp:htm,chead:&quot;C Header&quot; maps extension jsp to html and chead to C Header]
      --count-ignore                 set to allow .gitignore and .ignore files to be counted
      --currency-symbol string       set currency symbol (default &quot;$&quot;)
      --debug                        enable debug output
  -a, --dryness                      calculate the DRYness of the project (implies --uloc)
      --eaf float                    the effort adjustment factor derived from the cost drivers (1.0 if rated nominal) (default 1)
      --exclude-dir strings          directories to exclude (default [.git,.hg,.svn])
  -x, --exclude-ext strings          ignore file extensions (overrides include-ext) [comma separated list: e.g. go,java,js]
  -n, --exclude-file strings         ignore files with matching names (default [package-lock.json,Cargo.lock,yarn.lock,pubspec.lock,Podfile.lock,pnpm-lock.yaml])
      --file-gc-count int            number of files to parse before turning the GC on (default 10000)
  -f, --format string                set output format [tabular, wide, json, json2, csv, csv-stream, cloc-yaml, html, html-table, sql, sql-insert, openmetrics] (default &quot;tabular&quot;)
      --format-multi string          have multiple format output overriding --format [e.g. tabular:stdout,csv:file.csv,json:file.json]
      --gen                          identify generated files
      --generated-markers strings    string markers in head of generated files (default [do not edit,&amp;lt;auto-generated /&amp;gt;])
  -h, --help                         help for scc
  -i, --include-ext strings          limit to file extensions [comma separated list: e.g. go,java,js]
      --include-symlinks             if set will count symlink files
  -l, --languages                    print supported languages and extensions
      --large-byte-count int         number of bytes a file can contain before being removed from output (default 1000000)
      --large-line-count int         number of lines a file can contain before being removed from output (default 40000)
      --min                          identify minified files
  -z, --min-gen                      identify minified or generated files
      --min-gen-line-length int      number of bytes per average line for file to be considered minified or generated (default 255)
      --no-cocomo                    remove COCOMO calculation output
  -c, --no-complexity                skip calculation of code complexity
  -d, --no-duplicates                remove duplicate files from stats and output
      --no-gen                       ignore generated files in output (implies --gen)
      --no-gitignore                 disables .gitignore file logic
      --no-ignore                    disables .ignore file logic
      --no-large                     ignore files over certain byte and line size set by max-line-count and max-byte-count
      --no-min                       ignore minified files in output (implies --min)
      --no-min-gen                   ignore minified or generated files in output (implies --min-gen)
      --no-size                      remove size calculation output
  -M, --not-match stringArray        ignore files and directories matching regular expression
  -o, --output string                output filename (default stdout)
      --overhead float               set the overhead multiplier for corporate overhead (facilities, equipment, accounting, etc.) (default 2.4)
  -p, --percent                      include percentage values in output
      --remap-all string             inspect every file and remap by checking for a string and remapping the language [e.g. &quot;-*- C++ -*-&quot;:&quot;C Header&quot;]
      --remap-unknown string         inspect files of unknown type and remap by checking for a string and remapping the language [e.g. &quot;-*- C++ -*-&quot;:&quot;C Header&quot;]
      --size-unit string             set size unit [si, binary, mixed, xkcd-kb, xkcd-kelly, xkcd-imaginary, xkcd-intel, xkcd-drive, xkcd-bakers] (default &quot;si&quot;)
      --sloccount-format             print a more SLOCCount like COCOMO calculation
  -s, --sort string                  column to sort by [files, name, lines, blanks, code, comments, complexity] (default &quot;files&quot;)
      --sql-project string           use supplied name as the project identifier for the current run. Only valid with the --format sql or sql-insert option
  -t, --trace                        enable trace output (not recommended when processing multiple files)
  -u, --uloc                         calculate the number of unique lines of code (ULOC) for the project
  -v, --verbose                      verbose output
      --version                      version for scc
  -w, --wide                         wider output with additional statistics (implies --complexity)
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Output should look something like the below for the redis project&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;$ scc redis 
───────────────────────────────────────────────────────────────────────────────
Language                 Files     Lines   Blanks  Comments     Code Complexity
───────────────────────────────────────────────────────────────────────────────
C                          296    180267    20367     31679   128221      32548
C Header                   215     32362     3624      6968    21770       1636
TCL                        143     28959     3130      1784    24045       2340
Shell                       44      1658      222       326     1110        187
Autoconf                    22     10871     1038      1326     8507        953
Lua                         20       525       68        70      387         65
Markdown                    16      2595      683         0     1912          0
Makefile                    11      1363      262       125      976         59
Ruby                        10       795       78        78      639        116
gitignore                   10       162       16         0      146          0
YAML                         6       711       46         8      657          0
HTML                         5      9658     2928        12     6718          0
C++                          4       286       48        14      224         31
License                      4       100       20         0       80          0
Plain Text                   3       185       26         0      159          0
CMake                        2       214       43         3      168          4
CSS                          2       107       16         0       91          0
Python                       2       219       12         6      201         34
Systemd                      2        80        6         0       74          0
BASH                         1       118       14         5       99         31
Batch                        1        28        2         0       26          3
C++ Header                   1         9        1         3        5          0
Extensible Styleshe…         1        10        0         0       10          0
Smarty Template              1        44        1         0       43          5
m4                           1       562      116        53      393          0
───────────────────────────────────────────────────────────────────────────────
Total                      823    271888    32767     42460   196661      38012
───────────────────────────────────────────────────────────────────────────────
Estimated Cost to Develop (organic) $6,918,301
Estimated Schedule Effort (organic) 28.682292 months
Estimated People Required (organic) 21.428982
───────────────────────────────────────────────────────────────────────────────
Processed 9425137 bytes, 9.425 megabytes (SI)
───────────────────────────────────────────────────────────────────────────────
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Note that you don&apos;t have to specify the directory you want to run against. Running &lt;code&gt;scc&lt;/code&gt; will assume you want to run against the current directory.&lt;/p&gt; 
&lt;p&gt;You can also run against multiple files or directories &lt;code&gt;scc directory1 directory2 file1 file2&lt;/code&gt; with the results aggregated in the output.&lt;/p&gt; 
&lt;h3&gt;Ignore Files&lt;/h3&gt; 
&lt;p&gt;&lt;code&gt;scc&lt;/code&gt; mostly supports .ignore files inside directories that it scans. This is similar to how ripgrep, ag and tokei work. .ignore files are 100% the same as .gitignore files with the same syntax, and as such &lt;code&gt;scc&lt;/code&gt; will ignore files and directories listed in them. You can add .ignore files to ignore things like vendored dependency checked in files and such. The idea is allowing you to add a file or folder to git and have ignored in the count.&lt;/p&gt; 
&lt;h3&gt;Interesting Use Cases&lt;/h3&gt; 
&lt;p&gt;Used inside Intel Nemu Hypervisor to track code changes between revisions &lt;a href=&quot;https://github.com/intel/nemu/blob/topic/virt-x86/tools/cloc-change.sh#L9&quot;&gt;https://github.com/intel/nemu/blob/topic/virt-x86/tools/cloc-change.sh#L9&lt;/a&gt;&lt;br&gt; Appears to also be used inside both &lt;a href=&quot;http://codescoop.com/&quot;&gt;http://codescoop.com/&lt;/a&gt; &lt;a href=&quot;https://pinpoint.com/&quot;&gt;https://pinpoint.com/&lt;/a&gt; &lt;a href=&quot;https://github.com/chaoss/grimoirelab-graal&quot;&gt;https://github.com/chaoss/grimoirelab-graal&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;It also is used to count code and guess language types in &lt;a href=&quot;https://searchcode.com/&quot;&gt;https://searchcode.com/&lt;/a&gt; which makes it one of the most frequently run code counters in the world.&lt;/p&gt; 
&lt;p&gt;You can also hook scc into your gitlab pipeline &lt;a href=&quot;https://gitlab.com/guided-explorations/ci-cd-plugin-extensions/ci-cd-plugin-extension-scc&quot;&gt;https://gitlab.com/guided-explorations/ci-cd-plugin-extensions/ci-cd-plugin-extension-scc&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Also used by CodeQL &lt;a href=&quot;https://github.com/boyter/scc/pull/317&quot;&gt;https://github.com/boyter/scc/pull/317&lt;/a&gt; and Scaleway &lt;a href=&quot;https://twitter.com/Scaleway/status/1488087029476995074?s=20&amp;amp;t=N2-z6O-ISDdDzULg4o4uVQ&quot;&gt;https://twitter.com/Scaleway/status/1488087029476995074?s=20&amp;amp;t=N2-z6O-ISDdDzULg4o4uVQ&lt;/a&gt;&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://docs.linuxfoundation.org/lfx/insights/v3-beta-version-current/getting-started/landing-page/cocomo-cost-estimation-simplified&quot;&gt;https://docs.linuxfoundation.org/lfx/insights/v3-beta-version-current/getting-started/landing-page/cocomo-cost-estimation-simplified&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://openems.io/&quot;&gt;https://openems.io/&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Features&lt;/h3&gt; 
&lt;p&gt;&lt;code&gt;scc&lt;/code&gt; uses a small state machine in order to determine what state the code is when it reaches a newline &lt;code&gt;\n&lt;/code&gt;. As such it is aware of and able to count&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Single Line Comments&lt;/li&gt; 
 &lt;li&gt;Multi Line Comments&lt;/li&gt; 
 &lt;li&gt;Strings&lt;/li&gt; 
 &lt;li&gt;Multi Line Strings&lt;/li&gt; 
 &lt;li&gt;Blank lines&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;Because of this it is able to accurately determine if a comment is in a string or is actually a comment.&lt;/p&gt; 
&lt;p&gt;It also attempts to count the complexity of code. This is done by checking for branching operations in the code. For example, each of the following &lt;code&gt;for if switch while else || &amp;amp;&amp;amp; != ==&lt;/code&gt; if encountered in Java would increment that files complexity by one.&lt;/p&gt; 
&lt;h3&gt;Complexity Estimates&lt;/h3&gt; 
&lt;p&gt;Let&apos;s take a minute to discuss the complexity estimate itself.&lt;/p&gt; 
&lt;p&gt;The complexity estimate is really just a number that is only comparable to files in the same language. It should not be used to compare languages directly without weighting them. The reason for this is that its calculated by looking for branch and loop statements in the code and incrementing a counter for that file.&lt;/p&gt; 
&lt;p&gt;Because some languages don&apos;t have loops and instead use recursion they can have a lower complexity count. Does this mean they are less complex? Probably not, but the tool cannot see this because it does not build an AST of the code as it only scans through it.&lt;/p&gt; 
&lt;p&gt;Generally though the complexity there is to help estimate between projects written in the same language, or for finding the most complex file in a project &lt;code&gt;scc --by-file -s complexity&lt;/code&gt; which can be useful when you are estimating on how hard something is to maintain, or when looking for those files that should probably be refactored.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Semmle QL</title>
      <link>https://tedneward.github.io/Research/tools/semmleql/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/semmleql/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/Semmle/ql&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Vulnerability hunting with Semmle QL, &lt;a href=&quot;https://blogs.technet.microsoft.com/srd/2018/08/16/vulnerability-hunting-with-semmle-ql-part-1/&quot;&gt;part 1&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>SimpleNote</title>
      <link>https://tedneward.github.io/Research/tools/simplenote/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/simplenote/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://simplenote.com/&quot;&gt;Website&lt;/a&gt; | Source: &lt;a href=&quot;https://github.com/Automattic/simplenote-electron&quot;&gt;simplenote-electron&lt;/a&gt; is the official Simplenote desktop app for Windows and Linux.&lt;/p&gt; 
&lt;p&gt;For other platforms, see:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/Automattic/simplenote-macos&quot;&gt;simplenote-macos&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/Automattic/simplenote-ios&quot;&gt;simplenote-ios&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/Automattic/simplenote-android&quot;&gt;simplenote-android&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Souffle</title>
      <link>https://tedneward.github.io/Research/tools/souffle/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/souffle/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://souffle-lang.github.io/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/souffle-lang/souffle&quot;&gt;Source&lt;/a&gt; | &lt;a href=&quot;https://souffle-lang.github.io/tutorial&quot;&gt;Tutorial&lt;/a&gt;&lt;/p&gt; 
&lt;h2&gt;Examples/Intro&lt;/h2&gt; 
&lt;p&gt;Say we have a Datalog file example.dl, whose contents are as shown.&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;.decl edge(x:number, y:number)
.input edge

.decl path(x:number, y:number)
.output path

path(x, y) :- edge(x, y).
path(x, y) :- path(x, z), edge(z, y).
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;We see that edge is a .input relation, and so will be read from disk. Also, path is a .output relation, and so will be written to disk.&lt;/p&gt; 
&lt;p&gt;The last two lines say that 1) “there is a path from x to y if there is an edge from x to y”, and 2) “there is a path from x to y if there is a path from x to some z, and there is an edge from that z to y”.&lt;/p&gt; 
&lt;p&gt;So if the input edge relation is pairs of vertices in a graph, by these two rules the output path relation will give us all pairs of vertices x and y for which a path exists in that graph from x to y.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Sphinx</title>
      <link>https://tedneward.github.io/Research/tools/sphinx/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/sphinx/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.sphinx-doc.org/en/master/&quot;&gt;Website&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Uses &lt;a href=&quot;/formats/restructuredtext&quot;&gt;reStructuredText&lt;/a&gt; for content. Not sure of the benefit above/beyond Markdown.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Rubberduck</title>
      <link>https://tedneward.github.io/Research/tools/rubberduck/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/rubberduck/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://rubberduckvba.com/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/rubberduck-vba&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>rv</title>
      <link>https://tedneward.github.io/Research/tools/rv/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/rv/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/spinel-coop/rv&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;h2&gt;Quickstart&lt;/h2&gt; 
&lt;pre&gt;&lt;code&gt;brew install rv
# zsh
echo &apos;eval &quot;$(rv shell init zsh)&quot;&apos; &amp;gt;&amp;gt; ~/.zshrc
eval &quot;$(rv shell init zsh)&quot;
# bash
echo &apos;eval &quot;$(rv shell init bash)&quot;&apos; &amp;gt;&amp;gt; ~/.bashrc
eval &quot;$(rv shell init bash)&quot;
# fish
echo &apos;rv shell init fish | source&apos; &amp;gt;&amp;gt; ~/.config/fish/config.fish
rv shell init fish | source
&lt;/code&gt;&lt;/pre&gt;
	</description>
    </item>
    <item>
      <title>SchemaCrawler</title>
      <link>https://tedneward.github.io/Research/tools/schemacrawler/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/schemacrawler/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.schemacrawler.com/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/schemacrawler/SchemaCrawler&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;You can search for database schema objects using regular expressions, and output the schema and data in a readable text format. The output serves for database documentation, and is designed to be diff-ed against other database schemas. SchemaCrawler also generates schema diagrams. You can execute scripts in any standard scripting language against your database. You can find potential schema design issues with lint.&lt;/p&gt; 
&lt;/blockquote&gt;
	</description>
    </item>
    <item>
      <title>Semtools</title>
      <link>https://tedneward.github.io/Research/tools/semtools/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/semtools/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/run-llama/semtools&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;By default, &lt;code&gt;parse&lt;/code&gt; uses LlamaParse as a backend. Get your API key today for free at &lt;a href=&quot;https://cloud.llamaindex.ai&quot;&gt;https://cloud.llamaindex.ai&lt;/a&gt;. &lt;code&gt;search&lt;/code&gt; remains local-only.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Slashbase</title>
      <link>https://tedneward.github.io/Research/tools/slashbase/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/slashbase/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://slashbase.com/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/slashbaseide/slashbase&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Spall</title>
      <link>https://tedneward.github.io/Research/tools/spall/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/spall/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://gravitymoth.com/spall/&quot;&gt;Website&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Spin</title>
      <link>https://tedneward.github.io/Research/tools/spin/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/spin/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.fermyon.com/spin&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/spinframework/spin&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Spin is an open source framework for building and running fast, secure, and composable cloud microservices with WebAssembly. It aims to be the easiest way to get started with WebAssembly microservices, and takes advantage of the latest developments in the WebAssembly component model and Wasmtime runtime.&lt;/p&gt; 
&lt;p&gt;Spin offers a simple CLI that helps you create, distribute, and execute applications, and in the next sections we will learn more about Spin applications and how to get started.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>ruff</title>
      <link>https://tedneward.github.io/Research/tools/ruff/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/ruff/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://docs.astral.sh/ruff/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/astral-sh/ruff&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;10-100x faster than existing linters (like Flake8) and formatters (like Black)&lt;/li&gt; 
 &lt;li&gt;Installable via pip&lt;/li&gt; 
 &lt;li&gt;pyproject.toml support&lt;/li&gt; 
 &lt;li&gt;Python 3.13 compatibility&lt;/li&gt; 
 &lt;li&gt;Drop-in parity with Flake8, isort, and Black&lt;/li&gt; 
 &lt;li&gt;Built-in caching, to avoid re-analyzing unchanged files&lt;/li&gt; 
 &lt;li&gt;Fix support, for automatic error correction (e.g., automatically remove unused imports)&lt;/li&gt; 
 &lt;li&gt;Over 800 built-in rules, with native re-implementations of popular Flake8 plugins, like flake8-bugbear&lt;/li&gt; 
 &lt;li&gt;First-party editor integrations for VS Code and more&lt;/li&gt; 
 &lt;li&gt;Monorepo-friendly, with hierarchical and cascading configuration&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>SASM</title>
      <link>https://tedneward.github.io/Research/tools/sasm/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/sasm/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://dman95.github.io/SASM/english.html&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/Dman95/SASM&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>SciGen</title>
      <link>https://tedneward.github.io/Research/tools/scigen/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/scigen/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://pdos.csail.mit.edu/archive/scigen/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/strib/scigen&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;It uses a hand-written &lt;strong&gt;context-free grammar&lt;/strong&gt; to form all elements of the papers. Our aim here is to maximize amusement, rather than coherence.&lt;/p&gt; 
&lt;p&gt;One useful purpose for such a program is to auto-generate submissions to conferences that you suspect might have very low submission standards. A prime example, which you may recognize from spam in your inbox, is SCI/IIIS and its dozens of co-located conferences (check out the very broad conference description on the &lt;a href=&quot;http://www.iiisci.org/sci2005/&quot;&gt;WMSCI 2005&lt;/a&gt; website). There&apos;s also a list of &lt;a href=&quot;http://anthony.liekens.net/index.php/Misc/FakeConferences&quot;&gt;known bogus conferences&lt;/a&gt;. Using SCIgen to generate submissions for conferences like this gives us pleasure to no end. In fact, one of our papers was accepted to SCI 2005! See &lt;a href=&quot;https://pdos.csail.mit.edu/archive/scigen/#examples&quot;&gt;Examples&lt;/a&gt; for more details.&lt;/p&gt; 
&lt;p&gt;We went to WMSCI 2005. Check out the &lt;a href=&quot;https://pdos.csail.mit.edu/archive/scigen/#talks&quot;&gt;talks and video&lt;/a&gt;. You can find more details in our &lt;a href=&quot;https://pdos.csail.mit.edu/archive/scigen/blog/&quot;&gt;blog&lt;/a&gt;.&lt;/p&gt; 
&lt;p&gt;Also, check out our 10th anniversary celebration project: &lt;a href=&quot;https://pdos.csail.mit.edu/archive/scigen/scipher.html&quot;&gt;SCIpher&lt;/a&gt;!&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Sharp Cells</title>
      <link>https://tedneward.github.io/Research/tools/sharpcells/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/sharpcells/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.sharpcells.com/&quot;&gt;Website&lt;/a&gt;&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Quickly and easily create custom functions and commands with with robustness and power of F# and .NET&lt;/li&gt; 
 &lt;li&gt;Sharp Cells can connect to data sources from anywhere in your organisation or across the web&lt;/li&gt; 
 &lt;li&gt;Sharp Cells commands let you automate almost any user action with a similar programming interface to VBA&lt;/li&gt; 
 &lt;li&gt;Sharp Cells scripts run on your machine and are saved with the workbook giving you the same single file portability as VBA&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>sli.dev</title>
      <link>https://tedneward.github.io/Research/tools/slidev/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/slidev/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://sli.dev/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/slidevjs/slidev&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>SPARTA</title>
      <link>https://tedneward.github.io/Research/tools/sparta/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/sparta/index.html</guid>
      	<description>
	&lt;p&gt;A C++ library of software components for building high-performance static analyzers.&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://code.fb.com/open-source/sparta/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/facebookincubator/SPARTA&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Easy Abstract Interpretation with SPARTA&lt;br&gt; - Strange Loop 2019; Arnaud Venet and Jez Ng&lt;br&gt; - &lt;a href=&quot;https://www.youtube.com/watch?v=_fA7vkVJhF8&quot;&gt;https://www.youtube.com/watch?v=_fA7vkVJhF8&lt;/a&gt;&lt;br&gt; - &lt;a href=&quot;https://thestrangeloop.com/2019/easy-abstract-interpretation-with-sparta.html&quot;&gt;https://thestrangeloop.com/2019/easy-abstract-interpretation-with-sparta.html&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Proguard</title>
      <link>https://tedneward.github.io/Research/tools/proguard/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/proguard/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/Guardsquare/proguard-core&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;ProGuardCORE is a free library to read, analyze, modify, and write Java class files. It is the core of the well-known shrinker, optimizer, and obfuscator ProGuard, the ProGuard Assembler and Disassembler, and the Kotlin Metadata Printer.&lt;/p&gt; 
&lt;p&gt;Typical applications:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Read and write class files, including any Kotlin metadata.&lt;/li&gt; 
 &lt;li&gt;Search for instruction patterns.&lt;/li&gt; 
 &lt;li&gt;Create byte code instrumentation tools.&lt;/li&gt; 
 &lt;li&gt;Analyze code with abstract evaluation.&lt;/li&gt; 
 &lt;li&gt;Build static code analysis tools.&lt;/li&gt; 
 &lt;li&gt;Optimize and obfuscate, like ProGuard itself.&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Pyew</title>
      <link>https://tedneward.github.io/Research/tools/pyew/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/pyew/index.html</guid>
      	<description>
	&lt;p&gt;It does have support for hexadecimal viewing, disassembly (Intel 16, 32 and 64 bits), PE and ELF file formats (it performs code analysis and let you write scripts using an API to perform many types of analysis), follows direct call/jmp instructions in the interactive command line, displays function names and string data references; supports OLE2 format, PDF format and more. It also supports plugins to add more features to the tool.&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://github.com/joxeankoret/pyew&quot;&gt;Github&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>RAD Debugger</title>
      <link>https://tedneward.github.io/Research/tools/raddebugger/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/raddebugger/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/EpicGamesExt/raddebugger&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Redex</title>
      <link>https://tedneward.github.io/Research/tools/redex/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/redex/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;http://docs.racket-lang.org/redex/index.html&quot;&gt;Website&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Replit</title>
      <link>https://tedneward.github.io/Research/tools/replit/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/replit/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://replit.com/&quot;&gt;Website&lt;/a&gt; Commercial, has a free tier&lt;/p&gt; 
&lt;p&gt;Looks like cloud-hosted browser-based development IDEs/environments?&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>resterm</title>
      <link>https://tedneward.github.io/Research/tools/resterm/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/resterm/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/unkn0wn-root/resterm&quot;&gt;Source&lt;/a&gt; | &lt;a href=&quot;https://github.com/unkn0wn-root/resterm/blob/main/docs&quot;&gt;Docs&lt;/a&gt;&lt;/p&gt; 
&lt;hr&gt; 
&lt;p&gt;Resterm is a terminal client for working with &lt;strong&gt;HTTP&lt;/strong&gt;, &lt;strong&gt;GraphQL&lt;/strong&gt;, and &lt;strong&gt;gRPC&lt;/strong&gt; services. No cloud sync, no signups, no heavy desktop app, no bullshit.&lt;br&gt; It pairs a Vim-like-style editor with a workspace explorer, response diff, history, profiler and scripting so you can iterate on requests without leaving the keyboard (no mouse support is a feature here).&lt;/p&gt; 
&lt;h2&gt;Highlights&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;strong&gt;Workspace&lt;/strong&gt; navigator that filters &lt;code&gt;.http&lt;/code&gt; / &lt;code&gt;.rest&lt;/code&gt; files, supports recursion and keeps request lists in sync as you edit.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Editor&lt;/strong&gt; with inline syntax highlighting, search (&lt;code&gt;Ctrl+F&lt;/code&gt;), clipboard motions, and inline metadata completions (type &lt;code&gt;@&lt;/code&gt; for contextual hints).&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Variable&lt;/strong&gt; scopes with &lt;code&gt;@global&lt;/code&gt; (environment-wide), &lt;code&gt;@var file&lt;/code&gt; (document), &lt;code&gt;@var request&lt;/code&gt; (per-call), plus compile-time constants (&lt;code&gt;@const&lt;/code&gt;), captures, JavaScript hooks, and multi-step workflows with per-step expectations and overrides.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;GraphQL&lt;/strong&gt; helpers (&lt;code&gt;@graphql&lt;/code&gt;, &lt;code&gt;@variables&lt;/code&gt;, &lt;code&gt;@query&lt;/code&gt;) and gRPC directives (&lt;code&gt;@grpc&lt;/code&gt;, &lt;code&gt;@grpc-descriptor&lt;/code&gt;, reflection, metadata).&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;WebSockets and SSE&lt;/strong&gt; with scripted &lt;code&gt;@ws&lt;/code&gt; steps, automatic transcripts and an interactive console for ad-hoc frames.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;OpenAPI importer&lt;/strong&gt; converts OpenAPI specs into Resterm-ready &lt;code&gt;.http&lt;/code&gt; collections from the CLI.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Inline&lt;/strong&gt; requests and &lt;strong&gt;curl&lt;/strong&gt; import for one-off calls (&lt;code&gt;Ctrl+Enter&lt;/code&gt; on a URL or curl block).&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Pretty/Raw/Header/Diff/History/Stream&lt;/strong&gt; views with optional split panes, pinned comparisons, and live event playback.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Built-in&lt;/strong&gt; OAuth 2.0 client plus support for basic, bearer, API key, and custom header auth.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Latency&lt;/strong&gt; with &lt;code&gt;@profile&lt;/code&gt; to benchmark endpoints and render histograms right inside the TUI.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Tracing and Timeline&lt;/strong&gt; with &lt;code&gt;@trace&lt;/code&gt; to enable request tracing.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Multi-step workflows&lt;/strong&gt; let you compose several named requests into one workflow (&lt;code&gt;@workflow&lt;/code&gt; + &lt;code&gt;@step&lt;/code&gt;), override per-step variables, and review aggregated results in History.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Multi-environment compare&lt;/strong&gt; via &lt;code&gt;@compare&lt;/code&gt; directives or the global &lt;code&gt;--compare&lt;/code&gt; flag + &lt;code&gt;g+c&lt;/code&gt; shortcut so you can run the same request across diffrent envs. (dev/stage/prod etc.)&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Quick Start&lt;/h2&gt; 
&lt;p&gt;If you just want to hit an API &lt;strong&gt;right now&lt;/strong&gt;, you don’t need any files.&lt;/p&gt; 
&lt;ol&gt; 
 &lt;li&gt;&lt;strong&gt;Start Resterm&lt;/strong&gt;&lt;/li&gt; 
&lt;/ol&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;# In a project directory (no files required)
resterm

# Or explicitly point to a workspace
resterm --workspace path/to/project
&lt;/code&gt;&lt;/pre&gt; 
&lt;ol&gt; 
 &lt;li&gt;&lt;strong&gt;Type a minimal request&lt;/strong&gt;&lt;/li&gt; 
&lt;/ol&gt; 
&lt;ul&gt; 
 &lt;li&gt;Focus the editor pane (use &lt;code&gt;Tab&lt;/code&gt; if needed).&lt;/li&gt; 
 &lt;li&gt;Press &lt;code&gt;i&lt;/code&gt; or &lt;code&gt;a&lt;/code&gt; and type a simple request, for example: &lt;pre&gt;&lt;code class=&quot;language-http&quot;&gt;GET https://httpbin.org/status/204
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;ol&gt; 
 &lt;li&gt;&lt;strong&gt;Send it&lt;/strong&gt;&lt;/li&gt; 
&lt;/ol&gt; 
&lt;ul&gt; 
 &lt;li&gt;Press &lt;code&gt;Ctrl+Enter&lt;/code&gt; to send the request.&lt;/li&gt; 
 &lt;li&gt;The response appears in the response pane on the right.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;ol&gt; 
 &lt;li&gt;&lt;strong&gt;Move around&lt;/strong&gt;&lt;/li&gt; 
&lt;/ol&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;code&gt;Tab&lt;/code&gt; / &lt;code&gt;Shift+Tab&lt;/code&gt; - cycle focus between sidebar, editor, and response.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;g+p&lt;/code&gt; - jump directly to the response pane.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;g+i&lt;/code&gt; - jump back to the editor.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;That’s enough to be productive: open Resterm, type a URL, hit &lt;code&gt;Ctrl+Enter&lt;/code&gt;, see the response.&lt;/p&gt; 
&lt;hr&gt; 
&lt;h3&gt;Quick Start (but with files)&lt;/h3&gt; 
&lt;p&gt;If you work with &lt;strong&gt;&lt;code&gt;.http&lt;/code&gt; / &lt;code&gt;.rest&lt;/code&gt; files&lt;/strong&gt;, Resterm will discover and use them.&lt;/p&gt; 
&lt;ol&gt; 
 &lt;li&gt;&lt;strong&gt;Open a directory with request files&lt;/strong&gt;&lt;/li&gt; 
&lt;/ol&gt; 
&lt;ul&gt; 
 &lt;li&gt;Create or open a directory that contains &lt;code&gt;.http&lt;/code&gt; / &lt;code&gt;.rest&lt;/code&gt; files&lt;br&gt; (see &lt;code&gt;_examples/&lt;/code&gt; in this repo for samples).&lt;/li&gt; 
 &lt;li&gt;Run: &lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;resterm
# or
resterm --workspace path/to/project
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;ol&gt; 
 &lt;li&gt;&lt;strong&gt;Pick and send a request&lt;/strong&gt;&lt;/li&gt; 
&lt;/ol&gt; 
&lt;ul&gt; 
 &lt;li&gt;Use the &lt;strong&gt;sidebar&lt;/strong&gt; to select a request from your &lt;code&gt;.http&lt;/code&gt; / &lt;code&gt;.rest&lt;/code&gt; files.&lt;/li&gt; 
 &lt;li&gt;Press &lt;code&gt;Ctrl+Enter&lt;/code&gt; to send it.&lt;/li&gt; 
 &lt;li&gt;The response shows up in the right pane.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;ol&gt; 
 &lt;li&gt;&lt;strong&gt;Minimal request file example&lt;/strong&gt;&lt;/li&gt; 
&lt;/ol&gt; 
&lt;pre&gt;&lt;code class=&quot;language-http&quot;&gt;### Status check
# @name status
GET https://httpbin.org/status/204
User-Agent: resterm

### Authenticated echo
# @name bearerEcho
# @auth bearer {{auth.token}}
GET https://httpbin.org/bearer
Accept: application/json
&lt;/code&gt;&lt;/pre&gt; 
&lt;hr&gt; 
&lt;h3&gt;Navigation &amp;amp; Layout Cheat Sheet&lt;/h3&gt; 
&lt;p&gt;A few keys that make Resterm feel “native” quickly:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;strong&gt;Pane focus &amp;amp; layout&lt;/strong&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;Tab&lt;/code&gt; / &lt;code&gt;Shift+Tab&lt;/code&gt; - move focus between sidebar, editor, and response.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;g+r&lt;/code&gt; - jump to &lt;strong&gt;Requests&lt;/strong&gt; (sidebar).&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;g+i&lt;/code&gt; - jump to &lt;strong&gt;Editor&lt;/strong&gt;.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;g+p&lt;/code&gt; - jump to &lt;strong&gt;Response&lt;/strong&gt;.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;g+h&lt;/code&gt; / &lt;code&gt;g+l&lt;/code&gt; - adjust layout: 
  &lt;ul&gt; 
   &lt;li&gt;When the &lt;strong&gt;left pane&lt;/strong&gt; (sidebar) is focused: change sidebar width.&lt;/li&gt; 
   &lt;li&gt;Otherwise: change editor/response split.&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;g+v&lt;/code&gt; / &lt;code&gt;g+s&lt;/code&gt; - toggle response pane between inline and stacked layout.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;g+1&lt;/code&gt;, &lt;code&gt;g+2&lt;/code&gt;, &lt;code&gt;g+3&lt;/code&gt; + minimize/restore sidebar, editor, response.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;g+z&lt;/code&gt; / &lt;code&gt;g+Z&lt;/code&gt; - zoom the focused pane / clear zoom.&lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Environments &amp;amp; globals&lt;/strong&gt;&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;Ctrl+E&lt;/code&gt; - switch environments.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;Ctrl+G&lt;/code&gt; - inspect captured globals.&lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Working with responses&lt;/strong&gt;&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;Ctrl+V&lt;/code&gt; / &lt;code&gt;Ctrl+U&lt;/code&gt; - split the response pane for side-by-side comparison.&lt;/li&gt; 
 &lt;li&gt;When response pane is focused: 
  &lt;ul&gt; 
   &lt;li&gt;&lt;code&gt;Ctrl+Shift+C&lt;/code&gt; or &lt;code&gt;g y&lt;/code&gt; - copy the entire Pretty/Raw/Headers tab&lt;br&gt; to the clipboard (no mouse selection needed).&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;hr&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;[!TIP]&lt;br&gt; &lt;strong&gt;If you only remember three shortcuts...&lt;/strong&gt;&lt;br&gt; - &lt;code&gt;Ctrl+Enter&lt;/code&gt; - send request&lt;br&gt; - &lt;code&gt;Tab&lt;/code&gt; / &lt;code&gt;Shift+Tab&lt;/code&gt; - switch panes&lt;br&gt; - &lt;code&gt;g+p&lt;/code&gt; - jump to response&lt;/p&gt; 
&lt;/blockquote&gt; 
&lt;h2&gt;Inline curl import&lt;/h2&gt; 
&lt;p&gt;Drop a curl command into the editor and press &lt;code&gt;Ctrl+Enter&lt;/code&gt; anywhere inside to turn it into a structured request. Resterm understands common flags (&lt;code&gt;-X&lt;/code&gt;, &lt;code&gt;-H&lt;/code&gt;, &lt;code&gt;--data*&lt;/code&gt;, &lt;code&gt;--json&lt;/code&gt;, &lt;code&gt;--url&lt;/code&gt;, &lt;code&gt;--user&lt;/code&gt;, &lt;code&gt;--compressed&lt;/code&gt;, &lt;code&gt;-F/--form&lt;/code&gt;, etc.), merges repeated data segments, and respects multipart uploads.&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;curl \
  --compressed \
  --url &quot;https://httpbin.org/post?source=resterm&amp;amp;case=multipart&quot; \
  --request POST \
  -H &quot;Accept: application/json&quot; \
  -H &quot;X-Client: resterm-dev&quot; \
  --user resterm:test123 \
  -F file=@README.md \
  --form-string memo=&apos;Testing resterm inline curl
with multiline value&apos; \
  --form-string meta=&apos;{&quot;env&quot;:&quot;test&quot;,&quot;attempt&quot;:1}&apos;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;If you copied the command from a shell, prefixes like &lt;code&gt;sudo&lt;/code&gt; or &lt;code&gt;$&lt;/code&gt; are ignored automatically. Resterm loads the file attachment, preserves multiline form fields, and applies compression/auth headers without extra tweaks.&lt;/p&gt; 
&lt;h2&gt;Quick Configuration Overview&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;Environment files: &lt;code&gt;resterm.env.json&lt;/code&gt; (or legacy &lt;code&gt;rest-client.env.json&lt;/code&gt;) discovered in the file directory, workspace root, or current working directory. Explicit dotenv files (&lt;code&gt;.env&lt;/code&gt;, &lt;code&gt;.env.*&lt;/code&gt;, &lt;code&gt;*.env&lt;/code&gt;) are supported via &lt;code&gt;--env-file&lt;/code&gt; only; we derive the environment name from a &lt;code&gt;workspace&lt;/code&gt; entry, then the file stem, falling back to &lt;code&gt;default&lt;/code&gt; for bare &lt;code&gt;.env&lt;/code&gt; files. Important: Dotenv loading is &lt;strong&gt;single-workspace&lt;/strong&gt; for now. Use JSON when you need multiple environments in one file.&lt;/li&gt; 
 &lt;li&gt;CLI flags: &lt;code&gt;--workspace&lt;/code&gt;, &lt;code&gt;--file&lt;/code&gt;, &lt;code&gt;--env&lt;/code&gt;, &lt;code&gt;--env-file&lt;/code&gt;, &lt;code&gt;--timeout&lt;/code&gt;, &lt;code&gt;--insecure&lt;/code&gt;, &lt;code&gt;--follow&lt;/code&gt;, &lt;code&gt;--proxy&lt;/code&gt;, &lt;code&gt;--recursive&lt;/code&gt;, &lt;code&gt;--from-openapi&lt;/code&gt;, &lt;code&gt;--http-out&lt;/code&gt;, &lt;code&gt;--openapi-base-var&lt;/code&gt;, &lt;code&gt;--openapi-resolve-refs&lt;/code&gt;, &lt;code&gt;--openapi-include-deprecated&lt;/code&gt;, &lt;code&gt;--openapi-server-index&lt;/code&gt;.&lt;/li&gt; 
 &lt;li&gt;Config directory: &lt;code&gt;$HOME/Library/Application Support/resterm&lt;/code&gt;, &lt;code&gt;%APPDATA%\resterm&lt;/code&gt;, or &lt;code&gt;$HOME/.config/resterm&lt;/code&gt; (override with &lt;code&gt;RESTERM_CONFIG_DIR&lt;/code&gt;).&lt;/li&gt; 
 &lt;li&gt;Themes: add &lt;code&gt;.toml&lt;/code&gt; or &lt;code&gt;.json&lt;/code&gt; files under &lt;code&gt;~/.config/resterm/themes&lt;/code&gt; (override with &lt;code&gt;RESTERM_THEMES_DIR&lt;/code&gt;) and switch them at runtime with &lt;code&gt;Ctrl+Alt+T&lt;/code&gt; (or chord &lt;code&gt;g&lt;/code&gt; then &lt;code&gt;t&lt;/code&gt;).&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Workflows&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;Combine existing requests with &lt;code&gt;@workflow&lt;/code&gt; + &lt;code&gt;@step&lt;/code&gt; blocks to build repeatable scenarios that run inside the TUI.&lt;/li&gt; 
 &lt;li&gt;Set per-step assertions (&lt;code&gt;expect.status&lt;/code&gt;, &lt;code&gt;expect.statuscode&lt;/code&gt;) and pass data between steps via &lt;code&gt;vars.request.*&lt;/code&gt; and &lt;code&gt;vars.workflow.*&lt;/code&gt; namespaces.&lt;/li&gt; 
 &lt;li&gt;View progress in the sidebar, and inspect the aggregated summary in History after the run.&lt;/li&gt; 
 &lt;li&gt;See &lt;a href=&quot;https://github.com/unkn0wn-root/resterm/blob/main/docs/resterm.md#workflows-multi-step-workflows&quot;&gt;&lt;code&gt;docs/resterm.md&lt;/code&gt;&lt;/a&gt; for the full reference and &lt;code&gt;_examples/workflows.http&lt;/code&gt; for a runnable sample workflow.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Compare Runs&lt;/h2&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;Try &lt;code&gt;_examples/compare.http&lt;/code&gt; to see &lt;code&gt;@compare&lt;/code&gt; directives and the &lt;code&gt;g+c&lt;/code&gt; shortcut in action (pair it with &lt;code&gt;resterm --compare dev,stage,prod&lt;/code&gt; for instant multi-environment sweeps).&lt;/p&gt; 
&lt;/blockquote&gt; 
&lt;p&gt;Modern API work rarely stops at a single environment, so Resterm bakes in a compare workflow that takes seconds to use:&lt;/p&gt; 
&lt;ol&gt; 
 &lt;li&gt;Add &lt;code&gt;# @compare dev stage prod base=stage&lt;/code&gt; to any request (or launch the app with &lt;code&gt;--compare dev,stage,prod --compare-base stage&lt;/code&gt;).&lt;/li&gt; 
 &lt;li&gt;Press &lt;code&gt;g+c&lt;/code&gt; (or &lt;code&gt;Enter&lt;/code&gt; if you mapped the command) to send the current request to every listed environment. Resterm flips into a split view automatically so you can watch progress live.&lt;/li&gt; 
 &lt;li&gt;When the run finishes, move to the Compare tab and use the arrow keys (PgUp/PgDn/Home/End work too) to highlight any environment. Press &lt;code&gt;Enter&lt;/code&gt; and the primary pane shows that environment, the secondary pane pins the baseline and you land in the Diff tab so Pretty/Raw/Headers all reflect selected ↔ baseline.&lt;/li&gt; 
 &lt;li&gt;Loading a compare entry from History gives the same experience even if you are offline. Resterm rehydrates the snapshots so you can keep auditing deltas without rerunning requests.&lt;/li&gt; 
&lt;/ol&gt; 
&lt;p&gt;For more info. about compare runs, see &lt;a href=&quot;https://github.com/unkn0wn-root/resterm/blob/main/docs/resterm.md#compare-runs&quot;&gt;docs/resterm.md#compare-runs&lt;/a&gt;.&lt;/p&gt; 
&lt;h2&gt;Tracing &amp;amp; Timeline&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;Enable per-phase network tracing by adding &lt;code&gt;# @trace&lt;/code&gt; metadata to a request. Budgets use &lt;code&gt;phase&amp;lt;=duration&lt;/code&gt; syntax (for example &lt;code&gt;dns&amp;lt;=50ms total&amp;lt;=300ms tolerance=25ms&lt;/code&gt;). Supported phases mirror the HTTP client hooks: &lt;code&gt;dns&lt;/code&gt;, &lt;code&gt;connect&lt;/code&gt;, &lt;code&gt;tls&lt;/code&gt;, &lt;code&gt;request_headers&lt;/code&gt;, &lt;code&gt;request_body&lt;/code&gt;, &lt;code&gt;ttfb&lt;/code&gt;, &lt;code&gt;transfer&lt;/code&gt;, and &lt;code&gt;total&lt;/code&gt;.&lt;/li&gt; 
 &lt;li&gt;When a traced response arrives, a &lt;strong&gt;Timeline&lt;/strong&gt; tab appears beside Pretty/Raw/Headers. It renders a proportional bar chart, annotates overruns, and lists budget breaches. Jump straight to it with &lt;code&gt;Ctrl+Alt+L&lt;/code&gt; (or the &lt;code&gt;g+t&lt;/code&gt; chord) and exit via the standard tab navigation.&lt;/li&gt; 
 &lt;li&gt;Trace data is available to scripts through the &lt;code&gt;trace&lt;/code&gt; binding (&lt;code&gt;trace.enabled()&lt;/code&gt;, &lt;code&gt;trace.phases()&lt;/code&gt;, &lt;code&gt;trace.breaches()&lt;/code&gt;, &lt;code&gt;trace.withinBudget()&lt;/code&gt;, etc.), making CI assertions straightforward.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;_examples/trace.http&lt;/code&gt; contains two runnable requests (one within budget, one intentionally breaching) for quick experimentation.&lt;/li&gt; 
 &lt;li&gt;Resterm can export spans to OpenTelemetry when &lt;code&gt;RESTERM_TRACE_OTEL_ENDPOINT&lt;/code&gt; (or &lt;code&gt;--trace-otel-endpoint&lt;/code&gt;) is set. Optional extras: &lt;code&gt;RESTERM_TRACE_OTEL_INSECURE&lt;/code&gt; / &lt;code&gt;--trace-otel-insecure&lt;/code&gt;, &lt;code&gt;RESTERM_TRACE_OTEL_SERVICE&lt;/code&gt; / &lt;code&gt;--trace-otel-service&lt;/code&gt;, &lt;code&gt;RESTERM_TRACE_OTEL_TIMEOUT&lt;/code&gt;, and &lt;code&gt;RESTERM_TRACE_OTEL_HEADERS&lt;/code&gt;.&lt;/li&gt; 
 &lt;li&gt;Spans are emitted only when tracing is enabled. Budget breaches and HTTP failures automatically mark spans with an error status so distributed traces surface anomalies clearly.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;Deep dive into budgets, keyboard shortcuts, and trace scripting in &lt;a href=&quot;https://github.com/unkn0wn-root/resterm/blob/main/docs/resterm.md#timeline--tracing&quot;&gt;docs/resterm.md#timeline--tracing&lt;/a&gt;.&lt;/p&gt; 
&lt;h2&gt;OpenAPI imports&lt;/h2&gt; 
&lt;p&gt;Resterm can translate an OpenAPI 3 specification into a &lt;code&gt;.http&lt;/code&gt; collection directly from the CLI.&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;resterm \
  --from-openapi openapi-test.yml \
  --http-out openapi-test.http \
  --openapi-base-var apiBase \
  --openapi-resolve-refs \
  --openapi-server-index 1
&lt;/code&gt;&lt;/pre&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;code&gt;--from-openapi&lt;/code&gt; points at the source spec, &lt;code&gt;--http-out&lt;/code&gt; controls the generated &lt;code&gt;.http&lt;/code&gt; file (defaults to &lt;code&gt;&amp;lt;spec&amp;gt;.http&lt;/code&gt; when omitted).&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;--openapi-base-var&lt;/code&gt; overrides the variable name injected for the base URL (falls back to &lt;code&gt;baseUrl&lt;/code&gt;).&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;--openapi-resolve-refs&lt;/code&gt; enables kin-openapi&apos;s &lt;code&gt;$ref&lt;/code&gt; resolution before generation.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;--openapi-include-deprecated&lt;/code&gt; keeps deprecated operations that are skipped by default.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;--openapi-server-index&lt;/code&gt; picks which server entry (0-based) should populate the base URL if multiple servers are defined.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;The repository ships with &lt;code&gt;openapi-specs.yml&lt;/code&gt;, an intentionally full-featured spec that covers array/object query parameters, callbacks, and unsupported constructs (for example OpenID Connect). Those unsupported pieces surface as &lt;code&gt;Warning:&lt;/code&gt; lines within the generated header comment so you can verify warning handling end-to-end.&lt;/p&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;[!NOTE]&lt;br&gt; Resterm relies on &lt;a href=&quot;https://github.com/getkin/kin-openapi&quot;&gt;&lt;code&gt;kin-openapi&lt;/code&gt;&lt;/a&gt;, which currently supports OpenAPI documents up to &lt;strong&gt;v3.0.1&lt;/strong&gt;. Work on v3.1 support is tracked in &lt;a href=&quot;https://github.com/getkin/kin-openapi/pull/1102&quot;&gt;getkin/kin-openapi#1102&lt;/a&gt;.&lt;/p&gt; 
&lt;/blockquote&gt; 
&lt;p&gt;More about OpenAPI importer and available flags in &lt;a href=&quot;https://github.com/unkn0wn-root/resterm/blob/main/docs/resterm.md#importing-openapi-specs&quot;&gt;docs/resterm.md#importing-openapi-specs&lt;/a&gt;.&lt;/p&gt; 
&lt;h2&gt;Streaming (WebSocket &amp;amp; SSE)&lt;/h2&gt; 
&lt;p&gt;Streaming requests are first-class citizens in Resterm. Enable the &lt;strong&gt;Stream&lt;/strong&gt; response tab to watch events in real time. See &lt;a href=&quot;https://github.com/unkn0wn-root/resterm/blob/main/docs/resterm.md#streaming-sse--websocket&quot;&gt;docs/resterm.md#streaming-sse--websocket&lt;/a&gt; for the complete directive list.&lt;/p&gt; 
&lt;h3&gt;Server-Sent Events&lt;/h3&gt; 
&lt;p&gt;Annotate any HTTP request with &lt;code&gt;# @sse&lt;/code&gt; to keep the connection open and capture events:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-http&quot;&gt;### Notification feed
# @name streamNotifications
# @sse duration=1m idle=5s max-events=50
GET https://api.example.com/notifications
Accept: text/event-stream
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;&lt;code&gt;@sse&lt;/code&gt; accepts:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;code&gt;duration&lt;/code&gt; / &lt;code&gt;timeout&lt;/code&gt; total session timeout before Resterm aborts the stream.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;idle&lt;/code&gt; / &lt;code&gt;idle-timeout&lt;/code&gt; maximum gap between events before the stream is closed.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;max-events&lt;/code&gt; stop after N events (Resterm still records the transcript).&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;max-bytes&lt;/code&gt; / &lt;code&gt;limit-bytes&lt;/code&gt; cap downloaded payload size.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;The Pretty/Raw/Headers tabs collapse into a JSON transcript when a stream finishes and the history entry exposes a summary (&lt;code&gt;events&lt;/code&gt;, &lt;code&gt;bytes&lt;/code&gt;, &lt;code&gt;reason&lt;/code&gt;). More SSE options and transcript fields live in &lt;a href=&quot;https://github.com/unkn0wn-root/resterm/blob/main/docs/resterm.md#server-sent-events-sse&quot;&gt;docs/resterm.md#server-sent-events-sse&lt;/a&gt;.&lt;/p&gt; 
&lt;h3&gt;WebSockets&lt;/h3&gt; 
&lt;p&gt;Switch any request to WebSocket mode with &lt;code&gt;# @websocket&lt;/code&gt; and describe scripted steps with &lt;code&gt;# @ws&lt;/code&gt; lines:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-http&quot;&gt;### Chat handshake
# @name websocketChat
# @websocket timeout=10s receive-timeout=5s subprotocols=chat.v2,json
# @ws send {&quot;type&quot;:&quot;hello&quot;}
# @ws wait 1s
# @ws send-json {&quot;type&quot;:&quot;message&quot;,&quot;text&quot;:&quot;Hi&quot;}
# @ws close 1000 &quot;client done&quot;
wss://chat.example.com/stream
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;or if you prefer just to open websocket connection:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-http&quot;&gt;### Chat
# @name websocketChat
# @websocket
ws://chat.example.com/stream
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;WebSocket options mirror runtime controls:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;code&gt;timeout&lt;/code&gt; - handshake deadline.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;receive-timeout&lt;/code&gt; - idle receive window (0 keeps it open indefinitely).&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;max-message-bytes&lt;/code&gt; - hard cap for inbound payloads.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;subprotocols&lt;/code&gt; - comma-separated list sent during the handshake.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;compression=&amp;lt;true|false&amp;gt;&lt;/code&gt; - explicitly enable or disable per-message compression.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;Each &lt;code&gt;@ws&lt;/code&gt; directive emits a step:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;code&gt;send&lt;/code&gt;/&lt;code&gt;send-json&lt;/code&gt;/&lt;code&gt;send-base64&lt;/code&gt;/&lt;code&gt;send-file&lt;/code&gt; send text, JSON, base64, or file payloads.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;ping&lt;/code&gt; / &lt;code&gt;pong&lt;/code&gt; transmit control frames.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;wait &amp;lt;duration&amp;gt;&lt;/code&gt; pauses before the next scripted action.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;close [code] [reason]&lt;/code&gt; ends the session with an optional status.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;The transcript records sender/receiver, opcode, sizes, close metadata and elapsed time. History entries keep the conversation for later review or scripted assertions. See &lt;a href=&quot;./docs/resterm.md#websockets-websocket-ws&quot;&gt;docs/resterm.md#websockets-websocket-ws&lt;/a&gt;.&lt;/p&gt; 
&lt;h3&gt;Stream viewer &amp;amp; console&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;Focus the response pane with &lt;code&gt;g+p&lt;/code&gt;, then switch to the Stream tab using the left/right arrow keys (or &lt;code&gt;Ctrl+H&lt;/code&gt; / &lt;code&gt;Ctrl+L&lt;/code&gt;). Follow events live, bookmark frames and scrub after the stream completes.&lt;/li&gt; 
 &lt;li&gt;Toggle the interactive WebSocket console with &lt;code&gt;Ctrl+I&lt;/code&gt; or &lt;code&gt;g+r&lt;/code&gt; while the Stream tab is focused. Use &lt;code&gt;F2&lt;/code&gt; to cycle payload modes (text, JSON, base64, file), &lt;code&gt;Ctrl+S&lt;/code&gt; (or &lt;code&gt;Ctrl+Enter&lt;/code&gt;) to send, arrows to navigate history, &lt;code&gt;Ctrl+P&lt;/code&gt; for ping, &lt;code&gt;Ctrl+W&lt;/code&gt; to close and &lt;code&gt;Ctrl+L&lt;/code&gt; to clear the buffer.&lt;/li&gt; 
 &lt;li&gt;Scripted tests can consume transcripts via the &lt;code&gt;stream&lt;/code&gt; API (&lt;code&gt;stream.kind&lt;/code&gt;, &lt;code&gt;stream.summary&lt;/code&gt;, &lt;code&gt;stream.events&lt;/code&gt;, &lt;code&gt;stream.onEvent()&lt;/code&gt;), enabling assertions on streaming workloads.&lt;br&gt; Find every stream history/export hook in &lt;a href=&quot;https://github.com/unkn0wn-root/resterm/blob/main/docs/resterm.md#stream-tab-history-and-console&quot;&gt;docs/resterm.md#stream-tab-history-and-console&lt;/a&gt;.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Custom themes&lt;/h2&gt; 
&lt;p&gt;Resterm ships with a default palette, but you can provide your own by dropping theme definitions into the themes directory mentioned above. Each theme can be written in TOML or JSON and only needs to override the parts you care about.&lt;/p&gt; 
&lt;p&gt;A ready-to-use sample lives in &lt;a href=&quot;https://github.com/unkn0wn-root/resterm/blob/main/_examples/themes/aurora.toml&quot;&gt;_examples/themes/aurora.toml&lt;/a&gt;. Point &lt;code&gt;RESTERM_THEMES_DIR&lt;/code&gt; env var at that folder to try it immediately.&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-toml&quot;&gt;[metadata]
name = &quot;Oceanic&quot;
author = &quot;You&quot;

[styles.header_title]
foreground = &quot;#5fd1ff&quot;
bold = true

[colors]
pane_active_foreground = &quot;#5fd1ff&quot;
pane_border_focus_file = &quot;#1f6feb&quot;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Save the file as &lt;code&gt;~/.config/resterm/themes/oceanic.toml&lt;/code&gt; (or to your &lt;code&gt;RESTERM_THEMES_DIR&lt;/code&gt;) and press &lt;code&gt;Ctrl+Alt+T&lt;/code&gt; (or type &lt;code&gt;g&lt;/code&gt; then &lt;code&gt;t&lt;/code&gt;) inside Resterm to pick it as the default. The selected theme is persisted to &lt;code&gt;settings.toml&lt;/code&gt; so it is restored on the next launch. The theming primer (directory layout, schema, and testing tips) lives in &lt;a href=&quot;https://github.com/unkn0wn-root/resterm/blob/main/docs/resterm.md#theming&quot;&gt;docs/resterm.md#theming&lt;/a&gt;.&lt;/p&gt; 
&lt;h2&gt;Custom bindings&lt;/h2&gt; 
&lt;p&gt;Resterm looks for &lt;code&gt;${RESTERM_CONFIG_DIR}/bindings.toml&lt;/code&gt; first (and &lt;code&gt;bindings.json&lt;/code&gt; second). Each entry maps an action ID to one or more bindings:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-toml&quot;&gt;[bindings]
save_file = [&quot;ctrl+shift+s&quot;]
set_main_split_horizontal = [&quot;g s&quot;, &quot;ctrl+alt+s&quot;]
send_request = [&quot;ctrl+enter&quot;, &quot;cmd+enter&quot;]
&lt;/code&gt;&lt;/pre&gt; 
&lt;ul&gt; 
 &lt;li&gt;Modifiers use &lt;code&gt;+&lt;/code&gt; (&lt;code&gt;ctrl+shift+o&lt;/code&gt;), while chord steps are separated by spaces (&lt;code&gt;&quot;g s&quot;&lt;/code&gt;).&lt;/li&gt; 
 &lt;li&gt;Only up to two steps are supported; &lt;code&gt;send_request&lt;/code&gt; must stay single-step so it can fire while you type.&lt;/li&gt; 
 &lt;li&gt;Unknown actions or two actions sharing the same binding will be rejected (Resterm logs the error and keeps defaults).&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;The complete action catalog and a binding reference live in &lt;a href=&quot;https://github.com/unkn0wn-root/resterm/blob/main/docs/resterm.md#custom-bindings&quot;&gt;docs/resterm.md#custom-bindings&lt;/a&gt;.&lt;/p&gt; 
&lt;p&gt;Check out the sample in &lt;a href=&quot;https://github.com/unkn0wn-root/resterm/blob/main/_examples/bindings/bindings.toml&quot;&gt;_examples/bindings/bindings.toml&lt;/a&gt;&lt;/p&gt; 
&lt;h2&gt;Documentation&lt;/h2&gt; 
&lt;p&gt;The full reference, including request syntax, metadata, directive tables, scripting APIs, transport settings and advanced workflows, lives in &lt;a href=&quot;https://github.com/unkn0wn-root/resterm/blob/main/docs/resterm.md&quot;&gt;&lt;code&gt;docs/resterm.md&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>RockBot</title>
      <link>https://tedneward.github.io/Research/tools/rockbot/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/rockbot/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/MarimerLLC/rockbot&quot;&gt;Source&lt;/a&gt; | &lt;a href=&quot;https://hub.docker.com/r/rockylhotka/rockbot-agent/&quot;&gt;Docker Hub&lt;/a&gt;&lt;/p&gt; 
&lt;h2&gt;Resources&lt;/h2&gt; 
&lt;h3&gt;Articles/Blogs/Essays&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://blog.lhotka.net/2026/03/03/The-RockBot-Band&quot;&gt;Announcement&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Pixi</title>
      <link>https://tedneward.github.io/Research/tools/pixi/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/pixi/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://pixi.prefix.dev/latest/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/prefix-dev/pixi&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;h2&gt;Overview&lt;/h2&gt; 
&lt;p&gt;&lt;code&gt;pixi&lt;/code&gt; is a cross-platform, multi-language package manager and workflow tool built on the foundation of the conda ecosystem. It provides developers with an exceptional experience similar to popular package managers like &lt;a href=&quot;https://doc.rust-lang.org/cargo/&quot;&gt;&lt;code&gt;cargo&lt;/code&gt;&lt;/a&gt; or &lt;a href=&quot;https://docs.npmjs.com&quot;&gt;&lt;code&gt;npm&lt;/code&gt;&lt;/a&gt;, but for any language.&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Supports &lt;strong&gt;multiple languages&lt;/strong&gt; including Python, C++, and R using Conda packages. You can find available packages on &lt;a href=&quot;https://prefix.dev&quot;&gt;prefix.dev&lt;/a&gt;.&lt;/li&gt; 
 &lt;li&gt;Compatible with all major operating systems: Linux, Windows, macOS (including Apple Silicon).&lt;/li&gt; 
 &lt;li&gt;Always includes an up-to-date &lt;a href=&quot;https://pixi.sh/latest/workspace/lockfile/&quot;&gt;&lt;strong&gt;lock file&lt;/strong&gt;&lt;/a&gt;.&lt;/li&gt; 
 &lt;li&gt;Provides a clean and simple Cargo-like &lt;strong&gt;command-line interface&lt;/strong&gt;.&lt;/li&gt; 
 &lt;li&gt;Allows you to install tools &lt;strong&gt;per-project&lt;/strong&gt; or &lt;strong&gt;system-wide&lt;/strong&gt;.&lt;/li&gt; 
 &lt;li&gt;Entirely written in &lt;strong&gt;Rust&lt;/strong&gt; and built on top of the &lt;strong&gt;&lt;a href=&quot;https://github.com/conda/rattler&quot;&gt;rattler&lt;/a&gt;&lt;/strong&gt; library.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Installation&lt;/h2&gt; 
&lt;p&gt;&lt;code&gt;pixi&lt;/code&gt; can be installed on macOS, Linux, and Windows. The provided scripts will automatically download the latest version of &lt;code&gt;pixi&lt;/code&gt;, extract it, and move the &lt;code&gt;pixi&lt;/code&gt; binary to &lt;code&gt;~/.pixi/bin&lt;/code&gt;. If this directory does not exist, the script will create it.&lt;/p&gt; 
&lt;h3&gt;macOS and Linux&lt;/h3&gt; 
&lt;p&gt;To install Pixi on macOS and Linux, open a terminal and run the following command:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;curl -fsSL https://pixi.sh/install.sh | sh
# or with brew
brew install pixi
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;The script will also update your &lt;code&gt;~/.bashrc&lt;/code&gt; to include &lt;code&gt;~/.pixi/bin&lt;/code&gt; in your &lt;code&gt;PATH&lt;/code&gt;, allowing you to invoke the &lt;code&gt;pixi&lt;/code&gt; command from anywhere.&lt;br&gt; You might need to restart your terminal or source your shell for the changes to take effect.&lt;/p&gt; 
&lt;p&gt;Starting with macOS Catalina &lt;a href=&quot;https://support.apple.com/en-us/102360&quot;&gt;zsh is the default login shell and interactive shell&lt;/a&gt;. Therefore, you might want to use &lt;code&gt;zsh&lt;/code&gt; instead of &lt;code&gt;bash&lt;/code&gt; in the install command:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-zsh&quot;&gt;curl -fsSL https://pixi.sh/install.sh | zsh
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;The script will also update your &lt;code&gt;~/.zshrc&lt;/code&gt; to include &lt;code&gt;~/.pixi/bin&lt;/code&gt; in your &lt;code&gt;PATH&lt;/code&gt;, allowing you to invoke the &lt;code&gt;pixi&lt;/code&gt; command from anywhere.&lt;/p&gt; 
&lt;h3&gt;Windows&lt;/h3&gt; 
&lt;p&gt;To install Pixi on Windows, open a PowerShell terminal (you may need to run it as an administrator) and run the following command:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-powershell&quot;&gt;powershell -ExecutionPolicy ByPass -c &quot;irm -useb https://pixi.sh/install.ps1 | iex&quot;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Changing the &lt;a href=&quot;https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_execution_policies?view=powershell-7.4#powershell-execution-policies&quot;&gt;execution policy&lt;/a&gt; allows running a script from the internet.&lt;br&gt; Check the script you would be running with:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-powershell&quot;&gt;powershell -c &quot;irm -useb https://pixi.sh/install.ps1 | more&quot;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;The script will inform you once the installation is successful and add the &lt;code&gt;~/.pixi/bin&lt;/code&gt; directory to your &lt;code&gt;PATH&lt;/code&gt;, which will allow you to run the &lt;code&gt;pixi&lt;/code&gt; command from any location.&lt;br&gt; Or with &lt;code&gt;winget&lt;/code&gt;&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-shell&quot;&gt;winget install prefix-dev.pixi
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;Autocompletion&lt;/h3&gt; 
&lt;p&gt;To get autocompletion follow the instructions for your shell.&lt;br&gt; Afterwards, restart the shell or source the shell config file.&lt;/p&gt; 
&lt;h4&gt;Bash (default on most Linux systems)&lt;/h4&gt; 
&lt;p&gt;Add the following to the end of &lt;code&gt;~/.bashrc&lt;/code&gt;:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;# ~/.bashrc

eval &quot;$(pixi completion --shell bash)&quot;
&lt;/code&gt;&lt;/pre&gt; 
&lt;h4&gt;Zsh (default on macOS)&lt;/h4&gt; 
&lt;p&gt;Add the following to the end of &lt;code&gt;~/.zshrc&lt;/code&gt;:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-zsh&quot;&gt;# ~/.zshrc

eval &quot;$(pixi completion --shell zsh)&quot;
&lt;/code&gt;&lt;/pre&gt; 
&lt;h4&gt;PowerShell (pre-installed on all Windows systems)&lt;/h4&gt; 
&lt;p&gt;Add the following to the end of &lt;code&gt;Microsoft.PowerShell_profile.ps1&lt;/code&gt;.&lt;br&gt; You can check the location of this file by querying the &lt;code&gt;$PROFILE&lt;/code&gt; variable in PowerShell.&lt;br&gt; Typically the path is &lt;code&gt;~\Documents\PowerShell\Microsoft.PowerShell_profile.ps1&lt;/code&gt; or&lt;br&gt; &lt;code&gt;~/.config/powershell/Microsoft.PowerShell_profile.ps1&lt;/code&gt; on -Nix.&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-pwsh&quot;&gt;(&amp;amp; pixi completion --shell powershell) | Out-String | Invoke-Expression
&lt;/code&gt;&lt;/pre&gt; 
&lt;h4&gt;Fish&lt;/h4&gt; 
&lt;p&gt;Add the following to the end of &lt;code&gt;~/.config/fish/config.fish&lt;/code&gt;:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-fish&quot;&gt;# ~/.config/fish/config.fish

pixi completion --shell fish | source
&lt;/code&gt;&lt;/pre&gt; 
&lt;h4&gt;Nushell&lt;/h4&gt; 
&lt;p&gt;Add the following to your Nushell config file (find it by running &lt;code&gt;$nu.config-path&lt;/code&gt; in Nushell):&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-nushell&quot;&gt;mkdir $&quot;($nu.data-dir)/vendor/autoload&quot;
pixi completion --shell nushell | save --force $&quot;($nu.data-dir)/vendor/autoload/pixi-completions.nu&quot;
&lt;/code&gt;&lt;/pre&gt; 
&lt;h4&gt;Elvish&lt;/h4&gt; 
&lt;p&gt;Add the following to the end of &lt;code&gt;~/.elvish/rc.elv&lt;/code&gt;:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-elv&quot;&gt;# ~/.elvish/rc.elv

eval (pixi completion --shell elvish | slurp)
&lt;/code&gt;&lt;/pre&gt; 
&lt;h4&gt;Arch Linux&lt;/h4&gt; 
&lt;p&gt;You can install &lt;code&gt;pixi&lt;/code&gt; from the &lt;a href=&quot;https://archlinux.org/packages/extra/x86_64/pixi/&quot;&gt;extra repository&lt;/a&gt; using &lt;a href=&quot;https://wiki.archlinux.org/title/Pacman&quot;&gt;pacman&lt;/a&gt;:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-shell&quot;&gt;pacman -S pixi
&lt;/code&gt;&lt;/pre&gt; 
&lt;h4&gt;Alpine Linux&lt;/h4&gt; 
&lt;p&gt;&lt;code&gt;pixi&lt;/code&gt; is available for &lt;a href=&quot;https://pkgs.alpinelinux.org/packages?name=pixi&amp;amp;branch=edge&quot;&gt;Alpine Edge&lt;/a&gt;. It can be installed via &lt;a href=&quot;https://wiki.alpinelinux.org/wiki/Alpine_Package_Keeper&quot;&gt;apk&lt;/a&gt; after enabling the &lt;a href=&quot;https://wiki.alpinelinux.org/wiki/Repositories&quot;&gt;testing repository&lt;/a&gt;.&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-shell&quot;&gt;apk add pixi
&lt;/code&gt;&lt;/pre&gt; 
&lt;h2&gt;Build/install from source&lt;/h2&gt; 
&lt;p&gt;&lt;code&gt;pixi&lt;/code&gt; is 100% written in Rust and therefore it can be installed, built and tested with cargo.&lt;br&gt; To start using &lt;code&gt;pixi&lt;/code&gt; from a source build run:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-shell&quot;&gt;cargo install --locked --git https://github.com/prefix-dev/pixi.git pixi
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;We don&apos;t publish to &lt;code&gt;crates.io&lt;/code&gt; anymore, so you need to install it from the repository.&lt;br&gt; The reason for this is that we depend on some unpublished crates which disallows us to publish to &lt;code&gt;crates.io&lt;/code&gt;.&lt;/p&gt; 
&lt;p&gt;or when you want to make changes use:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-shell&quot;&gt;cargo build
cargo test
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;If you have any issues building because of the dependency on &lt;code&gt;rattler&lt;/code&gt; checkout&lt;br&gt; it&apos;s &lt;a href=&quot;https://github.com/conda/rattler/tree/main#give-it-a-try&quot;&gt;compile steps&lt;/a&gt;&lt;/p&gt; 
&lt;h2&gt;Uninstall&lt;/h2&gt; 
&lt;p&gt;To uninstall, the Pixi binary should be removed.&lt;br&gt; Delete &lt;code&gt;pixi&lt;/code&gt; from the &lt;code&gt;$PIXI_DIR&lt;/code&gt; which is default to &lt;code&gt;~/.pixi/bin/pixi&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;So on Linux its:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-shell&quot;&gt;rm ~/.pixi/bin/pixi
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;and on Windows:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-shell&quot;&gt;$PIXI_BIN = &quot;$Env:LocalAppData\pixi\bin\pixi&quot;; Remove-Item -Path $PIXI_BIN
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;After this command you can still use the tools you installed with &lt;code&gt;pixi&lt;/code&gt;.&lt;br&gt; To remove these as well just remove the whole &lt;code&gt;~/.pixi&lt;/code&gt; directory and remove the directory from your path.&lt;/p&gt; 
&lt;h1&gt;Usage&lt;/h1&gt; 
&lt;p&gt;The cli looks as follows:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;➜ pixi
Pixi [version 0.59.0] - Developer Workflow and Environment Management for Multi-Platform, Language-Agnostic Workspaces.

Pixi is a versatile developer workflow tool designed to streamline the management of your workspace&apos;s dependencies, tasks, and environments. Built on top of the Conda ecosystem, Pixi offers seamless integration with the PyPI ecosystem.

Basic Usage:
    Initialize pixi for a workspace:
    $ pixi init
    $ pixi add python numpy pytest

    Run a task:
    $ pixi task add test &apos;pytest -s&apos;
    $ pixi run test

Usage: pixi [OPTIONS] [COMMAND]

Commands:
  add         Adds dependencies to the workspace [aliases: a]
  auth        Login to prefix.dev or anaconda.org servers to access private channels
  build       Workspace configuration
  clean       Cleanup the environments
  completion  Generates a completion script for a shell
  config      Configuration management
  exec        Run a command and install it in a temporary environment [aliases: x]
  global      Subcommand for global package management actions [aliases: g]
  info        Information about the system, workspace and environments for the current machine
  init        Creates a new workspace
  import      Imports a file into an environment in an existing workspace.
  install     Install an environment, both updating the lockfile and installing the environment [aliases: i]
  list        List the packages of the current workspace [aliases: ls]
  lock        Solve environment and update the lock file without installing the environments
  reinstall   Re-install an environment, both updating the lockfile and re-installing the environment
  remove      Removes dependencies from the workspace [aliases: rm]
  run         Runs task in the pixi environment [aliases: r]
  search      Search a conda package
  shell       Start a shell in a pixi environment, run `exit` to leave the shell [aliases: s]
  shell-hook  Print the pixi environment activation script
  task        Interact with tasks in the workspace
  tree        Show a tree of workspace dependencies [aliases: t]
  update      The `update` command checks if there are newer versions of the dependencies and updates the `pixi.lock`
              file and environments accordingly
  upgrade     Checks if there are newer versions of the dependencies and upgrades them in the lockfile and manifest
              file
  upload      Upload a conda package
  workspace   Modify the workspace configuration file through the command line
  help        Print this message or the help of the given subcommand(s)

Options:
  -V, --version  Print version

Global Options:
  -h, --help           Display help information
  -v, --verbose...     Increase logging verbosity (-v for warnings, -vv for info, -vvv for debug, -vvvv for trace)
  -q, --quiet...       Decrease logging verbosity (quiet mode)
      --color &amp;lt;COLOR&amp;gt;  Whether the log needs to be colored [env: PIXI_COLOR=] [default: auto] [possible values:
                       always, never, auto]
      --no-progress    Hide all progress bars, always turned on if stderr is not a terminal [env: PIXI_NO_PROGRESS=]
      --list           List all installed commands (built-in and extensions)
&lt;/code&gt;&lt;/pre&gt; 
&lt;h2&gt;Creating a Pixi workspace&lt;/h2&gt; 
&lt;p&gt;Initialize a new workspace and navigate to the workspace directory&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;pixi init myworkspace
cd myworkspace
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Add the dependencies you want to use&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;pixi add cowpy
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Run the installed package in its environment&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;pixi run cowpy &quot;Thanks for using pixi&quot;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Activate a shell in the environment&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-shell&quot;&gt;pixi shell
cowpy &quot;Thanks for using pixi&quot;
exit
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Check out &lt;a href=&quot;https://pixi.sh/dev/first_workspace/&quot;&gt;https://pixi.sh/dev/first_workspace/&lt;/a&gt; for a more detailed introduction to workspaces.&lt;/p&gt; 
&lt;h2&gt;Installing a conda package globally&lt;/h2&gt; 
&lt;p&gt;You can also globally install conda packages into their own environment.&lt;br&gt; This behavior is similar to &lt;a href=&quot;https://github.com/pypa/pipx&quot;&gt;&lt;code&gt;pipx&lt;/code&gt;&lt;/a&gt; or &lt;a href=&quot;https://github.com/mariusvniekerk/condax&quot;&gt;&lt;code&gt;condax&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;pixi global install cowpy
&lt;/code&gt;&lt;/pre&gt;
	</description>
    </item>
    <item>
      <title>PROSE Framework</title>
      <link>https://tedneward.github.io/Research/tools/prose/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/prose/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.microsoft.com/en-us/research/project/prose-framework/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/microsoft/prose&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;Microsoft PROSE is a framework of technologies for programming by examples: automatic generation of programs from input-output examples. Given a domain-specific language (DSL) and input-output examples for the desired program’s behavior, PROSE synthesizes a ranked set of DSL programs that are consistent with the examples.&lt;/p&gt; 
&lt;/blockquote&gt;
	</description>
    </item>
    <item>
      <title>QBDI (QuarkslaB Dynamic binary Instrumentation)</title>
      <link>https://tedneward.github.io/Research/tools/qbdi/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/qbdi/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://qbdi.quarkslab.com&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/quarkslab/QBDI&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://events.ccc.de/congress/2017/Fahrplan/events/9006.html&quot;&gt;Implementing an LLVM based Dynamic Binary Instrumentation framework&lt;/a&gt;, 34C3 (2017)&lt;br&gt; - Example: plugging Triton on top of QBDI - &lt;a href=&quot;http://shell-storm.org/repo/Notepad/qbdi_with_triton.txt&quot;&gt;http://shell-storm.org/repo/Notepad/qbdi_with_triton.txt&lt;/a&gt;&lt;br&gt; - A Preliminary Test of QBDI - &lt;a href=&quot;https://www.johnfxgalea.com/2018/01/13/a-preliminary-test-of-qbdi/&quot;&gt;https://www.johnfxgalea.com/2018/01/13/a-preliminary-test-of-qbdi/&lt;/a&gt;&lt;br&gt; - Example: SRAC - a Simple Return Address Checker - &lt;a href=&quot;https://github.com/johnfxgalea/SRAC&quot;&gt;https://github.com/johnfxgalea/SRAC&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Raycast</title>
      <link>https://tedneward.github.io/Research/tools/raycast/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/raycast/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.raycast.com/&quot;&gt;Website&lt;/a&gt; | Freemium/commercial&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>RedPen</title>
      <link>https://tedneward.github.io/Research/tools/redpen/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/redpen/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://redpen.cc/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/redpen-cc/redpen&quot;&gt;Source&lt;/a&gt; &lt;em&gt;(Last update ~2019?)&lt;/em&gt;&lt;/p&gt; 
&lt;h1&gt;Features&lt;/h1&gt; 
&lt;ul&gt; 
 &lt;li&gt;Language independent&lt;/li&gt; 
 &lt;li&gt;Highly customizable&lt;/li&gt; 
 &lt;li&gt;Multi platform (MacOS, Windows, and Linux)&lt;/li&gt; 
 &lt;li&gt;Support various markup text formats (Wiki, Markdown, AsciiDoc, LaTeX, Re:VIEW, reStructuredText)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://blog.redpen.cc/2015/09/08/writing-extension-with-javascript/&quot;&gt;Plugin system: users can write their extensions with JavaScript&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://blog.redpen.cc/2016/06/14/introduction-of-annotation-for-suppressing-errors-from-document-checking-tool-redpen/&quot;&gt;Annotation based error suppression&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://redpen.herokuapp.com/&quot;&gt;Practical REST API and UI&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>RepoAssist</title>
      <link>https://tedneward.github.io/Research/tools/repoassist/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/repoassist/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/githubnext/agentics/blob/main/docs/repo-assist.md&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Using Repo Assist is simple:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;You add it to your repository&lt;/li&gt; 
 &lt;li&gt;It does useful things automatically and repeatedly, at a pace you choose&lt;/li&gt; 
 &lt;li&gt;It reports in an issue&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Reading&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://dsyme.net/2026/02/25/repo-assist-a-repository-assistant/&quot;&gt;Repo Assist: Crunching the Technical Debt with GitHub Agentic Workflows&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>RetDec</title>
      <link>https://tedneward.github.io/Research/tools/retdec/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/retdec/index.html</guid>
      	<description>
	&lt;p&gt;Supported file formats: ELF, PE, Mach-O, COFF, AR (archive), Intel HEX, and raw machine code.&lt;/p&gt; 
&lt;p&gt;Supported architectures (32b only): Intel x86, ARM, MIPS, PIC32, and PowerPC.&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://github.com/avast-tl/retdec&quot;&gt;Github&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>PMD</title>
      <link>https://tedneward.github.io/Research/tools/pmd/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/pmd/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://pmd.github.io/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/pmd/pmd&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Pulp</title>
      <link>https://tedneward.github.io/Research/tools/pulp/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/pulp/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://pulpproject.org/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/pulp/pulpcore&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Qiew</title>
      <link>https://tedneward.github.io/Research/tools/qiew/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/qiew/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/mtivadar/qiew&quot;&gt;Github&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;ELF and PE plugins available&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Reaper</title>
      <link>https://tedneward.github.io/Research/tools/reaper/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/reaper/index.html</guid>
      	<description>
	&lt;p&gt;Source: &lt;a href=&quot;https://github.com/EmergeTools/emerge-android&quot;&gt;Android&lt;/a&gt; &lt;a href=&quot;https://github.com/getsentry/Reaper-iOS&quot;&gt;iOS&lt;/a&gt; &lt;a href=&quot;https://github.com/getsentry/reaper-server&quot;&gt;Server&lt;/a&gt; | &lt;a href=&quot;https://docs.emergetools.com/docs/quickstart&quot;&gt;Docs&lt;/a&gt;&lt;/p&gt; 
&lt;h2&gt;Reading&lt;/h2&gt; 
&lt;h3&gt;Articles&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://blog.sentry.io/an-open-source-sdk-for-finding-dead-code/&quot;&gt;https://blog.sentry.io/an-open-source-sdk-for-finding-dead-code/&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Refine</title>
      <link>https://tedneward.github.io/Research/tools/refine/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/refine/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://refine.dev/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/refinedev/refine&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Rescuezilla</title>
      <link>https://tedneward.github.io/Research/tools/rescuezilla/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/rescuezilla/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://rescuezilla.com/&quot;&gt;Website&lt;/a&gt;&lt;/p&gt; 
&lt;h2&gt;Reading&lt;/h2&gt; 
&lt;h3&gt;Articles&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.xda-developers.com/i-use-rescuezilla-to-swap-between-operating-systems-and-i-love-it/&quot;&gt;I use Rescuezilla to swap between operating systems and I love it&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Robomongo / Robo 3T</title>
      <link>https://tedneward.github.io/Research/tools/robomongo/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/robomongo/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://robomongo.org/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/Studio3T/robomongo&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Poetry</title>
      <link>https://tedneward.github.io/Research/tools/poetry/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/poetry/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://python-poetry.org/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/python-poetry/poetry&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Pulumi</title>
      <link>https://tedneward.github.io/Research/tools/pulumi/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/pulumi/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.pulumi.com/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/pulumi/pulumi&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Rad</title>
      <link>https://tedneward.github.io/Research/tools/rad/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/rad/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://amterp.github.io/rad/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/amterp/rad&quot;&gt;Source&lt;/a&gt; | &lt;a href=&quot;https://amterp.github.io/rad/&quot;&gt;Docs&lt;/a&gt;&lt;/p&gt; 
&lt;h2&gt;&lt;a href=&quot;https://amterp.github.io/rad/guide/getting-started/&quot;&gt;Getting Started&lt;/a&gt;&lt;/h2&gt; 
&lt;p&gt;macOS: &lt;code&gt;brew install amterp/rad/rad&lt;/code&gt;&lt;/p&gt; 
&lt;h2&gt;Examples&lt;/h2&gt; 
&lt;p&gt;Fetch and display GitHub commits in one, minimal script:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;#!/usr/bin/env rad
args:
    repo str        # The repo to query. Format: user/project
    limit int = 20  # Max commits to return

url = &quot;https://api.github.com/repos/{repo}/commits?per_page={limit}&quot;

Time = json[].commit.author.date
Author = json[].commit.author.name
SHA = json[].sha

rad url:
    fields Time, Author, SHA
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Put this &lt;code&gt;commits&lt;/code&gt; script on your PATH, and invoke:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;\&amp;gt; commits spf13/cobra 3
Querying url: https://api.github.com/repos/spf13/cobra/commits?per\_page=3
Time                  Author          SHA
2025-03-07T14:53:22Z  styee           4f9ef8cdbbc88c5302be95e0e67fd78ebbfa9dd2
2025-02-21T12:46:14Z  Fraser Waters   1995054b003053cc1e404bccfbf6d168e8731509
2025-02-17T19:16:17Z  Yedaya Katsman  f98cf4216d3cb5235e6e0cd00ee00959deb1dc65
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;No &lt;code&gt;curl | jq | awk&lt;/code&gt; gymnastics. No argparse boilerplate. Just readable code that does what you want.&lt;/p&gt; 
&lt;p&gt;Explaining the above script:&lt;/p&gt; 
&lt;ol&gt; 
 &lt;li&gt;The script takes two args: a repo string and an optional limit (defaults to 20). 
  &lt;ul&gt; 
   &lt;li&gt;The &lt;code&gt;#&lt;/code&gt; comments are read by Rad and used to generate helpful docs / usage strings for the script.&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;It uses string interpolation to build the url we will query, based on the supplied args.&lt;/li&gt; 
 &lt;li&gt;It defines the fields to extract from the JSON response.&lt;/li&gt; 
 &lt;li&gt;It executes the query, extracting the specified fields from the response, and displays the resulting data as a table. 
  &lt;ul&gt; 
   &lt;li&gt;Note the &lt;code&gt;rad url&lt;/code&gt; syntax: &quot;rad&quot; actually stands for &quot;request and display&quot;, which is what this built-in syntax does.&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ol&gt; 
&lt;p&gt;This example is kept somewhat minimal - there are Rad features we could use to further improve this.&lt;/p&gt; 
&lt;p&gt;Some alternative valid invocations for this example:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;code&gt;&amp;gt; commits amterp/rad&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;&amp;gt; commits --repo amterp/rad --limit 5&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;&amp;gt; commits --limit 5 --repo amterp/rad&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;&amp;gt; commits amterp/rad --limit 5&lt;/code&gt;&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Recaf</title>
      <link>https://tedneward.github.io/Research/tools/recaf/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/recaf/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://recaf.coley.software/home.html&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/Col-E/Recaf&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>RemedyBG</title>
      <link>https://tedneward.github.io/Research/tools/remedybg/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/remedybg/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://remedybg.itch.io/remedybg&quot;&gt;Website&lt;/a&gt; |&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Reshape</title>
      <link>https://tedneward.github.io/Research/tools/reshape/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/reshape/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/fabianlindfors/reshape&quot;&gt;Source&lt;/a&gt; Not production-ready&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Robot Framework</title>
      <link>https://tedneward.github.io/Research/tools/robotframework/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/robotframework/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://robotframework.org/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/robotframework/robotframework&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Example:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;*** Settings ***
Documentation     A test suite with a single test for valid login.
...
...               This test has a workflow that is created using keywords in
...               the imported resource file.
Resource          resource.txt

*** Test Cases ***
Valid Login
    Open Browser To Login Page
    Input Username    demo
    Input Password    mode
    Submit Credentials
    Welcome Page Should Be Open
    [Teardown]    Close Browser
&lt;/code&gt;&lt;/pre&gt;
	</description>
    </item>
    <item>
      <title>Nuxt</title>
      <link>https://tedneward.github.io/Research/tools/nuxt/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/nuxt/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://nuxtjs.org/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/netlify/staticgen&quot;&gt;Souce&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>OmniSharp</title>
      <link>https://tedneward.github.io/Research/tools/omnisharp/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/omnisharp/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;http://www.omnisharp.net/&quot;&gt;Website&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>OpenCloud</title>
      <link>https://tedneward.github.io/Research/tools/opencloud/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/opencloud/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://opencloud.eu/en&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/opencloud-eu&quot;&gt;Source&lt;/a&gt; | Documentation: &lt;a href=&quot;https://docs.opencloud.eu/docs/user/&quot;&gt;User&lt;/a&gt;, &lt;a href=&quot;https://docs.opencloud.eu/docs/admin/&quot;&gt;Admin&lt;/a&gt;, &lt;a href=&quot;https://docs.opencloud.eu/docs/dev/&quot;&gt;Developer&lt;/a&gt;&lt;/p&gt; 
&lt;h2&gt;Getting Started&lt;/h2&gt; 
&lt;h3&gt;&lt;a href=&quot;https://docs.opencloud.eu/docs/admin/getting-started/container/docker&quot;&gt;Docker&lt;/a&gt;&lt;/h3&gt; 
&lt;p&gt;Create Required Directories for Bind Mounts&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;    mkdir -p $HOME/opencloud/opencloud-config
    mkdir -p $HOME/opencloud/opencloud-data
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Pull OpenCloud Image&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;    docker pull opencloudeu/opencloud-rolling:latest
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Initialize OpenCloud (First-time Setup) - You can set your own password using &lt;code&gt;IDM_ADMIN_PASSWORD=your_password&lt;/code&gt;. If not set, a password will be auto-generated&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;    docker run --rm -it \
        -v $HOME/opencloud/opencloud-config:/etc/opencloud \
        -v $HOME/opencloud/opencloud-data:/var/lib/opencloud \
        -e IDM_ADMIN_PASSWORD=admin \
        opencloudeu/opencloud-rolling:latest init
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Start OpenCloud&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;    docker run \
        --name opencloud \
        --rm \
        -d \
        -p 9200:9200 \
        -v $HOME/opencloud/opencloud-config:/etc/opencloud \
        -v $HOME/opencloud/opencloud-data:/var/lib/opencloud \
        -e OC_INSECURE=true \
        -e PROXY_HTTP_ADDR=0.0.0.0:9200 \
        -e OC_URL=https://localhost:9200 \
        opencloudeu/opencloud-rolling:latest
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Login with your browser:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;    https://localhost:9200
    user: admin
    password: admin
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;&lt;a href=&quot;https://docs.opencloud.eu/docs/admin/getting-started/container/docker-compose/docker-compose-base/&quot;&gt;Docker Compose&lt;/a&gt;&lt;/h3&gt; 
&lt;p&gt;Goal: Install a internet facing OpenCloud with SSL certification with Docker Compose. This installation documentation is for Ubuntu and Debian systems. The software can also be installed on other Linux distributions, but the commands and package managers may differ.&lt;/p&gt; 
&lt;h4&gt;Prerequisites&lt;/h4&gt; 
&lt;p&gt;Four domains pointing to your server:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;cloud.YOUR.DOMAIN → OpenCloud frontend&lt;/li&gt; 
 &lt;li&gt;collabora.YOUR.DOMAIN → Collabora Online Server&lt;/li&gt; 
 &lt;li&gt;wopiserver.YOUR.DOMAIN → WOPI server for document editing&lt;/li&gt; 
 &lt;li&gt;traefik.YOUR.DOMAIN → Traefik dashboard&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;Alternatively, you can use a wildcard domain (*.YOUR.DOMAIN)&lt;/p&gt; 
&lt;p&gt;A hosted server (e.g., Hetzner, AWS, or your own VPS) with Linux and SSH access&lt;/p&gt; 
&lt;p&gt;Log into your server via SSH: &lt;code&gt;ssh root@YOUR.SERVER.IP&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;First, perform an update and upgrade: &lt;code&gt;apt update &amp;amp;&amp;amp; apt upgrade -y&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;Install Docker following the official Docker guide. Once Docker is installed, enable and start the service: &lt;code&gt;systemctl enable docker &amp;amp;&amp;amp; systemctl start docker&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;Download the necessary configuration files: &lt;code&gt;git clone https://github.com/opencloud-eu/opencloud-compose.git&lt;/code&gt;&lt;/p&gt; 
&lt;h4&gt;Configure the .env File for Staging Certificates&lt;/h4&gt; 
&lt;p&gt;Before requesting real SSL certificates, test the setup with Let&apos;s Encrypt’s staging environment.&lt;/p&gt; 
&lt;p&gt;Navigate to the OpenCloud configuration folder: &lt;code&gt;cd opencloud-compose&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;Create environment file: &lt;code&gt;cp .env.example .env&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;NOTE: The repository includes .env.example as a template with default settings and documentation. Your actual .env file is excluded from version control (via .gitignore) to prevent accidentally committing sensitive information like passwords and domain-specific settings.&lt;/p&gt; 
&lt;p&gt;Edit the .env file with the editor of your choice.&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt; &lt;p&gt;Disable insecure mode&lt;/p&gt; &lt;pre&gt;&lt;code&gt;# INSECURE=true
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Set your domain names&lt;/p&gt; &lt;pre&gt;&lt;code&gt;TRAEFIK_DOMAIN=traefik.YOUR.DOMAIN
OC_DOMAIN=cloud.YOUR.DOMAIN
COLLABORA_DOMAIN=collabora.YOUR.DOMAIN
WOPISERVER_DOMAIN=wopiserver.YOUR.DOMAIN
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Set your admin password&lt;/p&gt; &lt;pre&gt;&lt;code&gt;INITIAL_ADMIN_PASSWORD=YourSecurePassword
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Set your email for SSL certification&lt;/p&gt; &lt;pre&gt;&lt;code&gt;TRAEFIK_ACME_MAIL=your@email.com
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Use Let&apos;s Encrypt staging certificates (for testing)&lt;/p&gt; &lt;pre&gt;&lt;code&gt;TRAEFIK_ACME_CASERVER=https://acme-staging-v02.api.letsencrypt.org/directory
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Set your deployment options. For Example without Collabora:&lt;/p&gt; &lt;pre&gt;&lt;code&gt;COMPOSE_FILE=docker-compose.yml:traefik/opencloud.yml
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;Save and exit.&lt;/p&gt; 
&lt;h4&gt;Production Setup Consideration&lt;/h4&gt; 
&lt;p&gt;Production Setup Recommended: By default, OpenCloud stores configuration and data inside internal Docker volumes. This works fine for local development or quick evaluations — but is not suitable for production environments.&lt;/p&gt; 
&lt;p&gt;In production, you should mount persistent local directories for configuration and data to ensure:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Data durability&lt;/li&gt; 
 &lt;li&gt;Easier backups and recovery&lt;/li&gt; 
 &lt;li&gt;Full control over storage location and permissions&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;Update your .env file with custom paths:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;    OC_CONFIG_DIR=/your/local/path/opencloud/config
    OC_DATA_DIR=/your/local/path/opencloud/data
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Folder Permissions: Ensure these folders exist and are owned by user and group 1000:1000, which the Docker containers use by default:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;    sudo mkdir -p /your/local/path/opencloud/{config,data}
    sudo chown -R 1000:1000 /your/local/path/opencloud
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;If these variables are left unset, Docker will use internal volumes, which do not persist if the containers are removed — not recommended for real-world use.&lt;/p&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;Security Warning: The user with UID 1000 on your host system will have full access to these mounted directories. This means that any local user account with this ID can read, modify, or delete OpenCloud config and data files. This can pose a security risk in shared or multi-user environments. Make sure to implement proper user and permission management and consider isolating access to these directories.&lt;/p&gt; 
&lt;/blockquote&gt; 
&lt;p&gt;Use production release container: To avoid accidentally updating to a version with breaking changes, you should specify the production container version to be used in your .env file:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;    OC_DOCKER_IMAGE=opencloudeu/opencloud
    OC_DOCKER_TAG=2
&lt;/code&gt;&lt;/pre&gt; 
&lt;h4&gt;Start OpenCloud&lt;/h4&gt; 
&lt;p&gt;Launch OpenCloud using Docker Compose: &lt;code&gt;docker compose up -d&lt;/code&gt; This will start all required services in the background.&lt;/p&gt; 
&lt;h4&gt;Verify SSL Certification&lt;/h4&gt; 
&lt;p&gt;In your web browser, visit:&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://cloud.YOUR.DOMAIN&quot;&gt;https://cloud.YOUR.DOMAIN&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;You should see a security warning because the staging certificate is not fully trusted. Same should appear with the other domains you are using.&lt;/p&gt; 
&lt;p&gt;Certificate Details: Check the certificate details to confirm it’s from Let&apos;s Encrypt Staging.&lt;/p&gt; 
&lt;h4&gt;Apply a Real SSL Certificate&lt;/h4&gt; 
&lt;p&gt;Once the staging certificate works, switch to a production certificate.&lt;/p&gt; 
&lt;p&gt;Stop Docker Compose: &lt;code&gt;docker compose down&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;Remove old staging certificates: &lt;code&gt;rm -r certs&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;Disable staging mode in .env: Edit .env&lt;/p&gt; 
&lt;p&gt;Comment the staging server:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;    # TRAEFIK_ACME_CASERVER=https://acme-staging-v02.api.letsencrypt.org/directory
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Restart OpenCloud with a real SSL certificate&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;    docker compose up -d
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Now, visiting &lt;a href=&quot;https://cloud.YOUR.DOMAIN&quot;&gt;https://cloud.YOUR.DOMAIN&lt;/a&gt; should show a secure connection with a valid SSL certificate.&lt;/p&gt; 
&lt;h4&gt;Log into OpenCloud&lt;/h4&gt; 
&lt;p&gt;Open a browser and visit:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;    https://cloud.YOUR.DOMAIN
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Login with:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;    Username: admin
    Password: (your password)
&lt;/code&gt;&lt;/pre&gt;
	</description>
    </item>
    <item>
      <title>OpenTofu</title>
      <link>https://tedneward.github.io/Research/tools/opentofu/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/opentofu/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://opentofu.org/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/opentofu/opentofu&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;What is OpenTofu? OpenTofu is an infrastructure as code tool that lets you define both cloud and on-prem resources in human-readable configuration files that you can version, reuse, and share. You can then use a consistent workflow to provision and manage all of your infrastructure throughout its lifecycle. OpenTofu can manage low-level components like compute, storage, and networking resources, as well as high-level components like DNS entries and SaaS features.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Pandoc</title>
      <link>https://tedneward.github.io/Research/tools/pandoc/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/pandoc/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://pandoc.org/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/jgm/pandoc/&quot;&gt;Source&lt;/a&gt; | &lt;a href=&quot;https://pandoc.org/demos.html&quot;&gt;Demos&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Written in Haskell.&lt;/p&gt; 
&lt;p&gt;Converts to/from more formats than most people realize exist:&lt;/p&gt; 
&lt;p&gt;(← = conversion from; → = conversion to; ↔︎ = conversion from and to)&lt;/p&gt; 
&lt;p&gt;Lightweight markup formats:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;↔︎ Markdown (including CommonMark and GitHub-flavored Markdown)&lt;/li&gt; 
 &lt;li&gt;↔︎ reStructuredText&lt;/li&gt; 
 &lt;li&gt;↔︎ AsciiDoc&lt;/li&gt; 
 &lt;li&gt;↔︎ Emacs Org-Mode&lt;/li&gt; 
 &lt;li&gt;↔︎ Emacs Muse&lt;/li&gt; 
 &lt;li&gt;↔︎ Textile&lt;/li&gt; 
 &lt;li&gt;→ Markua&lt;/li&gt; 
 &lt;li&gt;← txt2tags&lt;/li&gt; 
 &lt;li&gt;↔︎ djot&lt;/li&gt; 
 &lt;li&gt;→ BBCode&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;HTML formats&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;↔︎ (X)HTML 4&lt;/li&gt; 
 &lt;li&gt;↔︎ HTML5&lt;/li&gt; 
 &lt;li&gt;→ Chunked HTML&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;Ebooks&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;↔︎ EPUB version 2 or 3&lt;/li&gt; 
 &lt;li&gt;↔︎ FictionBook2&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;Documentation formats&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;→ GNU TexInfo&lt;/li&gt; 
 &lt;li&gt;← pod&lt;/li&gt; 
 &lt;li&gt;↔︎ Haddock markup&lt;/li&gt; 
 &lt;li&gt;→ Vimdoc&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;Roff formats&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;↔︎ roff man&lt;/li&gt; 
 &lt;li&gt;→ roff ms&lt;/li&gt; 
 &lt;li&gt;← mdoc&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;TeX formats&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;↔︎ LaTeX&lt;/li&gt; 
 &lt;li&gt;→ ConTeXt&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;XML formats&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;↔︎ DocBook version 4 or 5&lt;/li&gt; 
 &lt;li&gt;↔︎ JATS&lt;/li&gt; 
 &lt;li&gt;← BITS&lt;/li&gt; 
 &lt;li&gt;→ TEI Simple&lt;/li&gt; 
 &lt;li&gt;→ OpenDocument XML&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;Outline formats&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;↔︎ OPML&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;Bibliography formats&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;↔︎ BibTeX&lt;/li&gt; 
 &lt;li&gt;↔︎ BibLaTeX&lt;/li&gt; 
 &lt;li&gt;↔︎ CSL JSON&lt;/li&gt; 
 &lt;li&gt;↔︎ CSL YAML&lt;/li&gt; 
 &lt;li&gt;← RIS&lt;/li&gt; 
 &lt;li&gt;← EndNote XML&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;Word processor formats&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;↔︎ Microsoft Word docx&lt;/li&gt; 
 &lt;li&gt;↔︎ Rich Text Format RTF&lt;/li&gt; 
 &lt;li&gt;↔︎ OpenOffice/LibreOffice ODT&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;Interactive notebook formats&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;↔︎ Jupyter notebook (ipynb)&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;Page layout formats&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;→ InDesign ICML&lt;/li&gt; 
 &lt;li&gt;↔︎ Typst&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;Wiki markup formats&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;↔︎ MediaWiki markup&lt;/li&gt; 
 &lt;li&gt;↔︎ DokuWiki markup&lt;/li&gt; 
 &lt;li&gt;← TikiWiki markup&lt;/li&gt; 
 &lt;li&gt;← TWiki markup&lt;/li&gt; 
 &lt;li&gt;← Vimwiki markup&lt;/li&gt; 
 &lt;li&gt;→ XWiki markup&lt;/li&gt; 
 &lt;li&gt;→ ZimWiki markup&lt;/li&gt; 
 &lt;li&gt;↔︎ Jira wiki markup&lt;/li&gt; 
 &lt;li&gt;← Creole&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;Slide show formats&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;→ LaTeX Beamer&lt;/li&gt; 
 &lt;li&gt;↔︎ Microsoft PowerPoint&lt;/li&gt; 
 &lt;li&gt;→ Slidy&lt;/li&gt; 
 &lt;li&gt;→ reveal.js&lt;/li&gt; 
 &lt;li&gt;→ Slideous&lt;/li&gt; 
 &lt;li&gt;→ S5&lt;/li&gt; 
 &lt;li&gt;→ DZSlides&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;Data formats&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;← CSV tables&lt;/li&gt; 
 &lt;li&gt;← TSV tables&lt;/li&gt; 
 &lt;li&gt;← Microsoft Excel spreadsheets&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;Terminal output&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;→ ANSI-formatted text&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;Serialization formats&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;↔︎ Haskell AST&lt;/li&gt; 
 &lt;li&gt;↔︎ JSON representation of AST&lt;/li&gt; 
 &lt;li&gt;↔︎ XML representation of AST&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;Custom formats&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;↔︎ custom readers and writers can be written in Lua&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;PDF&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;→ via pdflatex, lualatex, xelatex, latexmk, tectonic, wkhtmltopdf, weasyprint, prince, pagedjs-cli, context, or pdfroff.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Installation&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;macOS: &lt;code&gt;brew install pandoc&lt;/code&gt;; integrations may be useful too: &lt;code&gt;brew install librsvg python homebrew/cask/basictex&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;Docker: &lt;code&gt;docker run --rm --volume &quot;&lt;/code&gt;pwd&lt;code&gt;:/data&quot; --user&lt;/code&gt;id -u&lt;code&gt;:&lt;/code&gt;id -g&lt;code&gt;pandoc/latex README.md -o README.pdf&lt;/code&gt; converts README.md to README.pdf 
  &lt;ul&gt; 
   &lt;li&gt;The official Docker images for pandoc can be found at &lt;a href=&quot;https://github.com/pandoc/dockerfiles&quot;&gt;https://github.com/pandoc/dockerfiles&lt;/a&gt; and at dockerhub.&lt;/li&gt; 
   &lt;li&gt;The &lt;a href=&quot;https://hub.docker.com/r/pandoc/core&quot;&gt;pandoc/core&lt;/a&gt; image contains pandoc. The &lt;a href=&quot;https://hub.docker.com/r/pandoc/latex&quot;&gt;pandoc/latex&lt;/a&gt; image also contains the minimal LaTeX installation needed to produce PDFs using pandoc.&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Build Actions&lt;/h2&gt; 
&lt;p&gt;Pandoc can be run through &lt;a href=&quot;https://github.com/features/actions&quot;&gt;GitHub Actions&lt;/a&gt;. For some examples, see &lt;a href=&quot;https://github.com/pandoc/pandoc-action-example&quot;&gt;https://github.com/pandoc/pandoc-action-example&lt;/a&gt;.&lt;/p&gt; 
&lt;p&gt;Pandoc can be run through &lt;a href=&quot;https://about.gitlab.com/stages-devops-lifecycle/continuous-integration/&quot;&gt;GitLab CI/CD&lt;/a&gt;. For some examples, see &lt;a href=&quot;https://gitlab.com/pandoc/pandoc-ci-example&quot;&gt;https://gitlab.com/pandoc/pandoc-ci-example&lt;/a&gt;.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>PDFKeeper</title>
      <link>https://tedneward.github.io/Research/tools/pdfkeeper/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/pdfkeeper/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.pdfkeeper.org/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/rffrasca/PDFKeeper/&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;PDFKeeper began as an idea to solve a personal document storage issue. With both digital and paper documents stored in many places, it was becoming a challenge to locate documents quickly, especially at tax time. What proved to be an even bigger challenge was locating a free solution that could store PDF documents in a free, full-text search ready, relational database that could be accessed by anyone on the local area network. In addition, I had a requirement to store notes in the database with the PDF document that would also be searchable.&lt;/p&gt; 
&lt;p&gt;​In early 2009, after being unsuccessful in locating a solution, I started building PDFKeeper, an open-source application that would use a free, full-text search ready, relational database for PDF document and notes storage, targeted at the Small Office Home Office and Small Business community. To develop the application quickly, I decided to build it with Open Object REXX, a scripting language with GUI support that I was very familiar with from my OS/2 days. As for the database, I chose to use Oracle® Database XE since it was free and was capable of indexing PDF documents; but it was my plan to expand database compatibility to other platforms over time.&lt;/p&gt; 
&lt;p&gt;​## Reading&lt;/p&gt; 
&lt;h3&gt;Articles&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.xda-developers.com/free-open-source-app-only-utility-need-for-managing-hundreds-of-pdfs/&quot;&gt;https://www.xda-developers.com/free-open-source-app-only-utility-need-for-managing-hundreds-of-pdfs/&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Performance tools and research</title>
      <link>https://tedneward.github.io/Research/tools/performance/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/performance/index.html</guid>
      	<description>
	&lt;h2&gt;Software&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;benchmark (Google) 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/google/benchmark&quot;&gt;https://github.com/google/benchmark&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://opensource.googleblog.com/2014/01/introducing-benchmark.html&quot;&gt;https://opensource.googleblog.com/2014/01/introducing-benchmark.html&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Celero 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/DigitalInBlue/Celero&quot;&gt;https://github.com/DigitalInBlue/Celero&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;hayai: the C++ benchmarking framework 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/nickbruun/hayai&quot;&gt;https://github.com/nickbruun/hayai&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;moodycamel::microbench 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/cameron314/microbench&quot;&gt;https://github.com/cameron314/microbench&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;geiger: A micro benchmark library in C++ that supports hardware performance counters 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/david-grs/geiger&quot;&gt;https://github.com/david-grs/geiger&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Nonius: A C++ micro-benchmarking framework 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/libnonius/nonius&quot;&gt;https://github.com/libnonius/nonius&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Readings&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;Examples: 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;http://www.bfilipek.com/2016/01/micro-benchmarking-libraries-for-c.html&quot;&gt;http://www.bfilipek.com/2016/01/micro-benchmarking-libraries-for-c.html&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://www.bfilipek.com/2016/02/revisiting-old-benchmark-vector-of.html&quot;&gt;http://www.bfilipek.com/2016/02/revisiting-old-benchmark-vector-of.html&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://www.bfilipek.com/2016/05/google-benchmark-library.html&quot;&gt;http://www.bfilipek.com/2016/05/google-benchmark-library.html&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Systems Benchmarking Crimes - Gernot Heiser - &lt;a href=&quot;https://www.cse.unsw.edu.au/~gernot/benchmarking-crimes.html&quot;&gt;https://www.cse.unsw.edu.au/~gernot/benchmarking-crimes.html&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h1&gt;Memory&lt;/h1&gt; 
&lt;h2&gt;Memory - Benchmarking&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;Intel Memory Latency Checker (MLC) 
  &lt;ul&gt; 
   &lt;li&gt;a tool used to measure memory latencies and bandwidth, and how they change with increasing load on the system&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.intel.com/software/mlc&quot;&gt;https://www.intel.com/software/mlc&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Memory Bandwidth Benchmark 
  &lt;ul&gt; 
   &lt;li&gt;MBW determines the &quot;copy&quot; memory bandwidth available to userspace programs. Its simplistic approach models that of real applications. It is not tuned to extremes and it is not aware of hardware architecture, just like your average software package.&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/raas/mbw&quot;&gt;https://github.com/raas/mbw&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;pmbw: Parallel Memory Bandwidth Benchmark / Measurement 
  &lt;ul&gt; 
   &lt;li&gt;a set of assembler routines to measure the parallel memory (cache and RAM) bandwidth of modern multi-core machines&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://panthema.net/2013/pmbw/&quot;&gt;http://panthema.net/2013/pmbw/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/bingmann/pmbw&quot;&gt;https://github.com/bingmann/pmbw&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Spatter: Benchmark for measuring the performance of sparse and irregular memory access 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/hpcgarage/spatter&quot;&gt;https://github.com/hpcgarage/spatter&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Spatter: A Tool for Evaluating Gather / Scatter Performance 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://arxiv.org/abs/1811.03743&quot;&gt;https://arxiv.org/abs/1811.03743&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;STREAM: Sustainable Memory Bandwidth in High Performance Computers 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;http://www.cs.virginia.edu/stream/&quot;&gt;http://www.cs.virginia.edu/stream/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;STREAM benchmark - &lt;a href=&quot;https://github.com/jeffhammond/STREAM&quot;&gt;https://github.com/jeffhammond/STREAM&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;NUMA-STREAM - &lt;a href=&quot;https://github.com/larsbergstrom/NUMA-STREAM&quot;&gt;https://github.com/larsbergstrom/NUMA-STREAM&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;BabelStream: STREAM, for lots of devices written in many programming models 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://github.com/UoB-HPC/BabelStream&quot;&gt;https://github.com/UoB-HPC/BabelStream&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;http://uob-hpc.github.io/BabelStream/&quot;&gt;http://uob-hpc.github.io/BabelStream/&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;tinymembench: simple benchmark for memory throughput and latency 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/ssvb/tinymembench&quot;&gt;https://github.com/ssvb/tinymembench&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Memory - Profiling&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;Heaptrack - A Heap Memory Profiler for Linux 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/KDE/heaptrack&quot;&gt;https://github.com/KDE/heaptrack&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://milianw.de/blog/heaptrack-a-heap-memory-profiler-for-linux&quot;&gt;http://milianw.de/blog/heaptrack-a-heap-memory-profiler-for-linux&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.kdab.com/heaptrack-v1-0-0-release/&quot;&gt;https://www.kdab.com/heaptrack-v1-0-0-release/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;How to Write a Heap Memory Profiler 
  &lt;ul&gt; 
   &lt;li&gt;CppCon 2019; Milian Wolff&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=YB0QoWI-g8E&quot;&gt;https://www.youtube.com/watch?v=YB0QoWI-g8E&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Slides &amp;amp; code: &lt;a href=&quot;https://github.com/milianw/how-to-write-a-memory-profiler&quot;&gt;https://github.com/milianw/how-to-write-a-memory-profiler&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;MALT &amp;amp; NUMAPROF: Memory Profiling for HPC Applications 
  &lt;ul&gt; 
   &lt;li&gt;NUMAPROF: a NUMA memory profiler based on Pintool to track remote memory accesses 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://memtt.github.io/numaprof&quot;&gt;https://memtt.github.io/numaprof&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://github.com/memtt/numaprof&quot;&gt;https://github.com/memtt/numaprof&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;MALT: a MALloc Tracker to find where and how your made your memory allocations in C/C++/Fortran applications 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://memtt.github.io/malt/&quot;&gt;https://memtt.github.io/malt/&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://github.com/memtt/malt&quot;&gt;https://github.com/memtt/malt&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;MALT: A Malloc Tracker 
    &lt;ul&gt; 
     &lt;li&gt;International Workshop on Software Engineering for Parallel Systems (SEPS) 2017&lt;/li&gt; 
     &lt;li&gt;Sébastien Valat, Andres S. Charif-Rubial, William Jalby&lt;/li&gt; 
     &lt;li&gt;paper: &lt;a href=&quot;https://memtt.github.io/malt/downloads/2017-seps-malt.pdf&quot;&gt;https://memtt.github.io/malt/downloads/2017-seps-malt.pdf&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;slides: &lt;a href=&quot;https://svalat.github.io/docs/2017-10-MALT-SEPS17.pdf&quot;&gt;https://svalat.github.io/docs/2017-10-MALT-SEPS17.pdf&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;FOSDEM 2019; Sébastien Valat 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=TnMOjdIy_Ow&quot;&gt;https://www.youtube.com/watch?v=TnMOjdIy_Ow&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://fosdem.org/2019/schedule/event/numaprof/&quot;&gt;https://fosdem.org/2019/schedule/event/numaprof/&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Memoro: A Detailed Heap Profiler 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://epfl-vlsc.github.io/memoro/&quot;&gt;https://epfl-vlsc.github.io/memoro/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/epfl-vlsc/memoro&quot;&gt;https://github.com/epfl-vlsc/memoro&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Detailed Heap Profiling 
    &lt;ul&gt; 
     &lt;li&gt;International Symposium on Memory Management (ISMM) 2018&lt;/li&gt; 
     &lt;li&gt;Stuart Byma, Jim Larus&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://dl.acm.org/citation.cfm?id=3210564&quot;&gt;https://dl.acm.org/citation.cfm?id=3210564&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;Memoro: Scaling an LLVM-based Heap profiler 
    &lt;ul&gt; 
     &lt;li&gt;2019 LLVM Developers’ Meeting; Thierry Treyer&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=fm47XsATelI&quot;&gt;https://www.youtube.com/watch?v=fm47XsATelI&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://llvm.org/devmtg/2019-10/slides/Treyer-Memoro.pdf&quot;&gt;https://llvm.org/devmtg/2019-10/slides/Treyer-Memoro.pdf&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;memory-profiler: A memory profiler for Linux 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/nokia/memory-profiler&quot;&gt;https://github.com/nokia/memory-profiler&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;memtrail: A LD_PRELOAD based memory profiler and leak detector for Linux 
  &lt;ul&gt; 
   &lt;li&gt;​&lt;a href=&quot;https://github.com/jrfonseca/memtrail&quot;&gt;https://github.com/jrfonseca/memtrail&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;memusage - profile memory usage of a program 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;http://man7.org/linux/man-pages/man1/memusage.1.html&quot;&gt;http://man7.org/linux/man-pages/man1/memusage.1.html&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;MTuner - a C/C++ memory profiler and memory leak finder for Windows, PlayStation 4, PlayStation 3, etc. 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://milostosic.github.io/MTuner/&quot;&gt;https://milostosic.github.io/MTuner/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/milostosic/MTuner&quot;&gt;https://github.com/milostosic/MTuner&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;PerfMemPlus: A Tool for Automatic Discovery of Memory Performance Problems 
  &lt;ul&gt; 
   &lt;li&gt;Tool for memory performance analysis based on Linux perf.&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/helchr/perfMemPlus&quot;&gt;https://github.com/helchr/perfMemPlus&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;PerfMemPlus: A Tool for Automatic Discovery of Memory Performance Problems 
    &lt;ul&gt; 
     &lt;li&gt;ISC 2019&lt;/li&gt; 
     &lt;li&gt;Christian Helm, Kenjiro Taura&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://doi.org/10.1007/978-3-030-20656-7_11&quot;&gt;https://doi.org/10.1007/978-3-030-20656-7_11&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;On the Correct Measurement of Application Memory Bandwidth and Memory Access Latency 
    &lt;ul&gt; 
     &lt;li&gt;HPC Asia 2020&lt;/li&gt; 
     &lt;li&gt;Christian Helm, Kenjiro Taura&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://doi.org/10.1145/3368474.3368476&quot;&gt;https://doi.org/10.1145/3368474.3368476&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Typegrind 
  &lt;ul&gt; 
   &lt;li&gt;a type preserving heap profiler for C++ - collects memory allocation information with type information&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://typegrind.github.io/&quot;&gt;https://typegrind.github.io/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/typegrind/typegrind&quot;&gt;https://github.com/typegrind/typegrind&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Valgrind 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;http://valgrind.org/&quot;&gt;http://valgrind.org/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;DHAT: a dynamic heap analysis tool - &lt;a href=&quot;http://valgrind.org/docs/manual/dh-manual.html&quot;&gt;http://valgrind.org/docs/manual/dh-manual.html&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Massif: a heap profiler - ​&lt;a href=&quot;http://valgrind.org/docs/manual/ms-manual.html&quot;&gt;http://valgrind.org/docs/manual/ms-manual.html&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h1&gt;Microarchitecture&lt;/h1&gt; 
&lt;ul&gt; 
 &lt;li&gt;Tools for microarchitectural benchmarking 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://dendibakh.github.io/blog/2018/04/03/Tools-for-microarchitectural-benchmarking&quot;&gt;https://dendibakh.github.io/blog/2018/04/03/Tools-for-microarchitectural-benchmarking&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;asmbench: A Benchmark Toolkit for Assembly Instructions Using the LLVM JIT 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/RRZE-HPC/asmbench&quot;&gt;https://github.com/RRZE-HPC/asmbench&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;OoO Instruction Benchmarking Framework on the Back of Dragons 
    &lt;ul&gt; 
     &lt;li&gt;2018 SC18 ACM SRC Poster&lt;/li&gt; 
     &lt;li&gt;J. Hammer, G. Hager, G. Wellein&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://sc18.supercomputing.org/proceedings/src_poster/src_poster_pages/spost115.html&quot;&gt;https://sc18.supercomputing.org/proceedings/src_poster/src_poster_pages/spost115.html&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;BHive: A Benchmark Suite and Measurement Framework for Validating x86-64 Basic Block Performance Models 
  &lt;ul&gt; 
   &lt;li&gt;IISWC 2019&lt;/li&gt; 
   &lt;li&gt;Yishen Chen, Ajay Brahmakshatriya, Charith Mendis, Alex Renda, Eric Atkinson, Ondrej Sykora, Saman Amarasinghe, Michael Carbin&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://groups.csail.mit.edu/commit/papers/19/ithemal-measurement.pdf&quot;&gt;http://groups.csail.mit.edu/commit/papers/19/ithemal-measurement.pdf&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/ithemal/bhive&quot;&gt;https://github.com/ithemal/bhive&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Intel Architecture Code Analyzer (IACA) 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://software.intel.com/en-us/articles/intel-architecture-code-analyzer&quot;&gt;https://software.intel.com/en-us/articles/intel-architecture-code-analyzer&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;ibench: Measure instruction latency and throughput 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/hofm/ibench&quot;&gt;https://github.com/hofm/ibench&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Ithemal: Instruction THroughput Estimator using MAchine Learning 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/psg-mit/Ithemal&quot;&gt;https://github.com/psg-mit/Ithemal&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Ithemal: Accurate, Portable and Fast Basic Block Throughput Estimation using Deep Neural Networks 
    &lt;ul&gt; 
     &lt;li&gt;ICML 2019&lt;/li&gt; 
     &lt;li&gt;Charith Mendis, Alex Renda, Saman Amarasinghe, Michael Carbin&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://arxiv.org/abs/1808.07412&quot;&gt;https://arxiv.org/abs/1808.07412&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;http://proceedings.mlr.press/v97/mendis19a.html&quot;&gt;http://proceedings.mlr.press/v97/mendis19a.html&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;llvm-exegesis – LLVM Machine Instruction Benchmark 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://llvm.org/docs/CommandGuide/llvm-exegesis.html&quot;&gt;https://llvm.org/docs/CommandGuide/llvm-exegesis.html&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/llvm-mirror/llvm/tree/master/tools/llvm-exegesis&quot;&gt;https://github.com/llvm-mirror/llvm/tree/master/tools/llvm-exegesis&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Static Performance Analysis with LLVM 
    &lt;ul&gt; 
     &lt;li&gt;2018 European LLVM Developers Meeting&lt;/li&gt; 
     &lt;li&gt;C. Courbet, O. Sykora, G. Chatelet, B. De Backer&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://youtu.be/XinMk-t8N-w&quot;&gt;https://youtu.be/XinMk-t8N-w&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;http://llvm.org/devmtg/2018-04/slides/Courbet-Static%20Performance%20Analysis%20with%20LLVM.pdf&quot;&gt;http://llvm.org/devmtg/2018-04/slides/Courbet-Static%20Performance%20Analysis%20with%20LLVM.pdf&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;Measuring x86 instruction latencies with LLVM 
    &lt;ul&gt; 
     &lt;li&gt;2018 European LLVM Developers Meeting&lt;/li&gt; 
     &lt;li&gt;G. Chatelet, C. Courbet, B. De Backer, O. Sykora&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://youtu.be/ex_C27OoApI&quot;&gt;https://youtu.be/ex_C27OoApI&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;http://llvm.org/devmtg/2018-04/slides/Chatelet-Measuring%20x86%20instruction%20latencies%20with%20LLVM.pdf&quot;&gt;http://llvm.org/devmtg/2018-04/slides/Chatelet-Measuring%20x86%20instruction%20latencies%20with%20LLVM.pdf&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;llvm-mca - LLVM Machine Code Analyzer 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://llvm.org/docs/CommandGuide/llvm-mca.html&quot;&gt;https://llvm.org/docs/CommandGuide/llvm-mca.html&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/llvm-mirror/llvm/tree/master/tools/llvm-mca&quot;&gt;https://github.com/llvm-mirror/llvm/tree/master/tools/llvm-mca&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Understanding the performance of code using LLVM&apos;s Machine Code Analyzer (llvm-mca) 
    &lt;ul&gt; 
     &lt;li&gt;2018 LLVM Developers’ Meeting; Andrea Di Biagio &amp;amp; Matt Davis&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=Ku2D8bjEGXk&quot;&gt;https://www.youtube.com/watch?v=Ku2D8bjEGXk&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;MC Ruler: Seamless llvm-mca CMake integration 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://github.com/jeremyong/mc_ruler&quot;&gt;https://github.com/jeremyong/mc_ruler&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;nanoBench: A tool for running small microbenchmarks on recent Intel and AMD x86 CPUs 
  &lt;ul&gt; 
   &lt;li&gt;used for running the microbenchmarks for obtaining the latency, throughput, and port usage data available on &lt;a href=&quot;http://uops.info&quot;&gt;http://uops.info&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/andreas-abel/nanoBench&quot;&gt;https://github.com/andreas-abel/nanoBench&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://uops.info/&quot;&gt;https://uops.info/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;nanoBench Cache Analyzer 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://github.com/andreas-abel/nanoBench/tree/master/tools/CacheAnalyzer&quot;&gt;https://github.com/andreas-abel/nanoBench/tree/master/tools/CacheAnalyzer&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://uops.info/cache.html&quot;&gt;https://uops.info/cache.html&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;uops.info: Characterizing Latency, Throughput, and Port Usage of Instructions on Intel Microarchitectures 
    &lt;ul&gt; 
     &lt;li&gt;ASPLOS 2019&lt;/li&gt; 
     &lt;li&gt;Andreas Abel, Jan Reineke&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://arxiv.org/abs/1810.04610&quot;&gt;https://arxiv.org/abs/1810.04610&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;nanoBench: A Low-Overhead Tool for Running Microbenchmarks on x86 Systems 
    &lt;ul&gt; 
     &lt;li&gt;2019; Andreas Abel, Jan Reineke&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://arxiv.org/abs/1911.03282&quot;&gt;https://arxiv.org/abs/1911.03282&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Open Power/Performance Analysis Tool (OPPAT) 
  &lt;ul&gt; 
   &lt;li&gt;a cross-OS, cross-architecture Power and Performance Analysis Tool&lt;/li&gt; 
   &lt;li&gt;cross-OS: supports Windows ETW trace files and Linux/Android perf/trace-cmd trace files&lt;/li&gt; 
   &lt;li&gt;cross-architecture: supports Intel and ARM chips hardware events (using perf and/or PCM)&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://patinnc.github.io/&quot;&gt;https://patinnc.github.io/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/patinnc/oppat&quot;&gt;https://github.com/patinnc/oppat&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;OSACA: Open Source Architecture Code Analyzer 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/RRZE-HPC/osaca&quot;&gt;https://github.com/RRZE-HPC/osaca&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://hpc.fau.de/research/tools/&quot;&gt;https://hpc.fau.de/research/tools/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Automated Instruction Stream Throughput Prediction for Intel and AMD Microarchitectures 
    &lt;ul&gt; 
     &lt;li&gt;Performance Modeling, Benchmarking and Simulation of High Performance Computer Systems (PMBS) 2018&lt;/li&gt; 
     &lt;li&gt;Jan Laukemann, Julian Hammer, Johannes Hofmann, Georg Hager, Gerhard Wellein&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://arxiv.org/abs/1809.00912&quot;&gt;https://arxiv.org/abs/1809.00912&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;Automatic Throughput and Critical Path Analysis of x86 and ARM Assembly Kernels 
    &lt;ul&gt; 
     &lt;li&gt;arXiv 2019&lt;/li&gt; 
     &lt;li&gt;Jan Laukemann, Julian Hammer, Georg Hager, Gerhard Wellein&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://arxiv.org/abs/1910.00214&quot;&gt;https://arxiv.org/abs/1910.00214&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://github.com/RRZE-HPC/OSACA-CP-2019&quot;&gt;https://github.com/RRZE-HPC/OSACA-CP-2019&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;Cross-Architecture Automatic Critical Path Detection For In-Core Performance Analysis 
    &lt;ul&gt; 
     &lt;li&gt;2020 Master Thesis; Jan Laukemann&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://hpc.fau.de/files/2020/02/Masterarbeit_JL-_final.pdf&quot;&gt;https://hpc.fau.de/files/2020/02/Masterarbeit_JL-_final.pdf&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;Measurements and reproducibility instructions 
      &lt;ul&gt; 
       &lt;li&gt;&lt;a href=&quot;https://github.com/RRZE-HPC/OSACA-Artifact-Appendix&quot;&gt;https://github.com/RRZE-HPC/OSACA-Artifact-Appendix&lt;/a&gt;&lt;/li&gt; 
      &lt;/ul&gt; &lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;PMEvo: Portable Inference of Port Mappings for Out-of-Order Processors by Evolutionary Optimization 
  &lt;ul&gt; 
   &lt;li&gt;PLDI 2020&lt;/li&gt; 
   &lt;li&gt;Fabian Ritter, Sebastian Hack&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://compilers.cs.uni-saarland.de/papers/ritter_pmevo_pldi20.pdf&quot;&gt;https://compilers.cs.uni-saarland.de/papers/ritter_pmevo_pldi20.pdf&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://compilers.cs.uni-saarland.de/projects/portmap/&quot;&gt;https://compilers.cs.uni-saarland.de/projects/portmap/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/cdl-saarland/pmevo-artifact&quot;&gt;https://github.com/cdl-saarland/pmevo-artifact&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;timing-harness: Harness for profiling arbitrary basic blocks. 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/ithemal/timing-harness&quot;&gt;https://github.com/ithemal/timing-harness&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;uarch-bench: A benchmark for low-level CPU micro-architectural features 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/travisdowns/uarch-bench&quot;&gt;https://github.com/travisdowns/uarch-bench&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h1&gt;Optimization&lt;/h1&gt; 
&lt;ul&gt; 
 &lt;li&gt;BOLT: Binary Optimization and Layout Tool 
  &lt;ul&gt; 
   &lt;li&gt;A linux command-line utility used for optimizing performance of binaries&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/facebookincubator/BOLT&quot;&gt;https://github.com/facebookincubator/BOLT&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Accelerate large-scale applications with BOLT 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://code.fb.com/data-infrastructure/accelerate-large-scale-applications-with-bolt/&quot;&gt;https://code.fb.com/data-infrastructure/accelerate-large-scale-applications-with-bolt/&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;Building Binary Optimizer with LLVM 
    &lt;ul&gt; 
     &lt;li&gt;2016 EuroLLVM Developers&apos; Meeting; Maksim Panchenko&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://llvm.org/devmtg/2016-03/Presentations/BOLT_EuroLLVM_2016.pdf&quot;&gt;https://llvm.org/devmtg/2016-03/Presentations/BOLT_EuroLLVM_2016.pdf&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=gw3iDO3By5Y&quot;&gt;https://www.youtube.com/watch?v=gw3iDO3By5Y&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;BOLT: A Practical Binary Optimizer for Data Centers and Beyond 
    &lt;ul&gt; 
     &lt;li&gt;Maksim Panchenko, Rafael Auler, Bill Nell, Guilherme Ottoni&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://arxiv.org/abs/1807.06735&quot;&gt;https://arxiv.org/abs/1807.06735&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;MAQAO (Modular Assembly Quality Analyzer and Optimizer) 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;http://www.maqao.org/&quot;&gt;http://www.maqao.org/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://maqao.bordeaux.inria.fr/&quot;&gt;http://maqao.bordeaux.inria.fr/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h1&gt;Profiling&lt;/h1&gt; 
&lt;ul&gt; 
 &lt;li&gt;Agner Fog&apos;s test programs for measuring clock cycles and performance monitoring 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;http://www.agner.org/optimize/#testp&quot;&gt;http://www.agner.org/optimize/#testp&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;BCC - Tools for BPF-based Linux IO analysis, networking, monitoring, and more 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://iovisor.github.io/bcc/&quot;&gt;https://iovisor.github.io/bcc/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/iovisor/bcc&quot;&gt;https://github.com/iovisor/bcc&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/iovisor/bpf-docs&quot;&gt;https://github.com/iovisor/bpf-docs&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://www.brendangregg.com/blog/2016-03-05/linux-bpf-superpowers.html&quot;&gt;http://www.brendangregg.com/blog/2016-03-05/linux-bpf-superpowers.html&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://www.brendangregg.com/blog/2016-03-28/linux-bpf-bcc-road-ahead-2016.html&quot;&gt;http://www.brendangregg.com/blog/2016-03-28/linux-bpf-bcc-road-ahead-2016.html&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://www.brendangregg.com/blog/2016-06-14/ubuntu-xenial-bcc-bpf.html&quot;&gt;http://www.brendangregg.com/blog/2016-06-14/ubuntu-xenial-bcc-bpf.html&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://qmonnet.github.io/whirl-offload/2016/09/01/dive-into-bpf/&quot;&gt;https://qmonnet.github.io/whirl-offload/2016/09/01/dive-into-bpf/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Caliper: A Performance Analysis Toolbox in a Library 
  &lt;ul&gt; 
   &lt;li&gt;an instrumentation and performance profiling library&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/LLNL/Caliper&quot;&gt;https://github.com/LLNL/Caliper&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Coz: Finding Code that Counts with Causal Profiling 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/plasma-umass/coz/&quot;&gt;https://github.com/plasma-umass/coz/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Charlie Curtsinger, Emery Berger&lt;/li&gt; 
   &lt;li&gt;SOSP 2015 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://www.sigops.org/sosp/sosp15/current/2015-Monterey/printable/090-curtsinger.pdf&quot;&gt;https://www.sigops.org/sosp/sosp15/current/2015-Monterey/printable/090-curtsinger.pdf&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;;login: 41(2) (2016) 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://www.usenix.org/publications/login/summer2016/curtsinger&quot;&gt;https://www.usenix.org/publications/login/summer2016/curtsinger&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;Performance Matters - Strange Loop 2019; Emery Berger 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=r-TLSBdHe1A&quot;&gt;https://www.youtube.com/watch?v=r-TLSBdHe1A&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;Coz vs. Sampling Profilers 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://easyperf.net/blog/2020/02/26/coz-vs-sampling-profilers&quot;&gt;https://easyperf.net/blog/2020/02/26/coz-vs-sampling-profilers&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;easy_profiler: Lightweight cross-platform profiler library for C++ 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/yse/easy_profiler&quot;&gt;https://github.com/yse/easy_profiler&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Event Tracing for Windows (ETW) / Windows Performance Toolkit – Xperf 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://blogs.msdn.microsoft.com/ntdebugging/2008/04/03/windows-performance-toolkit-xperf/&quot;&gt;https://blogs.msdn.microsoft.com/ntdebugging/2008/04/03/windows-performance-toolkit-xperf/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;ETW Central: &lt;a href=&quot;https://randomascii.wordpress.com/2015/09/24/etw-central/&quot;&gt;https://randomascii.wordpress.com/2015/09/24/etw-central/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;gperftools (originally Google Performance Tools) 
  &lt;ul&gt; 
   &lt;li&gt;&quot;The fastest malloc we’ve seen; works particularly well with threads and STL. Also: thread-friendly heap-checker, heap-profiler, and cpu-profiler.&quot;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/gperftools/gperftools&quot;&gt;https://github.com/gperftools/gperftools&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;gprof2dot 
  &lt;ul&gt; 
   &lt;li&gt;&quot;Python script to convert the output from many profilers into a dot graph.&quot;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/jrfonseca/gprof2dot&quot;&gt;https://github.com/jrfonseca/gprof2dot&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;HawkTracer 
  &lt;ul&gt; 
   &lt;li&gt;a highly portable, low-overhead, configurable profiling tool for getting performance metrics from low-end devices&lt;/li&gt; 
   &lt;li&gt;Linux, Windows, macOS; C &amp;amp; C++ library; Python &amp;amp; Rust wrappers&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.hawktracer.org/&quot;&gt;https://www.hawktracer.org/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/amzn/hawktracer&quot;&gt;https://github.com/amzn/hawktracer&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Low-end platform profiling with HawkTracer profiler 
    &lt;ul&gt; 
     &lt;li&gt;FOSDEM 2020; Marcin Kolny&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://fosdem.org/2020/schedule/event/debugging_hawktrace/&quot;&gt;https://fosdem.org/2020/schedule/event/debugging_hawktrace/&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Hotspot - the Linux perf GUI for performance analysis 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.kdab.com/hotspot-gui-linux-perf-profiler/&quot;&gt;https://www.kdab.com/hotspot-gui-linux-perf-profiler/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/KDAB/hotspot&quot;&gt;https://github.com/KDAB/hotspot&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.kdab.com/hotspot-video/&quot;&gt;https://www.kdab.com/hotspot-video/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Likwid: Performance monitoring and benchmarking suite 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/RRZE-HPC/likwid&quot;&gt;https://github.com/RRZE-HPC/likwid&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/RRZE-HPC/likwid/wiki&quot;&gt;https://github.com/RRZE-HPC/likwid/wiki&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/RRZE-HPC/likwid/wiki/TutorialStart&quot;&gt;https://github.com/RRZE-HPC/likwid/wiki/TutorialStart&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/RRZE-HPC/likwid/wiki/likwid-perfctr&quot;&gt;https://github.com/RRZE-HPC/likwid/wiki/likwid-perfctr&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/RRZE-HPC/likwid/wiki/TutorialMarkerC&quot;&gt;https://github.com/RRZE-HPC/likwid/wiki/TutorialMarkerC&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/RRZE-HPC/likwid/wiki/PatternsHaswellEP&quot;&gt;https://github.com/RRZE-HPC/likwid/wiki/PatternsHaswellEP&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;microprofile: an embeddable profiler 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/jonasmr/microprofile&quot;&gt;https://github.com/jonasmr/microprofile&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Optick: C++ Profiler For Games 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/bombomby/optick&quot;&gt;https://github.com/bombomby/optick&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://optick.dev/&quot;&gt;https://optick.dev/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;perf 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://perf.wiki.kernel.org/&quot;&gt;https://perf.wiki.kernel.org/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://www.brendangregg.com/perf.html&quot;&gt;http://www.brendangregg.com/perf.html&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/torvalds/linux/tree/master/tools/perf/Documentation&quot;&gt;https://github.com/torvalds/linux/tree/master/tools/perf/Documentation&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://suchakra.wordpress.com/2016/06/17/deconstructing-perfs-data-file/&quot;&gt;https://suchakra.wordpress.com/2016/06/17/deconstructing-perfs-data-file/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://www.brendangregg.com/linuxperf.html&quot;&gt;http://www.brendangregg.com/linuxperf.html&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;perf-tools - &lt;a href=&quot;https://github.com/brendangregg/perf-tools&quot;&gt;https://github.com/brendangregg/perf-tools&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;perf_events: The Unofficial Linux Perf Events Web-Page 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;http://web.eece.maine.edu/~vweaver/projects/perf_events/&quot;&gt;http://web.eece.maine.edu/~vweaver/projects/perf_events/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;perfmon2 - &lt;a href=&quot;http://perfmon2.sourceforge.net/&quot;&gt;http://perfmon2.sourceforge.net/&lt;/a&gt; 
  &lt;ul&gt; 
   &lt;li&gt;&quot;Perfmon2 aims to be a portable interface across all modern processors. It is designed to give full access to a given PMU and all the corresponding hardware performance counters. Typically the PMU hardware implementations use a different number of registers, counters with different length and possibly other unique features, a complexity that the software has to cope with. Although processors have different PMU implementations, they usually use configurations registers and data registers. Perfmon2 provides a uniform abstract model of these registers and exports read/write operations accordingly.&quot;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Performance Application Programming Interface (PAPI) 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;http://icl.cs.utk.edu/papi/&quot;&gt;http://icl.cs.utk.edu/papi/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://icl.cs.utk.edu/projects/papi/wiki/Main_Page&quot;&gt;http://icl.cs.utk.edu/projects/papi/wiki/Main_Page&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://www.drdobbs.com/tools/performance-monitoring-with-papi/184406109&quot;&gt;http://www.drdobbs.com/tools/performance-monitoring-with-papi/184406109&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;papi-wrapper (C++ library) - &lt;a href=&quot;https://github.com/sean-chester/papi-wrapper&quot;&gt;https://github.com/sean-chester/papi-wrapper&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;libpapipp: A C++ wrapper around libpapi - &lt;a href=&quot;https://github.com/david-grs/papipp&quot;&gt;https://github.com/david-grs/papipp&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;pmu tools: Intel PMU profiling tools 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/andikleen/pmu-tools&quot;&gt;https://github.com/andikleen/pmu-tools&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/andikleen/pmu-tools/wiki/toplev-manual&quot;&gt;https://github.com/andikleen/pmu-tools/wiki/toplev-manual&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;pmu-tools part I - introduction, ocperf - &lt;a href=&quot;http://halobates.de/blog/p/245&quot;&gt;http://halobates.de/blog/p/245&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;pmu-tools part II - toplev - &lt;a href=&quot;http://halobates.de/blog/p/262&quot;&gt;http://halobates.de/blog/p/262&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Processor Counter Monitor (PCM) 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/opcm/pcm&quot;&gt;https://github.com/opcm/pcm&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Intel Performance Counter Monitor (PCM) - &lt;a href=&quot;http://www.intel.com/software/pcm&quot;&gt;http://www.intel.com/software/pcm&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Remotery: Single C file, Realtime CPU/GPU Profiler with Remote Web Viewer 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/Celtoys/Remotery&quot;&gt;https://github.com/Celtoys/Remotery&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;sysdig 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/draios/sysdig&quot;&gt;https://github.com/draios/sysdig&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://sysdig.com/blog/50-shades-of-system-calls/&quot;&gt;https://sysdig.com/blog/50-shades-of-system-calls/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Tracy Profiler 
  &lt;ul&gt; 
   &lt;li&gt;Tracy is a real time, nanosecond resolution frame profiler that can be used for remote or embedded telemetry of your application. It can profile CPU (C++, Lua), GPU (OpenGL, Vulkan) and memory. It also can display locks held by threads and their interactions with each other.&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://bitbucket.org/wolfpld/tracy&quot;&gt;https://bitbucket.org/wolfpld/tracy&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Introduction to the Tracy profiler - &lt;a href=&quot;https://www.youtube.com/watch?v=fB5B46lbapc&quot;&gt;https://www.youtube.com/watch?v=fB5B46lbapc&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h1&gt;Timing&lt;/h1&gt; 
&lt;ul&gt; 
 &lt;li&gt;low-overhead-timers: Very low-overhead timer/counter interfaces for C on Intel 64 processors 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/jdmccalpin/low-overhead-timers&quot;&gt;https://github.com/jdmccalpin/low-overhead-timers&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Comments on timing short code sections on Intel processors 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;http://sites.utexas.edu/jdm4372/2018/07/23/comments-on-timing-short-code-sections-on-intel-processors/&quot;&gt;http://sites.utexas.edu/jdm4372/2018/07/23/comments-on-timing-short-code-sections-on-intel-processors/&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h1&gt;Visualization&lt;/h1&gt; 
&lt;ul&gt; 
 &lt;li&gt;Flame Graphs 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;http://www.brendangregg.com/flamegraphs.html&quot;&gt;http://www.brendangregg.com/flamegraphs.html&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://queue.acm.org/detail.cfm?id=2927301&quot;&gt;http://queue.acm.org/detail.cfm?id=2927301&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Memory Leak (and Growth) Flame Graphs 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;http://www.brendangregg.com/FlameGraphs/memoryflamegraphs.html&quot;&gt;http://www.brendangregg.com/FlameGraphs/memoryflamegraphs.html&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;FlameScope: a visualization tool for exploring different time ranges as Flame Graphs 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/Netflix/flamescope&quot;&gt;https://github.com/Netflix/flamescope&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Netflix FlameScope - &lt;a href=&quot;https://medium.com/@NetflixTechBlog/netflix-flamescope-a57ca19d47bb&quot;&gt;https://medium.com/@NetflixTechBlog/netflix-flamescope-a57ca19d47bb&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;pprof - a tool for visualization and analysis of profiling data 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/google/pprof&quot;&gt;https://github.com/google/pprof&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Pipedream</title>
      <link>https://tedneward.github.io/Research/tools/pipedream/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/pipedream/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://pipedream.com/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/PipedreamHQ/pipedream&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Obsidian</title>
      <link>https://tedneward.github.io/Research/tools/obsidian/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/obsidian/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://obsidian.md/&quot;&gt;Website&lt;/a&gt; | Commercial | &lt;a href=&quot;https://github.com/obsidianmd&quot;&gt;Releases&lt;/a&gt;&lt;/p&gt; 
&lt;h2&gt;Resources&lt;/h2&gt; 
&lt;h3&gt;Articles, Blogs, Essays&lt;/h3&gt; 
&lt;h3&gt;Source/Repositories&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/guyroyse/openclaw-obsidian-desktop&quot;&gt;Docker setup for running OpenClaw and Obsidian together in a browser-accessible virtual desktop, with an OpenClaw skill for interacting with your vault via the Obsidian CLI.&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>OneCommander</title>
      <link>https://tedneward.github.io/Research/tools/onecommander/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/onecommander/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.onecommander.com/&quot;&gt;Website&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>OpenNotebook</title>
      <link>https://tedneward.github.io/Research/tools/opennotebook/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/opennotebook/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.open-notebook.ai/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/lfnovo/open-notebook&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;To run:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;docker run -d \
  --name open-notebook \
  -p 8502:8502 -p 5055:5055 \
  -v ./notebook_data:/app/data \
  -v ./surreal_data:/mydata \
  -e OPENAI_API_KEY=your_key \
  lfnovo/open_notebook:v1-latest-single
&lt;/code&gt;&lt;/pre&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;code&gt;-d&lt;/code&gt; runs the container in detached mode&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;--name open-notebook&lt;/code&gt; names the container for easy reference&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;-p 8502:8502 -p 5055:5055&lt;/code&gt; maps ports for the web interface and API access&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;-v ./notebook_data:/app/data&lt;/code&gt; and &lt;code&gt;-v ./surreal_data:/mydata&lt;/code&gt; mount local folders to persist notes and database files. This ensures that your data is stored on your machine and remains intact even if the container is restarted&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;-e OPENAI_API_KEY=your_key&lt;/code&gt; allows integration with OpenAI models if desired&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;lfnovo/open_notebook:v1-latest-single&lt;/code&gt; specifies the container image&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;After running the container, navigate to:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Main Interface: &lt;a href=&quot;http://localhost:8502&quot;&gt;http://localhost:8502&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;API Access: &lt;a href=&quot;http://localhost:5055&quot;&gt;http://localhost:5055&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;API Documentation: &lt;a href=&quot;http://localhost:5055/docs&quot;&gt;http://localhost:5055/docs&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;After deployment, two folders appear in the local directory:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;notebook_data: Stores all notes, summaries, and AI-processed content&lt;/li&gt; 
 &lt;li&gt;surreal_data: Contains underlying database files for Open Notebook&apos;s internal storage&lt;/li&gt; 
&lt;/ul&gt; 
&lt;hr&gt; 
&lt;pre&gt;&lt;code&gt;docker run -d \
  --name open-notebook \
  -p 8502:8502 -p 5055:5055 \
  -v ./notebook_data:/app/data \
  -v ./surreal_data:/mydata \
  lfnovo/open_notebook:v1-latest-single
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Docker compose&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;services:
  surrealdb:
    image: surrealdb/surrealdb:v2
    command: start --user root --pass password --bind 0.0.0.0:8000 rocksdb:/mydata/mydatabase.db
    ports:
      - &quot;8000:8000&quot;
    volumes:
      - ./surreal_data:/mydata

  open_notebook:
    image: lfnovo/open_notebook:v1-latest-single
    pull_policy: always
    ports:
      - &quot;8502:8502&quot;  # Web UI (React frontend)
      - &quot;5055:5055&quot;  # API (required!)
    environment:
      # NO API KEYS NEEDED - Using Ollama (free, local)
      - OLLAMA_API_BASE=http://ollama:11434

      # Database (required)
      - SURREAL_URL=ws://surrealdb:8000/rpc
      - SURREAL_USER=root
      - SURREAL_PASSWORD=password
      - SURREAL_NAMESPACE=open_notebook
      - SURREAL_DATABASE=open_notebook
    volumes:
      - ./notebook_data:/app/data
      - ./surreal_data:/mydata
    depends_on:
      - surrealdb
    restart: always

  ollama:
    image: ollama/ollama:latest
    ports:
      - &quot;11434:11434&quot;
    volumes:
      - ./ollama_models:/root/.ollama
    environment:
      # Optional: set GPU support if available
      - OLLAMA_NUM_GPU=0
    restart: always
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;NOTE: If you want to run Ollama locally (to more easily use GPUs, I think), make sure &lt;code&gt;OLLAMA_API_BASE=http://host.docker.internal:11434&lt;/code&gt;&lt;/p&gt; 
&lt;h2&gt;Reading&lt;/h2&gt; 
&lt;h3&gt;Articles&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://dev.to/theairabbit/testing-open-notebook-a-complete-walkthrough-with-gemini-ai-4ggj&quot;&gt;https://dev.to/theairabbit/testing-open-notebook-a-complete-walkthrough-with-gemini-ai-4ggj&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>OpenWebUI</title>
      <link>https://tedneward.github.io/Research/tools/openwebui/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/openwebui/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://openwebui.com/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/open-webui/open-webui&quot;&gt;Source&lt;/a&gt; | &lt;a href=&quot;https://docs.openwebui.com/features&quot;&gt;Docs&lt;/a&gt;&lt;/p&gt; 
&lt;h2&gt;Key Features of Open WebUI ⭐&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt; &lt;p&gt;Install using Docker or Kubernetes (kubectl, kustomize or helm) with support for both &lt;code&gt;:ollama&lt;/code&gt; and &lt;code&gt;:cuda&lt;/code&gt; tagged images.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Ollama/OpenAI API Integration: Integrate OpenAI-compatible APIs for conversations alongside Ollama models. Customize the OpenAI API URL to link with LMStudio, GroqCloud, Mistral, OpenRouter, and more.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Granular Permissions and User Groups: By allowing administrators to create detailed user roles and permissions, we ensure a secure user environment. This granularity not only enhances security but also allows for customized user experiences, fostering a sense of ownership and responsibility amongst users.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Responsive Design: Enjoy a seamless experience across Desktop PC, Laptop, and Mobile devices.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Progressive Web App (PWA) for Mobile: Enjoy a native app-like experience on your mobile device with our PWA, providing offline access on localhost and a seamless user interface.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Full Markdown and LaTeX Support: Elevate your LLM experience with comprehensive Markdown and LaTeX capabilities for enriched interaction.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Hands-Free Voice/Video Call: Experience seamless communication with integrated hands-free voice and video call features using multiple Speech-to-Text providers (Local Whisper, OpenAI, Deepgram, Azure) and Text-to-Speech engines (Azure, ElevenLabs, OpenAI, Transformers, WebAPI), allowing for dynamic and interactive chat environments.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Model Builder: Easily create Ollama models via the Web UI. Create and add custom characters/agents, customize chat elements, and import models effortlessly through &lt;a href=&quot;https://openwebui.com/&quot;&gt;Open WebUI Community&lt;/a&gt; integration.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Native Python Function Calling Tool: Enhance your LLMs with built-in code editor support in the tools workspace. Bring Your Own Function (BYOF) by simply adding your pure Python functions, enabling seamless integration with LLMs.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Persistent Artifact Storage: Built-in key-value storage API for artifacts, enabling features like journals, trackers, leaderboards, and collaborative tools with both personal and shared data scopes across sessions.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Local RAG Integration: Dive into the future of chat interactions with groundbreaking Retrieval Augmented Generation (RAG) support using your choice of 9 vector databases and multiple content extraction engines (Tika, Docling, Document Intelligence, Mistral OCR, External loaders). Load documents directly into chat or add files to your document library, effortlessly accessing them using the &lt;code&gt;#&lt;/code&gt; command before a query.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Web Search for RAG: Perform web searches using 15+ providers including &lt;code&gt;SearXNG&lt;/code&gt;, &lt;code&gt;Google PSE&lt;/code&gt;, &lt;code&gt;Brave Search&lt;/code&gt;, &lt;code&gt;Kagi&lt;/code&gt;, &lt;code&gt;Mojeek&lt;/code&gt;, &lt;code&gt;Tavily&lt;/code&gt;, &lt;code&gt;Perplexity&lt;/code&gt;, &lt;code&gt;serpstack&lt;/code&gt;, &lt;code&gt;serper&lt;/code&gt;, &lt;code&gt;Serply&lt;/code&gt;, &lt;code&gt;DuckDuckGo&lt;/code&gt;, &lt;code&gt;SearchApi&lt;/code&gt;, &lt;code&gt;SerpApi&lt;/code&gt;, &lt;code&gt;Bing&lt;/code&gt;, &lt;code&gt;Jina&lt;/code&gt;, &lt;code&gt;Exa&lt;/code&gt;, &lt;code&gt;Sougou&lt;/code&gt;, &lt;code&gt;Azure AI Search&lt;/code&gt;, and &lt;code&gt;Ollama Cloud&lt;/code&gt;, injecting results directly into your chat experience.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Web Browsing Capability: Seamlessly integrate websites into your chat experience using the &lt;code&gt;#&lt;/code&gt; command followed by a URL. This feature allows you to incorporate web content directly into your conversations, enhancing the richness and depth of your interactions.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Image Generation &amp;amp; Editing Integration: Create and edit images using multiple engines including OpenAI&apos;s DALL-E, Gemini, ComfyUI (local), and AUTOMATIC1111 (local), with support for both generation and prompt-based editing workflows.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Many Models Conversations: Effortlessly engage with various models simultaneously, harnessing their unique strengths for optimal responses. Enhance your experience by leveraging a diverse set of models in parallel.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Role-Based Access Control (RBAC): Ensure secure access with restricted permissions; only authorized individuals can access your Ollama, and exclusive model creation/pulling rights are reserved for administrators.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Flexible Database &amp;amp; Storage Options: Choose from SQLite (with optional encryption), PostgreSQL, or configure cloud storage backends (S3, Google Cloud Storage, Azure Blob Storage) for scalable deployments.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Advanced Vector Database Support: Select from 9 vector database options including ChromaDB, PGVector, Qdrant, Milvus, Elasticsearch, OpenSearch, Pinecone, S3Vector, and Oracle 23ai for optimal RAG performance.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Enterprise Authentication: Full support for LDAP/Active Directory integration, SCIM 2.0 automated provisioning, and SSO via trusted headers alongside OAuth providers. Enterprise-grade user and group provisioning through SCIM 2.0 protocol, enabling seamless integration with identity providers like Okta, Azure AD, and Google Workspace for automated user lifecycle management.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Cloud-Native Integration: Native support for Google Drive and OneDrive/SharePoint file picking, enabling seamless document import from enterprise cloud storage.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Production Observability: Built-in OpenTelemetry support for traces, metrics, and logs, enabling comprehensive monitoring with your existing observability stack.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Horizontal Scalability: Redis-backed session management and WebSocket support for multi-worker and multi-node deployments behind load balancers.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Multilingual Support: Experience Open WebUI in your preferred language with our internationalization (i18n) support. Join us in expanding our supported languages! We&apos;re actively seeking contributors!&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Pipelines, Open WebUI Plugin Support: Seamlessly integrate custom logic and Python libraries into Open WebUI using &lt;a href=&quot;https://github.com/open-webui/pipelines&quot;&gt;Pipelines Plugin Framework&lt;/a&gt;. Launch your Pipelines instance, set the OpenAI URL to the Pipelines URL, and explore endless possibilities. &lt;a href=&quot;https://github.com/open-webui/pipelines/tree/main/examples&quot;&gt;Examples&lt;/a&gt; include &lt;strong&gt;Function Calling&lt;/strong&gt;, User &lt;strong&gt;Rate Limiting&lt;/strong&gt; to control access, &lt;strong&gt;Usage Monitoring&lt;/strong&gt; with tools like Langfuse, &lt;strong&gt;Live Translation with LibreTranslate&lt;/strong&gt; for multilingual support, &lt;strong&gt;Toxic Message Filtering&lt;/strong&gt; and much more.&lt;/p&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Getting Started&lt;/h2&gt; 
&lt;h3&gt;Installation via Python pip&lt;/h3&gt; 
&lt;p&gt;Open WebUI can be installed using using &lt;strong&gt;Python 3.11&lt;/strong&gt;.&lt;/p&gt; 
&lt;ol&gt; 
 &lt;li&gt;&lt;strong&gt;Install Open WebUI&lt;/strong&gt;:&lt;br&gt; Open your terminal and run the following command to install Open WebUI:&lt;/li&gt; 
&lt;/ol&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;pip install open-webui
&lt;/code&gt;&lt;/pre&gt; 
&lt;ol&gt; 
 &lt;li&gt;&lt;strong&gt;Running Open WebUI&lt;/strong&gt;:&lt;br&gt; After installation, you can start Open WebUI by executing:&lt;/li&gt; 
&lt;/ol&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;open-webui serve
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;This will start the Open WebUI server, which you can access at &lt;a href=&quot;http://localhost:8080&quot;&gt;http://localhost:8080&lt;/a&gt;&lt;/p&gt; 
&lt;h3&gt;Quick Start with Docker&lt;/h3&gt; 
&lt;p&gt;Please note that for certain Docker environments, additional configurations might be needed.&lt;/p&gt; 
&lt;p&gt;When using Docker to install Open WebUI, make sure to include the &lt;code&gt;-v open-webui:/app/backend/data&lt;/code&gt; in your Docker command. This step is crucial as it ensures your database is properly mounted and prevents any loss of data.&lt;/p&gt; 
&lt;p&gt;If you wish to utilize Open WebUI with Ollama included or CUDA acceleration, we recommend utilizing our official images tagged with either &lt;code&gt;:cuda&lt;/code&gt; or &lt;code&gt;:ollama&lt;/code&gt;. To enable CUDA, you must install the &lt;a href=&quot;https://docs.nvidia.com/dgx/nvidia-container-runtime-upgrade/&quot;&gt;Nvidia CUDA container toolkit&lt;/a&gt; on your Linux/WSL system.&lt;/p&gt; 
&lt;h3&gt;Installation with Default Configuration&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;strong&gt;If Ollama is on your computer&lt;/strong&gt;, use this command:&lt;/li&gt; 
&lt;/ul&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;docker run -d -p 3000:8080 --add-host=host.docker.internal:host-gateway -v open-webui:/app/backend/data --name open-webui --restart always ghcr.io/open-webui/open-webui:main
&lt;/code&gt;&lt;/pre&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;strong&gt;If Ollama is on a Different Server&lt;/strong&gt;, use this command:&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;To connect to Ollama on another server, change the &lt;code&gt;OLLAMA_BASE_URL&lt;/code&gt; to the server&apos;s URL:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;docker run -d -p 3000:8080 -e OLLAMA_BASE_URL=https://example.com -v open-webui:/app/backend/data --name open-webui --restart always ghcr.io/open-webui/open-webui:main
&lt;/code&gt;&lt;/pre&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;strong&gt;To run Open WebUI with Nvidia GPU support&lt;/strong&gt;, use this command:&lt;/li&gt; 
&lt;/ul&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;docker run -d -p 3000:8080 --gpus all --add-host=host.docker.internal:host-gateway -v open-webui:/app/backend/data --name open-webui --restart always ghcr.io/open-webui/open-webui:cuda
&lt;/code&gt;&lt;/pre&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;strong&gt;After experimentation&lt;/strong&gt;, I ended up with:&lt;/li&gt; 
&lt;/ul&gt; 
&lt;pre&gt;&lt;code&gt;docker run -d -p 3000:8080 --name=openweb-ui --restart=always --env=DOCKER=true --env=OLLAMA_BASE_URL=http://host.docker.internal:11434 --env=WEBUI_AUTH=False --env=WEBUI_SECRET_KEY= --volume=./open-webui:/app/backend/data --workdir=/app/backend ghcr.io/open-webui/open-webui:main
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Research:&lt;br&gt; * What does &quot;--add-host&quot; do in Docker?&lt;/p&gt; 
&lt;h3&gt;Installation for OpenAI API Usage Only&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;strong&gt;If you&apos;re only using OpenAI API&lt;/strong&gt;, use this command:&lt;/li&gt; 
&lt;/ul&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;docker run -d -p 3000:8080 -e OPENAI_API_KEY=your_secret_key -v open-webui:/app/backend/data --name open-webui --restart always ghcr.io/open-webui/open-webui:main
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;Installing Open WebUI with Bundled Ollama Support&lt;/h3&gt; 
&lt;p&gt;This installation method uses a single container image that bundles Open WebUI with Ollama, allowing for a streamlined setup via a single command. Choose the appropriate command based on your hardware setup:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;strong&gt;With GPU Support&lt;/strong&gt;:&lt;br&gt; Utilize GPU resources by running the following command:&lt;/li&gt; 
&lt;/ul&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;docker run -d -p 3000:8080 --gpus=all -v ollama:/root/.ollama -v open-webui:/app/backend/data --name open-webui --restart always ghcr.io/open-webui/open-webui:ollama
&lt;/code&gt;&lt;/pre&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;strong&gt;For CPU Only&lt;/strong&gt;:&lt;br&gt; If you&apos;re not using a GPU, use this command instead:&lt;/li&gt; 
&lt;/ul&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;docker run -d -p 3000:8080 -v ollama:/root/.ollama -v open-webui:/app/backend/data --name open-webui --restart always ghcr.io/open-webui/open-webui:ollama
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Both commands facilitate a built-in, hassle-free installation of both Open WebUI and Ollama, ensuring that you can get everything up and running swiftly.&lt;/p&gt; 
&lt;p&gt;After installation, you can access Open WebUI at &lt;a href=&quot;http://localhost:3000&quot;&gt;http://localhost:3000&lt;/a&gt;.&lt;/p&gt; 
&lt;p&gt;Look at the &lt;a href=&quot;https://docs.openwebui.com/getting-started/advanced-topics/development&quot;&gt;Local Development Guide&lt;/a&gt; for instructions on setting up a local development environment.&lt;/p&gt; 
&lt;h3&gt;Troubleshooting&lt;/h3&gt; 
&lt;h4&gt;Open WebUI: Server Connection Error&lt;/h4&gt; 
&lt;p&gt;If you&apos;re experiencing connection issues, it’s often due to the WebUI docker container not being able to reach the Ollama server at 127.0.0.1:11434 (host.docker.internal:11434) inside the container . Use the &lt;code&gt;--network=host&lt;/code&gt; flag in your docker command to resolve this. Note that the port changes from 3000 to 8080, resulting in the link: &lt;code&gt;http://localhost:8080&lt;/code&gt;.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Example Docker Command&lt;/strong&gt;:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;docker run -d --network=host -v open-webui:/app/backend/data -e OLLAMA_BASE_URL=http://127.0.0.1:11434 --name open-webui --restart always ghcr.io/open-webui/open-webui:main
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;Keeping Your Docker Installation Up-to-Date&lt;/h3&gt; 
&lt;p&gt;In case you want to update your local Docker installation to the latest version, you can do it with &lt;a href=&quot;https://containrrr.dev/watchtower/&quot;&gt;Watchtower&lt;/a&gt;:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;docker run --rm --volume /var/run/docker.sock:/var/run/docker.sock containrrr/watchtower --run-once open-webui
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;In the last part of the command, replace &lt;code&gt;open-webui&lt;/code&gt; with your container name if it is different.&lt;/p&gt; 
&lt;p&gt;Check our Updating Guide available in our &lt;a href=&quot;https://docs.openwebui.com/getting-started/updating&quot;&gt;Open WebUI Documentation&lt;/a&gt;.&lt;/p&gt; 
&lt;h3&gt;Offline Mode&lt;/h3&gt; 
&lt;p&gt;If you are running Open WebUI in an offline environment, you can set the &lt;code&gt;HF_HUB_OFFLINE&lt;/code&gt; environment variable to &lt;code&gt;1&lt;/code&gt; to prevent attempts to download models from the internet.&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;export HF_HUB_OFFLINE=1
&lt;/code&gt;&lt;/pre&gt; 
&lt;hr&gt; 
&lt;p&gt;Docker-compose setup&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;version: &apos;3.8&apos;

services:
ollama:
    image: ollama/ollama
    container_name: ollama
    volumes:
    - ollama:/root/.ollama
    ports:
    - &quot;11434:11434&quot;
    restart: unless-stopped

openwebui:
    image: ghcr.io/open-webui/open-webui:main
    container_name: openwebui
    depends_on:
    - ollama
    environment:
    - OLLAMA_BASE_URL=http://ollama:11434
    ports:
    - &quot;3000:3000&quot;
    volumes:
    - openwebui:/app/backend/data
    restart: unless-stopped

volumes:
ollama:
openwebui:
&lt;/code&gt;&lt;/pre&gt;
	</description>
    </item>
    <item>
      <title>PATAT</title>
      <link>https://tedneward.github.io/Research/tools/patat/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/patat/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/jaspervdj/patat&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Available via Homebrew (&lt;code&gt;brew install patat&lt;/code&gt;).&lt;/p&gt; 
&lt;p&gt;patat (Presentations Atop The ANSI Terminal) is a feature-rich presentation tool that runs in the terminal.&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Understands most markdown extensions and many other input formats (rST, Org-mode...) by building on top of Pandoc.&lt;/li&gt; 
 &lt;li&gt;Evaluate code snippets and show the result.&lt;/li&gt; 
 &lt;li&gt;Syntax highlighting for nearly one hundred languages generated from Kate syntax files.&lt;/li&gt; 
 &lt;li&gt;Automatically reload your slides as you edit them.&lt;/li&gt; 
 &lt;li&gt;Display speaker notes in a second window or monitor.&lt;/li&gt; 
 &lt;li&gt;Incremental slide display.&lt;/li&gt; 
 &lt;li&gt;Experimental images support.&lt;/li&gt; 
 &lt;li&gt;Transition effects.&lt;/li&gt; 
 &lt;li&gt;Supports smart slide splitting.&lt;/li&gt; 
 &lt;li&gt;Auto advancing with configurable delay.&lt;/li&gt; 
 &lt;li&gt;Centering and re-wrapping text to terminal width with proper indentation.&lt;/li&gt; 
 &lt;li&gt;Theming support including 24-bit RGB.&lt;/li&gt; 
 &lt;li&gt;Highly portable as it only requires an ANSI terminal as opposed to something like ncurses.&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>PeggyJS</title>
      <link>https://tedneward.github.io/Research/tools/peggyjs/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/peggyjs/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://peggyjs.org/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/pegjs/pegjs&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>pgit</title>
      <link>https://tedneward.github.io/Research/tools/pgit/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/pgit/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://git.erock.io/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/picosh/pgit&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;This golang binary will generate a commit log, files, and references based on a git repository and the provided revisions.&lt;/p&gt; 
&lt;p&gt;It will only generate a commit log and files for the provided revisions.&lt;/p&gt; 
&lt;h2&gt;Getting Started&lt;/h2&gt; 
&lt;pre&gt;&lt;code&gt;git clone git@github.com:picosh/pgit.git
cd pgit
make build
&lt;/code&gt;&lt;/pre&gt; 
&lt;pre&gt;&lt;code&gt;make build
./pgit --revs main --label pico --out ./public
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;To learn more about the options run:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;./pgit --help
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Multiple Repos&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;pgit \
  --out ./public/pico \
  --home-url &quot;https://git.erock.io&quot; \
  --revs main \
  --repo ~/pico \
  --root-relative &quot;/pico/&quot;

pgit \
  --out ./public/starfx \
  --home-url &quot;https://git.erock.io&quot; \
  --revs main \
  --repo ~/starfx \
  --root-relative &quot;/starfx/&quot;

echo &apos;&amp;lt;html&amp;gt;&amp;lt;body&amp;gt;&amp;lt;a href=&quot;/pico&quot;&amp;gt;pico&amp;lt;/a&amp;gt;&amp;lt;a href=&quot;/starfx&quot;&amp;gt;starfx&amp;lt;/a&amp;gt;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;&apos; &amp;gt; ./public/index.html

rsync -rv ./public/ pgs.sh:/git
&lt;/code&gt;&lt;/pre&gt; 
&lt;h2&gt;Reading&lt;/h2&gt; 
&lt;h3&gt;Articles&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.howtogeek.com/this-easy-tool-gives-me-the-best-of-github-on-my-local-machine/&quot;&gt;https://www.howtogeek.com/this-easy-tool-gives-me-the-best-of-github-on-my-local-machine/&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>OfficeCLI</title>
      <link>https://tedneward.github.io/Research/tools/officecli/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/officecli/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.officecli.ai/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/iOfficeAI/OfficeCLI&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Agent-chat installation: &lt;code&gt;curl -fsSL https://officecli.ai/SKILL.md&lt;/code&gt; &quot;Paste this into your AI agent&apos;s chat — it will read the skill file and install everything automatically. The skill file teaches the agent how to install the binary and use all commands.&quot;&lt;/p&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;OfficeCLI ships with a &lt;a href=&quot;https://github.com/iOfficeAI/OfficeCLI/blob/main/SKILL.md&quot;&gt;SKILL.md&lt;/a&gt; (239 lines, ~8K tokens) that covers command syntax, architecture, and common pitfalls. After installation, your agent can immediately create, read, and modify any Office document.&lt;/p&gt; 
&lt;/blockquote&gt; 
&lt;h2&gt;Quick Start&lt;/h2&gt; 
&lt;p&gt;From zero to a finished presentation in seconds:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;# Create a new PowerPoint
officecli create deck.pptx

# Add a slide with a title and background color
officecli add deck.pptx / --type slide --prop title=&quot;Q4 Report&quot; --prop background=1A1A2E

# Add a text shape to the slide
officecli add deck.pptx /slide\[1\] --type shape \\
  --prop text=&quot;Revenue grew 25%&quot; --prop x=2cm --prop y=5cm \\
  --prop font=Arial --prop size=24 --prop color=FFFFFF

# View the outline of the presentation
officecli view deck.pptx outline
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Output:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;Slide 1: Q4 Report
  Shape 1 [TextBox]: Revenue grew 25%
&lt;/code&gt;&lt;/pre&gt; 
&lt;pre&gt;&lt;code&gt;# Get structured JSON for any element
officecli get deck.pptx /slide\[1\]/shape\[1\] --json
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Output:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;{
    &quot;tag&quot;: &quot;shape&quot;,
    &quot;path&quot;: &quot;/slide\[1\]/shape\[1\]&quot;,
    &quot;attributes&quot;: {
        &quot;name&quot;: &quot;TextBox 1&quot;,
        &quot;text&quot;: &quot;Revenue grew 25%&quot;,
        &quot;x&quot;: &quot;720000&quot;,
        &quot;y&quot;: &quot;1800000&quot;
    }
}
&lt;/code&gt;&lt;/pre&gt; 
&lt;h2&gt;Why OfficeCLI?&lt;/h2&gt; 
&lt;p&gt;What used to take 50 lines of Python and 3 separate libraries:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;from pptx import Presentation
from pptx.util import Inches, Pt
prs \= Presentation()
slide \= prs.slides.add\_slide(prs.slide\_layouts\[0\])
title \= slide.shapes.title
title.text \= &quot;Q4 Report&quot;
\# ... 45 more lines ...
prs.save(&apos;deck.pptx&apos;)
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Now takes one command:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;officecli add deck.pptx / --type slide --prop title=&quot;Q4 Report&quot;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;&lt;strong&gt;What OfficeCLI can do:&lt;/strong&gt;&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;strong&gt;Create&lt;/strong&gt; documents from scratch -- blank or with content&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Read&lt;/strong&gt; text, structure, styles, formulas -- in plain text or structured JSON&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Analyze&lt;/strong&gt; formatting issues, style inconsistencies, and structural problems&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Modify&lt;/strong&gt; any element -- text, fonts, colors, layout, formulas, charts, images&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Reorganize&lt;/strong&gt; content -- add, remove, move, copy elements across documents&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;&lt;strong&gt;Word&lt;/strong&gt; — &lt;a href=&quot;https://github.com/iOfficeAI/OfficeCLI/wiki/word-paragraph&quot;&gt;paragraphs&lt;/a&gt;, &lt;a href=&quot;https://github.com/iOfficeAI/OfficeCLI/wiki/word-run&quot;&gt;runs&lt;/a&gt;, &lt;a href=&quot;https://github.com/iOfficeAI/OfficeCLI/wiki/word-table&quot;&gt;tables&lt;/a&gt;, &lt;a href=&quot;https://github.com/iOfficeAI/OfficeCLI/wiki/word-style&quot;&gt;styles&lt;/a&gt;, &lt;a href=&quot;https://github.com/iOfficeAI/OfficeCLI/wiki/word-header-footer&quot;&gt;headers/footers&lt;/a&gt;, &lt;a href=&quot;https://github.com/iOfficeAI/OfficeCLI/wiki/word-picture&quot;&gt;images&lt;/a&gt;, &lt;a href=&quot;https://github.com/iOfficeAI/OfficeCLI/wiki/word-equation&quot;&gt;equations&lt;/a&gt;, &lt;a href=&quot;https://github.com/iOfficeAI/OfficeCLI/wiki/word-comment&quot;&gt;comments&lt;/a&gt;, &lt;a href=&quot;https://github.com/iOfficeAI/OfficeCLI/wiki/word-footnote&quot;&gt;footnotes&lt;/a&gt;, &lt;a href=&quot;https://github.com/iOfficeAI/OfficeCLI/wiki/word-watermark&quot;&gt;watermarks&lt;/a&gt;, &lt;a href=&quot;https://github.com/iOfficeAI/OfficeCLI/wiki/word-bookmark&quot;&gt;bookmarks&lt;/a&gt;, &lt;a href=&quot;https://github.com/iOfficeAI/OfficeCLI/wiki/word-toc&quot;&gt;TOC&lt;/a&gt;, &lt;a href=&quot;https://github.com/iOfficeAI/OfficeCLI/wiki/word-chart&quot;&gt;charts&lt;/a&gt;, &lt;a href=&quot;https://github.com/iOfficeAI/OfficeCLI/wiki/word-hyperlink&quot;&gt;hyperlinks&lt;/a&gt;, &lt;a href=&quot;https://github.com/iOfficeAI/OfficeCLI/wiki/word-section&quot;&gt;sections&lt;/a&gt;, &lt;a href=&quot;https://github.com/iOfficeAI/OfficeCLI/wiki/word-formfield&quot;&gt;form fields&lt;/a&gt;, &lt;a href=&quot;https://github.com/iOfficeAI/OfficeCLI/wiki/word-sdt&quot;&gt;content controls (SDT)&lt;/a&gt;, &lt;a href=&quot;https://github.com/iOfficeAI/OfficeCLI/wiki/word-field&quot;&gt;fields&lt;/a&gt;, &lt;a href=&quot;https://github.com/iOfficeAI/OfficeCLI/wiki/word-document&quot;&gt;document properties&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Excel&lt;/strong&gt; — &lt;a href=&quot;https://github.com/iOfficeAI/OfficeCLI/wiki/excel-cell&quot;&gt;cells&lt;/a&gt;, formulas (150+ built-in functions with auto-evaluation), &lt;a href=&quot;https://github.com/iOfficeAI/OfficeCLI/wiki/excel-sheet&quot;&gt;sheets&lt;/a&gt;, &lt;a href=&quot;https://github.com/iOfficeAI/OfficeCLI/wiki/excel-table&quot;&gt;tables&lt;/a&gt;, &lt;a href=&quot;https://github.com/iOfficeAI/OfficeCLI/wiki/excel-conditionalformatting&quot;&gt;conditional formatting&lt;/a&gt;, &lt;a href=&quot;https://github.com/iOfficeAI/OfficeCLI/wiki/excel-chart&quot;&gt;charts&lt;/a&gt;, &lt;a href=&quot;https://github.com/iOfficeAI/OfficeCLI/wiki/excel-pivottable&quot;&gt;pivot tables&lt;/a&gt;, &lt;a href=&quot;https://github.com/iOfficeAI/OfficeCLI/wiki/excel-namedrange&quot;&gt;named ranges&lt;/a&gt;, &lt;a href=&quot;https://github.com/iOfficeAI/OfficeCLI/wiki/excel-validation&quot;&gt;data validation&lt;/a&gt;, &lt;a href=&quot;https://github.com/iOfficeAI/OfficeCLI/wiki/excel-picture&quot;&gt;images&lt;/a&gt;, &lt;a href=&quot;https://github.com/iOfficeAI/OfficeCLI/wiki/excel-sparkline&quot;&gt;sparklines&lt;/a&gt;, &lt;a href=&quot;https://github.com/iOfficeAI/OfficeCLI/wiki/excel-comment&quot;&gt;comments&lt;/a&gt;, &lt;a href=&quot;https://github.com/iOfficeAI/OfficeCLI/wiki/excel-autofilter&quot;&gt;autofilter&lt;/a&gt;, &lt;a href=&quot;https://github.com/iOfficeAI/OfficeCLI/wiki/excel-shape&quot;&gt;shapes&lt;/a&gt;, CSV/TSV import, &lt;code&gt;$Sheet:A1&lt;/code&gt; cell addressing&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;PowerPoint&lt;/strong&gt; — &lt;a href=&quot;https://github.com/iOfficeAI/OfficeCLI/wiki/ppt-slide&quot;&gt;slides&lt;/a&gt;, &lt;a href=&quot;https://github.com/iOfficeAI/OfficeCLI/wiki/ppt-shape&quot;&gt;shapes&lt;/a&gt;, &lt;a href=&quot;https://github.com/iOfficeAI/OfficeCLI/wiki/ppt-picture&quot;&gt;images&lt;/a&gt;, &lt;a href=&quot;https://github.com/iOfficeAI/OfficeCLI/wiki/ppt-table&quot;&gt;tables&lt;/a&gt;, &lt;a href=&quot;https://github.com/iOfficeAI/OfficeCLI/wiki/ppt-chart&quot;&gt;charts&lt;/a&gt;, &lt;a href=&quot;https://github.com/iOfficeAI/OfficeCLI/wiki/ppt-slide&quot;&gt;animations&lt;/a&gt;, &lt;a href=&quot;https://github.com/iOfficeAI/OfficeCLI/wiki/ppt-morph-check&quot;&gt;morph transitions&lt;/a&gt;, &lt;a href=&quot;https://github.com/iOfficeAI/OfficeCLI/wiki/ppt-3dmodel&quot;&gt;3D models (.glb)&lt;/a&gt;, &lt;a href=&quot;https://github.com/iOfficeAI/OfficeCLI/wiki/ppt-zoom&quot;&gt;slide zoom&lt;/a&gt;, &lt;a href=&quot;https://github.com/iOfficeAI/OfficeCLI/wiki/ppt-equation&quot;&gt;equations&lt;/a&gt;, &lt;a href=&quot;https://github.com/iOfficeAI/OfficeCLI/wiki/ppt-theme&quot;&gt;themes&lt;/a&gt;, &lt;a href=&quot;https://github.com/iOfficeAI/OfficeCLI/wiki/ppt-connector&quot;&gt;connectors&lt;/a&gt;, &lt;a href=&quot;https://github.com/iOfficeAI/OfficeCLI/wiki/ppt-video&quot;&gt;video/audio&lt;/a&gt;, &lt;a href=&quot;https://github.com/iOfficeAI/OfficeCLI/wiki/ppt-group&quot;&gt;groups&lt;/a&gt;, &lt;a href=&quot;https://github.com/iOfficeAI/OfficeCLI/wiki/ppt-notes&quot;&gt;notes&lt;/a&gt;, &lt;a href=&quot;https://github.com/iOfficeAI/OfficeCLI/wiki/ppt-placeholder&quot;&gt;placeholders&lt;/a&gt;&lt;/p&gt; 
&lt;h2&gt;Installation&lt;/h2&gt; 
&lt;p&gt;Ships as a single self-contained binary. The .NET runtime is embedded -- nothing to install, no runtime to manage.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;One-line install:&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;macOS / Linux: &lt;code&gt;curl -fsSL https://raw.githubusercontent.com/iOfficeAI/OfficeCLI/main/install.sh | bash&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;Windows (PowerShell): &lt;code&gt;irm https://raw.githubusercontent.com/iOfficeAI/OfficeCLI/main/install.ps1 | iex&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Or download manually&lt;/strong&gt; from &lt;a href=&quot;https://github.com/iOfficeAI/OfficeCLI/releases&quot;&gt;GitHub Releases&lt;/a&gt;:&lt;/p&gt; 
&lt;table&gt; 
 &lt;thead&gt; 
  &lt;tr&gt;
   &lt;th&gt; Platform &lt;/th&gt;
   &lt;th&gt; Binary &lt;/th&gt;
  &lt;/tr&gt; 
 &lt;/thead&gt; 
 &lt;tbody&gt; 
  &lt;tr&gt;
   &lt;td&gt; macOS Apple Silicon &lt;/td&gt;
   &lt;td&gt; &lt;code&gt;officecli-mac-arm64&lt;/code&gt; &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; macOS Intel &lt;/td&gt;
   &lt;td&gt; &lt;code&gt;officecli-mac-x64&lt;/code&gt; &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; Linux x64 &lt;/td&gt;
   &lt;td&gt; &lt;code&gt;officecli-linux-x64&lt;/code&gt; &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; Linux ARM64 &lt;/td&gt;
   &lt;td&gt; &lt;code&gt;officecli-linux-arm64&lt;/code&gt; &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; Windows x64 &lt;/td&gt;
   &lt;td&gt; &lt;code&gt;officecli-win-x64.exe&lt;/code&gt; &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; Windows ARM64 &lt;/td&gt;
   &lt;td&gt; &lt;code&gt;officecli-win-arm64.exe&lt;/code&gt; &lt;/td&gt;
  &lt;/tr&gt; 
 &lt;/tbody&gt; 
&lt;/table&gt; 
&lt;p&gt;Verify installation: &lt;code&gt;officecli --version&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Or self-install from a downloaded binary:&lt;/strong&gt; &lt;code&gt;officecli install&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;Updates are checked automatically in the background. Disable with &lt;code&gt;officecli config autoUpdate false&lt;/code&gt; or skip per-invocation with &lt;code&gt;OFFICECLI_SKIP_UPDATE=1&lt;/code&gt;. Configuration lives under &lt;code&gt;~/.officecli/config.json&lt;/code&gt;.&lt;/p&gt; 
&lt;h2&gt;Three-Layer Architecture&lt;/h2&gt; 
&lt;p&gt;Start simple, go deep only when needed.&lt;/p&gt; 
&lt;table&gt; 
 &lt;thead&gt; 
  &lt;tr&gt;
   &lt;th&gt; Layer &lt;/th&gt;
   &lt;th&gt; Purpose &lt;/th&gt;
   &lt;th&gt; Commands &lt;/th&gt;
  &lt;/tr&gt; 
 &lt;/thead&gt; 
 &lt;tbody&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;strong&gt;L1: Read&lt;/strong&gt; &lt;/td&gt;
   &lt;td&gt; Semantic views of content &lt;/td&gt;
   &lt;td&gt; &lt;code&gt;view&lt;/code&gt; (text, annotated, outline, stats, issues, html) &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;strong&gt;L2: DOM&lt;/strong&gt; &lt;/td&gt;
   &lt;td&gt; Structured element operations &lt;/td&gt;
   &lt;td&gt; &lt;code&gt;get&lt;/code&gt;, &lt;code&gt;query&lt;/code&gt;, &lt;code&gt;set&lt;/code&gt;, &lt;code&gt;add&lt;/code&gt;, &lt;code&gt;remove&lt;/code&gt;, &lt;code&gt;move&lt;/code&gt; &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;strong&gt;L3: Raw XML&lt;/strong&gt; &lt;/td&gt;
   &lt;td&gt; Direct XPath access — universal fallback &lt;/td&gt;
   &lt;td&gt; &lt;code&gt;raw&lt;/code&gt;, &lt;code&gt;raw-set&lt;/code&gt;, &lt;code&gt;add-part&lt;/code&gt;, &lt;code&gt;validate&lt;/code&gt; &lt;/td&gt;
  &lt;/tr&gt; 
 &lt;/tbody&gt; 
&lt;/table&gt; 
&lt;h1&gt;L1 — high-level views&lt;/h1&gt; 
&lt;pre&gt;&lt;code&gt;officecli view report.docx annotated
officecli view budget.xlsx text --cols A,B,C --max-lines 50
&lt;/code&gt;&lt;/pre&gt; 
&lt;h1&gt;L2 — element-level operations&lt;/h1&gt; 
&lt;pre&gt;&lt;code&gt;officecli query report.docx &quot;run:contains(TODO)&quot;
officecli add budget.xlsx / --type sheet --prop name=&quot;Q2 Report&quot;
officecli move report.docx /body/p\[5\] --to /body --index 1
&lt;/code&gt;&lt;/pre&gt; 
&lt;h1&gt;L3 — raw XML when L2 isn&apos;t enough&lt;/h1&gt; 
&lt;pre&gt;&lt;code&gt;officecli raw deck.pptx /slide\[1\]
officecli raw-set report.docx document \\
--xpath &quot;//w:p\[1\]&quot; --action append \\
--xml &apos;&amp;lt;w:r&amp;gt;&amp;lt;w:t&amp;gt;Injected text&amp;lt;/w:t&amp;gt;&amp;lt;/w:r&amp;gt;&apos;
&lt;/code&gt;&lt;/pre&gt; 
&lt;h2&gt;AI Integration&lt;/h2&gt; 
&lt;h3&gt;MCP Server&lt;/h3&gt; 
&lt;p&gt;Built-in &lt;a href=&quot;https://modelcontextprotocol.io/&quot;&gt;MCP&lt;/a&gt; server — register with one command:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;officecli mcp claude       # Claude Code
officecli mcp cursor       # Cursor
officecli mcp vscode       # VS Code / Copilot
officecli mcp lmstudio     # LM Studio
officecli mcp list         # Check registration status
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Exposes all document operations as tools over JSON-RPC — no shell access needed.&lt;/p&gt; 
&lt;h3&gt;Direct CLI Integration&lt;/h3&gt; 
&lt;p&gt;Get OfficeCLI working with your AI agent in two steps:&lt;/p&gt; 
&lt;ol&gt; 
 &lt;li&gt;&lt;strong&gt;Install the binary&lt;/strong&gt; -- one command (see &lt;a href=&quot;https://github.com/iOfficeAI/OfficeCLI#installation&quot;&gt;Installation&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Done.&lt;/strong&gt; OfficeCLI automatically detects your AI tools (Claude Code, GitHub Copilot, Codex) by checking known config directories and installs its skill file. Your agent can immediately create, read, and modify any Office document.&lt;/li&gt; 
&lt;/ol&gt; 
&lt;p&gt;&lt;strong&gt;Manual setup (optional)&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;If auto-install doesn&apos;t cover your setup, you can install the skill file manually:&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Feed SKILL.md to your agent directly:&lt;/strong&gt;&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;curl -fsSL https://officecli.ai/SKILL.md
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;&lt;strong&gt;Install as a local skill for Claude Code:&lt;/strong&gt;&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;curl -fsSL https://officecli.ai/SKILL.md -o ~/.claude/skills/officecli.md
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;&lt;strong&gt;Other agents:&lt;/strong&gt; Include the contents of &lt;code&gt;SKILL.md&lt;/code&gt; (239 lines, ~8K tokens) in your agent&apos;s system prompt or tool description.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Call from any language:&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;Python:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;import subprocess, json
def cli(\*args): return subprocess.check\_output(\[&quot;officecli&quot;, \*args\], text\=True)
cli(&quot;create&quot;, &quot;deck.pptx&quot;)
cli(&quot;set&quot;, &quot;deck.pptx&quot;, &quot;/slide\[1\]/shape\[1\]&quot;, &quot;--prop&quot;, &quot;text=Hello&quot;)
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;JavaScript:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;const { execFileSync } \= require(&apos;child\_process&apos;)
const cli \= (...args) \=&amp;gt; execFileSync(&apos;officecli&apos;, args, { encoding: &apos;utf8&apos; })
cli(&apos;set&apos;, &apos;deck.pptx&apos;, &apos;/slide\[1\]/shape\[1\]&apos;, &apos;--prop&apos;, &apos;text=Hello&apos;)
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Every command supports &lt;code&gt;--json&lt;/code&gt; for structured output. Path-based addressing means agents don&apos;t need to understand XML namespaces.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>OneURL</title>
      <link>https://tedneward.github.io/Research/tools/oneurl/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/oneurl/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.oneurl.live/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/KartikLabhshetwar/oneurl&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>OpenPeon</title>
      <link>https://tedneward.github.io/Research/tools/openpeon/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/openpeon/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://openpeon.com/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://openpeon.com/spec&quot;&gt;Specification&lt;/a&gt; | &lt;a href=&quot;https://openpeon.com/packs&quot;&gt;Packs&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Orca Jam</title>
      <link>https://tedneward.github.io/Research/tools/orca-jam/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/orca-jam/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://orca.handmade.network/&quot;&gt;Website&lt;/a&gt; |&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Parser Construction Kit (PCK)</title>
      <link>https://tedneward.github.io/Research/tools/pck/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/pck/index.html</guid>
      	<description>
	&lt;p&gt;&quot;It currently supports Yacc/Bison and Flex/lex. Support is coming for GOLD, ANTLR and possibly Coco/R. ... In addition, Pck is unique in that it exposes much of the generation process (including grammar transformation) to the console, so that you can run intermediate tools on the output before feeding into the input of the next phase of the transformation. For example, you may convert a high level representation of a grammar into the low level representation used by the engine, and then left factor it for LL(1) parsing before passing it to the generator, a bit like your compiler and linker work together.&quot; -- from &lt;a href=&quot;https://www.codeproject.com/Articles/5163943/Pck-The-Parser-Construction-Kit&quot;&gt;CodeProject Article&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://github.com/codewitch-honey-crisis/pck&quot;&gt;Github&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Pencil Project</title>
      <link>https://tedneward.github.io/Research/tools/pencil-project/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/pencil-project/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://pencil.evolus.vn/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/evolus/pencil&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Phasar</title>
      <link>https://tedneward.github.io/Research/tools/phasar/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/phasar/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;http://phasar.org/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/secure-software-engineering/phasar&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Static Analysis for C++ with Phasar 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://pldi18.sigplan.org/event/pldi-2018-pldi-tutorials-static-analysis-for-c-with-phasar&quot;&gt;https://pldi18.sigplan.org/event/pldi-2018-pldi-tutorials-static-analysis-for-c-with-phasar&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;PhASAR: An Inter-Procedural Static Analysis Framework for C/C++ 
  &lt;ul&gt; 
   &lt;li&gt;TACAS 2019&lt;/li&gt; 
   &lt;li&gt;Philipp D. Schubert, Ben Hermann, Eric Bodden&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://www.thewhitespace.de/publications/shb19-phasar.pdf&quot;&gt;http://www.thewhitespace.de/publications/shb19-phasar.pdf&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>OllyDbg</title>
      <link>https://tedneward.github.io/Research/tools/ollydbg/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/ollydbg/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.ollydbg.de/&quot;&gt;Website&lt;/a&gt; | No source but free dowload&lt;/p&gt; 
&lt;p&gt;Work is suspended on 64-bit version.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Onyx</title>
      <link>https://tedneward.github.io/Research/tools/onyx/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/onyx/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://onyx.app/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/onyx-dot-app/onyx&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>OpenRewrite</title>
      <link>https://tedneward.github.io/Research/tools/openrewrite/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/openrewrite/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://docs.openrewrite.org/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/openrewrite/rewrite&quot;&gt;Source&lt;/a&gt; | &lt;a href=&quot;https://docs.openrewrite.org/recipes&quot;&gt;Recipe Catalog&lt;/a&gt; | &lt;a href=&quot;https://docs.openrewrite.org/authoring-recipes&quot;&gt;Authoring Recipes&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Moderne is a cloud-hosted commercial implementation of OpenRewrite.&lt;/p&gt; 
&lt;h2&gt;Articles&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;Baeldung: &lt;a href=&quot;https://www.baeldung.com/java-openrewrite&quot;&gt;&quot;A Guide to OpenRewrite&quot;&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Notes&lt;/h2&gt; 
&lt;p&gt;&lt;strong&gt;&lt;em&gt;automatically refactor source code by applying recipes to the project&lt;/em&gt;&lt;/strong&gt; Each recipe can perform specific refactoring tasks. These recipes are written in Java code and included in the build process using the OpenRewrite Maven or Gradle plugin. Comes with a variety of built-in recipes for common transformations. Community contributes recipes for others.&lt;/p&gt; 
&lt;p&gt;Uses &lt;a href=&quot;https://docs.openrewrite.org/concepts-and-explanations/lossless-semantic-trees&quot;&gt;&quot;Lossless Semantic Trees&quot;&lt;/a&gt; (basically boosted ASTs) to enable more fine-grained input as source to a collection of rules (recipes) that are run over source:&lt;/p&gt; 
&lt;p&gt;Unlike the traditional Abstract Syntax Tree (AST), OpenRewrite&apos;s LST offers a unique set of characteristics that make it possible to perform accurate transformations and searches across a repository:&lt;/p&gt; 
&lt;p&gt;Type-attributed. Each LST is imbued with type information. For example, when referencing a field, the source code may just refer to it as myField. The OpenRewrite LST for myField, on the other hand, would contain additional information about what the type of myField is, even if it isn&apos;t defined in the same source file or even the same project.&lt;br&gt; Format-preserving. Whitespace before and after LSTs are preserved in the tree so the tree can be printed out to reconstitute the original source code without clobbering formatting. Additionally, refactoring operations that insert code are sensitive to the local style of the code around them and match the local style.&lt;br&gt; Type attribution is necessary for the accurate matching of patterns. For example, if we are looking for SLF4J log statements and we see a statement like the following, without type attribution how do we know if logger is an SLF4J or a Logback logger?&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;logger.info(&quot;Hi&quot;);
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Format preservation is necessary if formatting isn&apos;t 100% consistent throughout the whole repository.&lt;/p&gt; 
&lt;p&gt;When you run an OpenRewrite recipe locally:&lt;/p&gt; 
&lt;ol&gt; 
 &lt;li&gt;The OpenRewrite process creates an LST which is stored in memory. This reflects the current state of the repository on disk.&lt;/li&gt; 
 &lt;li&gt;The process continues by making transformations on the LST. This could be adding a search marker (~~&amp;gt;) if the recipe is a search recipe -- or it could be more significant code changes.&lt;/li&gt; 
 &lt;li&gt;Once the recipe finishes running, the LST is converted back to text which then is used to overwrite any existing files that have changed.&lt;/li&gt; 
 &lt;li&gt;After all of the files have been overwritten, the process ends. Nothing is stored between recipe runs.&lt;/li&gt; 
 &lt;li&gt;If you go to run another recipe after the first one is done, a new LST will be generated at that time.&lt;/li&gt; 
 &lt;li&gt;If the previous recipe made changes and those changes exist locally, then the newly generated LST will have all of those changes. If the previous recipe made no changes, then the LST will effectively be the same one as before (but regenerated as the previous one no longer exists).&lt;/li&gt; 
&lt;/ol&gt; 
&lt;p&gt;&lt;a href=&quot;https://docs.openrewrite.org/concepts-and-explanations/lst-examples&quot;&gt;Java Examples of LSTs&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>PANDA (Platform for Architecture-Neutral Dynamic Analysis)</title>
      <link>https://tedneward.github.io/Research/tools/panda/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/panda/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/panda-re/panda&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>PDF24 Tools</title>
      <link>https://tedneward.github.io/Research/tools/pdf24/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/pdf24/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://tools.pdf24.org/en/&quot;&gt;Website&lt;/a&gt; | Downloadable desktop version&lt;/p&gt; 
&lt;p&gt;Merge PDF | Split PDF | Compress PDF | Edit PDF | Sign PDF | PDF Converter | Images to PDF | PDF to images | Extract PDF images | Protect PDF | Unlock PDF | Rotate PDF pages | Remove PDF pages | Extract PDF pages | Rearrange PDF pages | Webpage to PDF | Create PDF job application | Create PDF with a camera | PDF OCR | Add watermark | Add page numbers | View as PDF | PDF Overlay | Compare PDFs | Web optimize PDF | Annotate PDF | Redact PDF | Create PDF | PDF to Word | JPG to PDF&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>PeonPing</title>
      <link>https://tedneward.github.io/Research/tools/peonping/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/peonping/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.peonping.com/&quot;&gt;Website&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Pin</title>
      <link>https://tedneward.github.io/Research/tools/pin/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/pin/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;http://www.pintool.org/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://en.wikipedia.org/wiki/Pin_(computer_program)&quot;&gt;Wikipedia&lt;/a&gt;&lt;/p&gt; 
&lt;h3&gt;Readings&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;Analyzing Parallel Programs With Pin 
  &lt;ul&gt; 
   &lt;li&gt;IEEE Computer 43(3) 2010&lt;/li&gt; 
   &lt;li&gt;Moshe Bach, Mark Charney, Robert Cohn, Elena Demikhovsky, Tevi Devor, Kim Hazelwood, Aamer Jaleel, Chi-Keung Luk, Gail Lyons, Harish Patil, Ady Tal&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://doi.org/10.1109/mc.2010.60&quot;&gt;https://doi.org/10.1109/mc.2010.60&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Pin: Building Customized Program Analysis Tools with Dynamic Instrumentation 
  &lt;ul&gt; 
   &lt;li&gt;PLDI 2005&lt;/li&gt; 
   &lt;li&gt;Chi-Keung Luk, Robert Cohn, Robert Muth, Harish Patil, Artur Klauser, Geoff Lowney, Steven Wallace, Vijay Janapa Reddi, Kim Hazelwood&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://doi.org/10.1145/1065010.1065034&quot;&gt;https://doi.org/10.1145/1065010.1065034&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Deterministic PinPoints: Representative and Repeatable Simulation Region Selection with PinPlay and Sniper 
  &lt;ul&gt; 
   &lt;li&gt;HPCA 2013 Tutorial&lt;/li&gt; 
   &lt;li&gt;Harish Patil, Trevor E. Carlson&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://snipersim.org/w/Tutorial:HPCA_2013_PinPoints&quot;&gt;https://snipersim.org/w/Tutorial:HPCA_2013_PinPoints&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Dynamic Binary Analysis with Intel Pin 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://blog.netspi.com/dynamic-binary-analysis-intel-pin/&quot;&gt;https://blog.netspi.com/dynamic-binary-analysis-intel-pin/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/NetSPI/Pin&quot;&gt;https://github.com/NetSPI/Pin&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Pinballs: Portable and Shareable User-level Checkpoints for Reproducible Analysis and Simulation 
  &lt;ul&gt; 
   &lt;li&gt;REPRODUCE 2014: Workshop on Reproducible Research Methodologies&lt;/li&gt; 
   &lt;li&gt;Harish Patil, Trevor E. Carlson&lt;/li&gt; 
   &lt;li&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;&lt;a href=&quot;https://www.researchgate.net/publication/280306016_Pinballs_Portable_and_Shareable_User-level_Checkpoints_for_Reproducible_Analysis_and_Simulation_Appeared_in_REPRODUCE_2014_Workshop_on_Reproducible_Research_Methodologies&quot;&gt;https://www.researchgate.net/publication/280306016_Pinballs_Portable_and_Shareable_User-level_Checkpoints_for_Reproducible_Analysis_and_Simulation_Appeared_in_REPRODUCE_2014_Workshop_on_Reproducible_Research_Methodologies&lt;/a&gt;&lt;br&gt; - PinPlay: a framework for deterministic replay and reproducible analysis of parallel programs&lt;br&gt; - Code Generation and Optimization (CGO) 2010&lt;br&gt; - Harish Patil, Cristiano Pereira, Mack Stallcup, Gregory Lueck, James Cownie&lt;br&gt; - &lt;a href=&quot;https://doi.org/10.1145/1772954.1772958&quot;&gt;https://doi.org/10.1145/1772954.1772958&lt;/a&gt;&lt;br&gt; - PinPlay: Using PinPlay for Reproducible Analysis and Replay Debugging&lt;br&gt; - PLDI 2015 Tutorial&lt;br&gt; - Harish Patil, Milind Chabbi&lt;br&gt; - &lt;a href=&quot;https://pldi15.sigplan.org/details/pldi2015-workshops/6/PINPLAY-Using-PinPlay-for-Reproducible-Analysis-and-Replay-Debugging&quot;&gt;https://pldi15.sigplan.org/details/pldi2015-workshops/6/PINPLAY-Using-PinPlay-for-Reproducible-Analysis-and-Replay-Debugging&lt;/a&gt;&lt;br&gt; - &lt;a href=&quot;https://sites.google.com/site/pinplaypldi2015tutotial/&quot;&gt;https://sites.google.com/site/pinplaypldi2015tutotial/&lt;/a&gt;&lt;br&gt; - PinPoints: Pinpointing Representative Portions of Large Intel® Itanium® Programs with Dynamic Instrumentation&lt;br&gt; - MICRO 2004&lt;br&gt; - H. Patil, R. Cohn, M. Charney, R. Kapoor, A. Sun, A. Karunanidhi&lt;br&gt; - &lt;a href=&quot;https://doi.org/10.1109/MICRO.2004.28&quot;&gt;https://doi.org/10.1109/MICRO.2004.28&lt;/a&gt;&lt;br&gt; - &lt;a href=&quot;https://software.intel.com/en-us/articles/pin-a-binary-instrumentation-tool-pinpoints&quot;&gt;https://software.intel.com/en-us/articles/pin-a-binary-instrumentation-tool-pinpoints&lt;/a&gt;&lt;br&gt; - PinPoints: Simulation Region Selection with PinPlay and Sniper&lt;br&gt; - ISCA 2014 Tutorial&lt;br&gt; - Harish Patil, Mack Stallcup&lt;br&gt; - &lt;a href=&quot;https://sites.google.com/site/pinpointstutorialisca14/&quot;&gt;https://sites.google.com/site/pinpointstutorialisca14/&lt;/a&gt;&lt;br&gt; - Some thoughts about code-coverage measurement with Pin&lt;br&gt; - &lt;a href=&quot;https://doar-e.github.io/blog/2013/08/31/some-thoughts-about-code-coverage-measurement-with-pin/&quot;&gt;https://doar-e.github.io/blog/2013/08/31/some-thoughts-about-code-coverage-measurement-with-pin/&lt;/a&gt;&lt;/p&gt; 
&lt;h3&gt;Projects&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;Ablation: Augmenting Static Analysis Using Pintool 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/paulmehta/Ablation&quot;&gt;https://github.com/paulmehta/Ablation&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Black Hat 2016; Paul Mehta&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=wHIlNRK_HiQ&quot;&gt;https://www.youtube.com/watch?v=wHIlNRK_HiQ&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;BasicBlocks: Pin tool for printing the address of each basic block executed in a program. 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/chokepoint/BasicBlocks&quot;&gt;https://github.com/chokepoint/BasicBlocks&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Pin++: A C++ template meta-programmable framework for authoring Pintools 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/SEDS/PinPP&quot;&gt;https://github.com/SEDS/PinPP&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Pin++: A Object-oriented Framework for Writing Pintools 
    &lt;ul&gt; 
     &lt;li&gt;Generative Programming: Concepts and Experiences (GPCE) 2014&lt;/li&gt; 
     &lt;li&gt;James H. Hill and Dennis C. Feiock&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://core.ac.uk/download/pdf/46962422.pdf&quot;&gt;https://core.ac.uk/download/pdf/46962422.pdf&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;PinCTF: use Intel&apos;s Pin Tool to instrument binaries and count instructions 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/ChrisTheCoolHut/PinCTF&quot;&gt;https://github.com/ChrisTheCoolHut/PinCTF&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Magic-trace</title>
      <link>https://tedneward.github.io/Research/tools/magictrace/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/magictrace/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://magic-trace.org/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/janestreet/magic-trace&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;magic-trace only supports Linux. It relies on perf, which is Linux specific. We do not think this is a fundamental limitation of magic-trace, and would welcome patches to support other operating systems.&lt;/p&gt; 
&lt;p&gt;magic-trace relies on Intel Processor Trace, which only really starts to be functional on relatively recent Intel CPUs. That means it doesn&apos;t support ARM, and it doesn&apos;t support AMD.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>MarkItDown</title>
      <link>https://tedneward.github.io/Research/tools/markitdown/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/markitdown/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/microsoft/markitdown&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;h3&gt;Articles&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.infoworld.com/article/3963991/markitdown-microsofts-open-source-tool-for-markdown-conversion.html&quot;&gt;https://www.infoworld.com/article/3963991/markitdown-microsofts-open-source-tool-for-markdown-conversion.html&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>mdq</title>
      <link>https://tedneward.github.io/Research/tools/mdq/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/mdq/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://yshavit.github.io/mdq-playground/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/yshavit/mdq&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Middleman</title>
      <link>https://tedneward.github.io/Research/tools/middleman/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/middleman/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://middlemanapp.com/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/middleman/middleman&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Ruby gem.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>mistral-vibe</title>
      <link>https://tedneward.github.io/Research/tools/mistral-vibe/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/mistral-vibe/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/mistralai/mistral-vibe&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Mistral Vibe is a command-line coding assistant powered by Mistral&apos;s models. It provides a conversational interface to your codebase, allowing you to use natural language to explore, modify, and interact with your projects through a powerful set of tools.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Moon</title>
      <link>https://tedneward.github.io/Research/tools/moon/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/moon/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://moonrepo.dev/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/moonrepo&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Microsoft PowerToys</title>
      <link>https://tedneward.github.io/Research/tools/msft-power-toys/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/msft-power-toys/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://aka.ms/getPowertoys&quot;&gt;Microsoft Store&lt;/a&gt; | &lt;a href=&quot;https://docs.microsoft.com/en-us/windows/powertoys/install&quot;&gt;Docs&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>NDepend</title>
      <link>https://tedneward.github.io/Research/tools/ndepend/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/ndepend/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.ndepend.com/&quot;&gt;Website&lt;/a&gt; | Commercial&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Nix/NixOS/nixpkgs</title>
      <link>https://tedneward.github.io/Research/tools/nixos/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/nixos/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://nixos.org&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/NixOS&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;h2&gt;Articles&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://nixos.org/nix/manual/#ch-expression-language&quot;&gt;Nix Manual - Nix expression language&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://jonathanlorimer.dev/posts/nix-thesis.html&quot;&gt;The Nix Thesis&lt;/a&gt;:&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://medium.com/@MrJamesFisher/nix-by-example-a0063a1a4c55&quot;&gt;James Fisher - Nix by example - Part 1: The Nix expression language&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://ebzzry.io/en/nix/#nix&quot;&gt;Rommel Martinez - A Gentle Introduction to the Nix Family&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://jvns.ca/blog/2023/02/28/some-notes-on-using-nix/&quot;&gt;Some notes on using nix&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;&lt;a href=&quot;https://learnxinyminutes.com/docs/nix/&quot;&gt;Learn X in Y minutes Quick Intro:&lt;/a&gt;&lt;/h2&gt; 
&lt;hr&gt; 
&lt;p&gt;Nix is a simple functional language developed for the &lt;a href=&quot;https://nixos.org/nix/&quot;&gt;Nix package manager&lt;/a&gt; and &lt;a href=&quot;https://nixos.org/&quot;&gt;NixOS&lt;/a&gt;.&lt;/p&gt; 
&lt;p&gt;You can evaluate Nix expressions using &lt;a href=&quot;https://nixos.org/nix/manual/#sec-nix-instantiate&quot;&gt;nix-instantiate&lt;/a&gt; or &lt;a href=&quot;https://nixos.org/nix/manual/#ssec-relnotes-2.0&quot;&gt;&lt;code&gt;nix repl&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;with builtins; [

  #  Comments
  #=========================================

  # Inline comments look like this.

  /* Multi-line comments
     look like this. */


  #  Booleans
  #=========================================

  (true &amp;amp;&amp;amp; false)               # And
  #=&amp;gt; false

  (true || false)               # Or
  #=&amp;gt; true

  (if 3 &amp;lt; 4 then &quot;a&quot; else &quot;b&quot;)  # Conditional
  #=&amp;gt; &quot;a&quot;


  #  Integers and Floats
  #=========================================

  # There are two numeric types: integers and floats

  1 0 42 (-3)       # Some integers

  123.43 .27e13     # A couple of floats

  # Operations will preserve numeric type

  (4 + 6 + 12 - 2)  # Addition
  #=&amp;gt; 20
  (4 - 2.5)
  #=&amp;gt; 1.5

  (7 / 2)           # Division
  #=&amp;gt; 3
  (7 / 2.0)
  #=&amp;gt; 3.5


  #  Strings
  #=========================================

  &quot;Strings literals are in double quotes.&quot;

  &quot;
    String literals can span
    multiple lines.
  &quot;

  &apos;&apos;
    This is called an &quot;indented string&quot; literal.
    It intelligently strips leading whitespace.
  &apos;&apos;

  &apos;&apos;
    a
      b
  &apos;&apos;
  #=&amp;gt; &quot;a\n  b&quot;

  (&quot;ab&quot; + &quot;cd&quot;)   # String concatenation
  #=&amp;gt; &quot;abcd&quot;

  # Antiquotation lets you embed values into strings.
  (&quot;Your home directory is ${getEnv &quot;HOME&quot;}&quot;)
  #=&amp;gt; &quot;Your home directory is /home/alice&quot;


  #  Paths
  #=========================================

  # Nix has a primitive data type for paths.
  /tmp/tutorials/learn.nix

  # A relative path is resolved to an absolute path at parse
  # time, relative to the file in which it occurs.
  tutorials/learn.nix
  #=&amp;gt; /the-base-path/tutorials/learn.nix

  # A path must contain at least one slash, so a relative
  # path for a file in the same directory needs a ./ prefix,
  ./learn.nix
  #=&amp;gt; /the-base-path/learn.nix

  # The / operator must be surrounded by whitespace if
  # you want it to signify division.

  7/2        # This is a path literal
  (7 / 2)    # This is integer division


  #  Imports
  #=========================================

  # A nix file contains a single top-level expression with no free
  # variables. An import expression evaluates to the value of the
  # file that it imports.
  (import /tmp/foo.nix)

  # Imports can also be specified by strings.
  (import &quot;/tmp/foo.nix&quot;)

  # Import paths must be absolute. Path literals
  # are automatically resolved, so this is fine.
  (import ./foo.nix)

  # But this does not happen with strings.
  (import &quot;./foo.nix&quot;)
  #=&amp;gt; error: string ‘foo.nix’ doesn&apos;t represent an absolute path


  #  Let
  #=========================================

  # `let` blocks allow us to bind values to variables.
  (let x = &quot;a&quot;; in
    x + x + x)
  #=&amp;gt; &quot;aaa&quot;

  # Bindings can refer to each other, and their order does not matter.
  (let y = x + &quot;b&quot;;
       x = &quot;a&quot;; in
    y + &quot;c&quot;)
  #=&amp;gt; &quot;abc&quot;

  # Inner bindings shadow outer bindings.
  (let a = 1; in
    let a = 2; in
      a)
  #=&amp;gt; 2


  #  Functions
  #=========================================

  (n: n + 1)      # Function that adds 1

  ((n: n + 1) 5)  # That same function, applied to 5
  #=&amp;gt; 6

  # There is no syntax for named functions, but they
  # can be bound by `let` blocks like any other value.
  (let succ = (n: n + 1); in succ 5)
  #=&amp;gt; 6

  # A function has exactly one argument.
  # Multiple arguments can be achieved with currying.
  ((x: y: x + &quot;-&quot; + y) &quot;a&quot; &quot;b&quot;)
  #=&amp;gt; &quot;a-b&quot;

  # We can also have named function arguments,
  # which we&apos;ll get to later after we introduce sets.


  #  Lists
  #=========================================

  # Lists are denoted by square brackets.

  (length [1 2 3 &quot;x&quot;])
  #=&amp;gt; 4

  ([1 2 3] ++ [4 5])
  #=&amp;gt; [1 2 3 4 5]

  (concatLists [[1 2] [3 4] [5]])
  #=&amp;gt; [1 2 3 4 5]

  (head [1 2 3])
  #=&amp;gt; 1
  (tail [1 2 3])
  #=&amp;gt; [2 3]

  (elemAt [&quot;a&quot; &quot;b&quot; &quot;c&quot; &quot;d&quot;] 2)
  #=&amp;gt; &quot;c&quot;

  (elem 2 [1 2 3])
  #=&amp;gt; true
  (elem 5 [1 2 3])
  #=&amp;gt; false

  (filter (n: n &amp;lt; 3) [1 2 3 4])
  #=&amp;gt; [ 1 2 ]


  #  Sets
  #=========================================

  # A &quot;set&quot; is an unordered mapping with string keys.
  { foo = [1 2]; bar = &quot;x&quot;; }

  # The . operator pulls a value out of a set.
  { a = 1; b = 2; }.a
  #=&amp;gt; 1

  # The ? operator tests whether a key is present in a set.
  ({ a = 1; b = 2; } ? a)
  #=&amp;gt; true
  ({ a = 1; b = 2; } ? c)
  #=&amp;gt; false

  # The // operator merges two sets.
  ({ a = 1; } // { b = 2; })
  #=&amp;gt; { a = 1; b = 2; }

  # Values on the right override values on the left.
  ({ a = 1; b = 2; } // { a = 3; c = 4; })
  #=&amp;gt; { a = 3; b = 2; c = 4; }

  # The rec keyword denotes a &quot;recursive set&quot;,
  # in which attributes can refer to each other.
  (let a = 1; in     { a = 2; b = a; }.b)
  #=&amp;gt; 1
  (let a = 1; in rec { a = 2; b = a; }.b)
  #=&amp;gt; 2

  # Nested sets can be defined in a piecewise fashion.
  {
    a.b   = 1;
    a.c.d = 2;
    a.c.e = 3;
  }.a.c
  #=&amp;gt; { d = 2; e = 3; }

  # Sets are immutable, so you can&apos;t redefine an attribute:
  {
    a = { b = 1; };
    a.b = 2;
  }
  #=&amp;gt; attribute &apos;a.b&apos; at (string):3:5 already defined at (string):2:11

  # However, an attribute&apos;s set members can also be defined piecewise
  # way even if the attribute itself has been directly assigned.
  {
    a = { b = 1; };
    a.c = 2;
  }
  #=&amp;gt; { a = { b = 1; c = 2; }; }


  #  With
  #=========================================

  # The body of a `with` block is evaluated with
  # a set&apos;s mappings bound to variables.
  (with { a = 1; b = 2; };
    a + b)
  # =&amp;gt; 3

  # Inner bindings shadow outer bindings.
  (with { a = 1; b = 2; };
    (with { a = 5; };
      a + b))
  #=&amp;gt; 7

  # This first line of tutorial starts with &quot;with builtins;&quot;
  # because builtins is a set that contains all of the built-in
  # functions (length, head, tail, filter, etc.). This saves
  # us from having to write, for example, &quot;builtins.length&quot;
  # instead of just &quot;length&quot;.


  #  Set patterns
  #=========================================

  # Sets are useful when we need to pass multiple values
  # to a function.
  (args: args.x + &quot;-&quot; + args.y) { x = &quot;a&quot;; y = &quot;b&quot;; }
  #=&amp;gt; &quot;a-b&quot;

  # This can be written more clearly using set patterns.
  ({x, y}: x + &quot;-&quot; + y) { x = &quot;a&quot;; y = &quot;b&quot;; }
  #=&amp;gt; &quot;a-b&quot;

  # By default, the pattern fails on sets containing extra keys.
  ({x, y}: x + &quot;-&quot; + y) { x = &quot;a&quot;; y = &quot;b&quot;; z = &quot;c&quot;; }
  #=&amp;gt; error: anonymous function called with unexpected argument ‘z’

  # Adding &quot;, ...&quot; allows ignoring extra keys.
  ({x, y, ...}: x + &quot;-&quot; + y) { x = &quot;a&quot;; y = &quot;b&quot;; z = &quot;c&quot;; }
  #=&amp;gt; &quot;a-b&quot;


  #  Errors
  #=========================================

  # `throw` causes evaluation to abort with an error message.
  (2 + (throw &quot;foo&quot;))
  #=&amp;gt; error: foo

  # `tryEval` catches thrown errors.
  (tryEval 42)
  #=&amp;gt; { success = true; value = 42; }
  (tryEval (2 + (throw &quot;foo&quot;)))
  #=&amp;gt; { success = false; value = false; }

  # `abort` is like throw, but it&apos;s fatal; it cannot be caught.
  (tryEval (abort &quot;foo&quot;))
  #=&amp;gt; error: evaluation aborted with the following error message: ‘foo’

  # `assert` evaluates to the given value if true;
  # otherwise it throws a catchable exception.
  (assert 1 &amp;lt; 2; 42)
  #=&amp;gt; 42
  (assert 1 &amp;gt; 2; 42)
  #=&amp;gt; error: assertion failed at (string):1:1
  (tryEval (assert 1 &amp;gt; 2; 42))
  #=&amp;gt; { success = false; value = false; }


  #  Impurity
  #=========================================

  # Because repeatability of builds is critical to the Nix package
  # manager, functional purity is emphasized in the Nix language
  # used to describe Nix packages. But there are a few impurities.

  # You can refer to environment variables.
  (getEnv &quot;HOME&quot;)
  #=&amp;gt; &quot;/home/alice&quot;

  # The trace function is used for debugging. It prints the first
  # argument to stderr and evaluates to the second argument.
  (trace 1 2)
  #=&amp;gt; trace: 1
  #=&amp;gt; 2

  # You can write files into the Nix store. Although impure, this is
  # fairly safe because the file name is derived from the hash of
  # its contents. You can read files from anywhere. In this example,
  # we write a file into the store, and then read it back out.
  (let filename = toFile &quot;foo.txt&quot; &quot;hello!&quot;; in
    [filename (builtins.readFile filename)])
  #=&amp;gt; [ &quot;/nix/store/ayh05aay2anx135prqp0cy34h891247x-foo.txt&quot; &quot;hello!&quot; ]

  # We can also download files into the Nix store.
  (fetchurl &quot;https://example.com/package-1.2.3.tgz&quot;)
  #=&amp;gt; &quot;/nix/store/2drvlh8r57f19s9il42zg89rdr33m2rm-package-1.2.3.tgz&quot;

]
&lt;/code&gt;&lt;/pre&gt;
	</description>
    </item>
    <item>
      <title>Maigret</title>
      <link>https://tedneward.github.io/Research/tools/maigret/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/maigret/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/soxoj/maigret&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Maigret collects a dossier on a person by username only, checking for accounts on a huge number of sites and gathering all the available information from web pages. No API keys are required. Maigret is an easy-to-use and powerful fork of Sherlock.&lt;/p&gt; 
&lt;p&gt;Currently supports more than 3000 sites (full list), search is launched against 500 popular sites in descending order of popularity by default. Also supported checking Tor sites, I2P sites, and domains (via DNS resolving).&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>MarkText</title>
      <link>https://tedneward.github.io/Research/tools/marktext/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/marktext/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.marktext.me/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/marktext/marktext&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Medicat</title>
      <link>https://tedneward.github.io/Research/tools/medicat/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/medicat/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://medicatusb.com/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://medicatusb.com/docs/&quot;&gt;Docs&lt;/a&gt;&lt;/p&gt; 
&lt;h2&gt;Reading&lt;/h2&gt; 
&lt;h3&gt;Articles&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://gbatemp.net/threads/medicat-usb-a-multiboot-linux-usb-for-pc-repair.361577/&quot;&gt;https://gbatemp.net/threads/medicat-usb-a-multiboot-linux-usb-for-pc-repair.361577/&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Mill</title>
      <link>https://tedneward.github.io/Research/tools/mill/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/mill/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://mill-build.org/mill/0.11.12/Java_Intro_to_Mill.html&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/com-lihaoyi/mill&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Mizu</title>
      <link>https://tedneward.github.io/Research/tools/mizu/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/mizu/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://getmizu.io/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/up9inc/mizu&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>MPS</title>
      <link>https://tedneward.github.io/Research/tools/mps/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/mps/index.html</guid>
      	<description>
	&lt;h2&gt;Tutorials/Courses&lt;/h2&gt; 
&lt;p&gt;&lt;a href=&quot;https://github.com/markusvoelter/mpsintrocourse&quot;&gt;MPS Introduction Course&lt;/a&gt;: A slightly advanced introduction to MPS: two languages, a generator, an interpreter, language composition and non-textual notations.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Msty</title>
      <link>https://tedneward.github.io/Research/tools/msty/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/msty/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://msty.ai/&quot;&gt;Website&lt;/a&gt; | Commercial w/free option&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Nexe</title>
      <link>https://tedneward.github.io/Research/tools/nexe/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/nexe/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/nexe/nexe&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Motivation and Features&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Self contained applications&lt;/li&gt; 
 &lt;li&gt;Ability to run multiple applications with different node.js runtimes.&lt;/li&gt; 
 &lt;li&gt;Distribute binaries without needing node / npm.&lt;/li&gt; 
 &lt;li&gt;Idempotent builds&lt;/li&gt; 
 &lt;li&gt;Start and deploy faster.&lt;/li&gt; 
 &lt;li&gt;Lockdown specific application versions, and easily rollback.&lt;/li&gt; 
 &lt;li&gt;Flexible build pipeline&lt;/li&gt; 
 &lt;li&gt;Cross platform builds&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Nmap</title>
      <link>https://tedneward.github.io/Research/tools/nmap/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/nmap/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://nmap.org/&quot;&gt;Website&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Many systems and network administrators also find it useful for tasks such as network inventory, managing service upgrade schedules, and monitoring host or service uptime. Nmap uses raw IP packets in novel ways to determine what hosts are available on the network, what services (application name and version) those hosts are offering, what operating systems (and OS versions) they are running, what type of packet filters/firewalls are in use, and dozens of other characteristics. It was designed to rapidly scan large networks, but works fine against single hosts. Nmap runs on all major computer operating systems, and official binary packages are available for Linux, Windows, and Mac OS X. In addition to the classic command-line Nmap executable, the Nmap suite includes an advanced GUI and results viewer (Zenmap), a flexible data transfer, redirection, and debugging tool (Ncat), a utility for comparing scan results (Ndiff), and a packet generation and response analysis tool (Nping).&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Manuskript</title>
      <link>https://tedneward.github.io/Research/tools/manuskript/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/manuskript/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.theologeek.ch/manuskript/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/olivierkes/manuskript&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Mattermost</title>
      <link>https://tedneward.github.io/Research/tools/mattermost/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/mattermost/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://mattermost.com/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/mattermost/&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Mermaid</title>
      <link>https://tedneward.github.io/Research/tools/mermaid/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/mermaid/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://mermaid-js.github.io/mermaid/#/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/mermaid-js&quot;&gt;Source&lt;/a&gt; | &lt;a href=&quot;https://github.com/mermaid-js/mermaid-cli&quot;&gt;CLI&lt;/a&gt; | &lt;a href=&quot;https://mermaid.live/edit&quot;&gt;Live Editor&lt;/a&gt;&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.freecodecamp.org/news/use-mermaid-javascript-library-to-create-flowcharts/&quot;&gt;&quot;Use Mermaid JS library to create flowcharts&quot;&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.freecodecamp.org/news/how-to-become-an-analytical-programmer-compare-five-projects/&quot;&gt;&quot;How to Become an Analytical Programmer – Solve the &quot;Rock, Paper, Scissors&quot; Game 5 Ways Using JavaScript &amp;amp; Mermaid.js&quot;&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;To create a Mermaid diagram in these pages, use &lt;code&gt;&amp;lt;pre class=&quot;mermaid&quot;&amp;gt;&lt;/code&gt; ... &lt;code&gt;&amp;lt;/pre&amp;gt;&lt;/code&gt; to enclose the diagram text.&lt;/p&gt; 
&lt;p&gt;Frontmatter configuration: The entire mermaid configuration (except the secure configs) can be overridden by the diagram author in the frontmatter of the diagram. The frontmatter is a YAML block at the top of the diagram.&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;---
title: Hello Title
config:
  theme: base
  themeVariables:
    primaryColor: &quot;#00ff00&quot;
---
flowchart
    Hello --&amp;gt; World
&lt;/code&gt;&lt;/pre&gt; 
&lt;pre class=&quot;mermaid&quot;&gt;---
title: Hello Title
config:
  theme: base
  themeVariables:
    primaryColor: &quot;#00ff00&quot;
---
flowchart
    Hello --&amp;gt; World
&lt;/pre&gt; 
&lt;hr&gt; 
&lt;p&gt;&lt;a href=&quot;https://mermaid.js.org/syntax/flowchart.html&quot;&gt;Flowchart&lt;/a&gt;&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;flowchart TD
    A[Christmas] --&amp;gt;|Get money| B(Go shopping)
    B --&amp;gt; C{Let me think}
    C --&amp;gt;|One| D[Laptop]
    C --&amp;gt;|Two| E[iPhone]
    C --&amp;gt;|Three| F[fa:fa-car Car]
&lt;/code&gt;&lt;/pre&gt; 
&lt;pre class=&quot;mermaid&quot;&gt;flowchart TD
    A[Christmas] --&amp;gt;|Get money| B(Go shopping)
    B --&amp;gt; C{Let me think}
    C --&amp;gt;|One| D[Laptop]
    C --&amp;gt;|Two| E[iPhone]
    C --&amp;gt;|Three| F[fa:fa-car Car]
&lt;/pre&gt; 
&lt;hr&gt; 
&lt;p&gt;&lt;a href=&quot;https://mermaid.js.org/syntax/sequenceDiagram.html&quot;&gt;Sequence diagram&lt;/a&gt;&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;sequenceDiagram
    Alice-&amp;gt;&amp;gt;+John: Hello John, how are you?
    Alice-&amp;gt;&amp;gt;+John: John, can you hear me?
    John--&amp;gt;&amp;gt;-Alice: Hi Alice, I can hear you!
    John--&amp;gt;&amp;gt;-Alice: I feel great!
&lt;/code&gt;&lt;/pre&gt; 
&lt;pre class=&quot;mermaid&quot;&gt;sequenceDiagram
    Alice-&amp;gt;&amp;gt;+John: Hello John, how are you?
    Alice-&amp;gt;&amp;gt;+John: John, can you hear me?
    John--&amp;gt;&amp;gt;-Alice: Hi Alice, I can hear you!
    John--&amp;gt;&amp;gt;-Alice: I feel great!
&lt;/pre&gt; 
&lt;hr&gt; 
&lt;p&gt;&lt;a href=&quot;https://mermaid.js.org/syntax/classDiagram.html&quot;&gt;Class diagram&lt;/a&gt;&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;---
title: Animal example
---
classDiagram
    Animal &amp;lt;|-- Duck
    note for Duck &quot;can fly\ncan swim\ncan dive\ncan help in debugging&quot;
    Animal &amp;lt;|-- Fish
    Animal &amp;lt;|-- Zebra
    Animal : +int age
    Animal : +String gender
    Animal: +isMammal()
    Animal: +mate()
    class Duck{
      +String beakColor
      +swim()
      +quack()
    }
    class Fish{
      -int sizeInFeet
      -canEat()
    }
    class Zebra{
      +bool is_wild
      +run()
    }
    class Square~Shape~{
        int id
        List~int~ position
        setPoints(List~int~ points)
        getPoints() List~int~
    }

    Square : -List~string~ messages
    Square : +setMessages(List~string~ messages)
    Square : +getMessages() List~string~
    Square : +getDistanceMatrix() List~List~int~~

    classA --|&amp;gt; classB : Inheritance
    classC --* classD : Composition
    classE --o classF : Aggregation
    classG --&amp;gt; classH : Association
    classI -- classJ : Link(Solid)
    classK ..&amp;gt; classL : Dependency
    classM ..|&amp;gt; classN : Realization
    classO .. classP : Link(Dashed)
&lt;/code&gt;&lt;/pre&gt; 
&lt;pre class=&quot;mermaid&quot;&gt;---
title: Animal example
---
classDiagram
    Animal &amp;lt;|-- Duck
    Animal &amp;lt;|-- Fish
    Animal &amp;lt;|-- Zebra
    Animal : +int age
    Animal : +String gender
    Animal: +isMammal()
    Animal: +mate()
    class Duck{
      +String beakColor
      +swim()
      +quack()
    }
    class Fish{
      -int sizeInFeet
      -canEat()
    }
    class Zebra{
      +bool is_wild
      +run()
    }
    class Square~Shape~{
        int id
        List~int~ position
        setPoints(List~int~ points)
        getPoints() List~int~
    }
&lt;pre&gt;&lt;code&gt;Square : -List~string~ messages
Square : +setMessages(List~string~ messages)
Square : +getMessages() List~string~
Square : +getDistanceMatrix() List~List~int~~

classA --|&amp;gt; classB : Inheritance
classC --* classD : Composition
classE --o classF : Aggregation
classG --&amp;gt; classH : Association
classI -- classJ : Link(Solid)
classK ..&amp;gt; classL : Dependency
classM ..|&amp;gt; classN : Realization
classO .. classP : Link(Dashed)
&lt;/code&gt;&lt;/pre&gt;
&lt;/pre&gt; 
&lt;hr&gt; 
&lt;p&gt;&lt;a href=&quot;https://mermaid.js.org/syntax/stateDiagram.html&quot;&gt;State diagram&lt;/a&gt;&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;stateDiagram-v2
    [*] --&amp;gt; Still
    Still --&amp;gt; [*]
    Still --&amp;gt; Moving
    Moving --&amp;gt; Still
    Moving --&amp;gt; Crash
    Crash --&amp;gt; [*]
&lt;/code&gt;&lt;/pre&gt; 
&lt;pre class=&quot;mermaid&quot;&gt;stateDiagram-v2
    [*] --&amp;gt; Still
    Still --&amp;gt; [*]
    Still --&amp;gt; Moving
    Moving --&amp;gt; Still
    Moving --&amp;gt; Crash
    Crash --&amp;gt; [*]
&lt;/pre&gt; 
&lt;hr&gt; 
&lt;p&gt;&lt;a href=&quot;&quot;&gt;Quadrant chart&lt;/a&gt;&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;quadrantChart
  title Reach and engagement of campaigns
  x-axis Low Reach --&amp;gt; High Reach
  y-axis Low Engagement --&amp;gt; High Engagement
  quadrant-1 We should expand
  quadrant-2 Need to promote
  quadrant-3 Re-evaluate
  quadrant-4 May be improved
  Campaign A: [0.9, 0.0] radius: 12
  Campaign B:::class1: [0.8, 0.1] color: #ff3300, radius: 10
  Campaign C: [0.7, 0.2] radius: 25, color: #00ff33, stroke-color: #10f0f0
  Campaign D: [0.6, 0.3] radius: 15, stroke-color: #00ff0f, stroke-width: 5px ,color: #ff33f0
  Campaign E:::class2: [0.5, 0.4]
  Campaign F:::class3: [0.4, 0.5] color: #0000ff
  classDef class1 color: #109060
  classDef class2 color: #908342, radius : 10, stroke-color: #310085, stroke-width: 10px
  classDef class3 color: #f00fff, radius : 10
&lt;/code&gt;&lt;/pre&gt; 
&lt;pre class=&quot;mermaid&quot;&gt;quadrantChart
  title Reach and engagement of campaigns
  x-axis Low Reach --&amp;gt; High Reach
  y-axis Low Engagement --&amp;gt; High Engagement
  quadrant-1 We should expand
  quadrant-2 Need to promote
  quadrant-3 Re-evaluate
  quadrant-4 May be improved
  Campaign A: [0.9, 0.0] radius: 12
  Campaign B:::class1: [0.8, 0.1] color: #ff3300, radius: 10
  Campaign C: [0.7, 0.2] radius: 25, color: #00ff33, stroke-color: #10f0f0
  Campaign D: [0.6, 0.3] radius: 15, stroke-color: #00ff0f, stroke-width: 5px ,color: #ff33f0
  Campaign E:::class2: [0.5, 0.4]
  Campaign F:::class3: [0.4, 0.5] color: #0000ff
  classDef class1 color: #109060
  classDef class2 color: #908342, radius : 10, stroke-color: #310085, stroke-width: 10px
  classDef class3 color: #f00fff, radius : 10
&lt;/pre&gt;
	</description>
    </item>
    <item>
      <title>MinerU</title>
      <link>https://tedneward.github.io/Research/tools/mineru/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/mineru/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://mineru.net/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/opendatalab/mineru&quot;&gt;Source&lt;/a&gt; | &lt;a href=&quot;https://deepwiki.com/opendatalab/MinerU&quot;&gt;DeepWiki&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Mkdocs</title>
      <link>https://tedneward.github.io/Research/tools/mkdocs/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/mkdocs/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.mkdocs.org/&quot;&gt;Website&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>mq</title>
      <link>https://tedneward.github.io/Research/tools/mq/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/mq/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://mqlang.org/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/harehare/mq&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;h2&gt;&lt;a href=&quot;https://github.com/harehare/mq#why-mq&quot;&gt;Why mq?&lt;/a&gt;&lt;/h2&gt; 
&lt;p&gt;mq makes working with Markdown files as easy as jq makes working with JSON. It&apos;s especially useful for:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;strong&gt;LLM Workflows&lt;/strong&gt;: Efficiently manipulate and process Markdown used in LLM prompts and outputs&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;LLM Input Generation&lt;/strong&gt;: Generate structured Markdown content optimized for LLM consumption, since Markdown serves as the primary input format for most language models&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Documentation Management&lt;/strong&gt;: Extract, transform, and organize content across multiple documentation files&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Content Analysis&lt;/strong&gt;: Quickly extract specific sections or patterns from Markdown documents&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Batch Processing&lt;/strong&gt;: Apply consistent transformations across multiple Markdown files&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;Since LLM inputs are primarily in Markdown format, mq provides efficient tools for generating and processing the structured Markdown content that LLMs require.&lt;/p&gt; 
&lt;h2&gt;&lt;a href=&quot;https://github.com/harehare/mq#features&quot;&gt;Features&lt;/a&gt;&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;strong&gt;Slice and Filter&lt;/strong&gt;: Extract specific parts of your Markdown documents with ease.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Map and Transform&lt;/strong&gt;: Apply transformations to your Markdown content.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Command-line Interface&lt;/strong&gt;: Simple and intuitive CLI for quick operations.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Extensibility&lt;/strong&gt;: Easily extendable with custom functions.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Built-in support&lt;/strong&gt;: Filter and transform content with many built-in functions and selectors.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;REPL Support&lt;/strong&gt;: Interactive command-line REPL for testing and experimenting.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;IDE Support&lt;/strong&gt;: VSCode Extension and Language Server &lt;strong&gt;Protocol&lt;/strong&gt; (LSP) support for custom function development.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Debugger&lt;/strong&gt;: Includes an experimental debugger (&lt;code&gt;mq-dbg&lt;/code&gt;) for inspecting and stepping through mq queries interactively.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;External Subcommands&lt;/strong&gt;: Extend mq with custom subcommands by placing executable files starting with &lt;code&gt;mq-&lt;/code&gt; in &lt;code&gt;~/.mq/bin/&lt;/code&gt;.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;&lt;a href=&quot;https://github.com/harehare/mq#installation&quot;&gt;Getting Started&lt;/a&gt;&lt;/h2&gt; 
&lt;h3&gt;&lt;a href=&quot;https://github.com/harehare/mq#quick-install&quot;&gt;Quick Install&lt;/a&gt;&lt;/h3&gt; 
&lt;p&gt;&lt;code&gt;curl -sSL https://mqlang.org/install.sh | bash&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;The installer will:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Download the latest mq binary for your platform&lt;/li&gt; 
 &lt;li&gt;Install it to &lt;code&gt;~/.mq/bin/&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;Update your shell profile to add mq to your PATH&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;&lt;a href=&quot;https://github.com/harehare/mq#binaries&quot;&gt;Binaries&lt;/a&gt;&lt;/h3&gt; 
&lt;p&gt;You can download pre-built binaries from the &lt;a href=&quot;https://github.com/harehare/mq/releases&quot;&gt;GitHub releases page&lt;/a&gt;:&lt;/p&gt; 
&lt;h1&gt;macOS (Apple Silicon): &lt;code&gt;curl -L https://github.com/harehare/mq/releases/download/v0.5.6/mq-aarch64-apple-darwin -o /usr/local/bin/mq &amp;amp;&amp;amp; chmod +x /usr/local/bin/mq&lt;/code&gt;&lt;/h1&gt; 
&lt;h1&gt;Linux x86_64: &lt;code&gt;curl -L https://github.com/harehare/mq/releases/download/v0.5.6/mq-x86\_64-unknown-linux-gnu -o /usr/local/bin/mq &amp;amp;&amp;amp; chmod +x /usr/local/bin/mq&lt;/code&gt;&lt;/h1&gt; 
&lt;h1&gt;Linux arm64: &lt;code&gt;curl -L https://github.com/harehare/mq/releases/download/v0.5.6/mq-aarch64-unknown-linux-gnu -o /usr/local/bin/mq &amp;amp;&amp;amp; chmod +x /usr/local/bin/mq&lt;/code&gt;&lt;/h1&gt; 
&lt;h1&gt;Windows (PowerShell): &lt;code&gt;Invoke-WebRequest -Uri https://github.com/harehare/mq/releases/download/v0.5.6/mq-x86\_64-pc-windows-msvc.exe -OutFile &quot;$env:USERPROFILE\\bin\\mq.exe&quot;&lt;/code&gt;&lt;/h1&gt; 
&lt;h3&gt;&lt;a href=&quot;https://github.com/harehare/mq#homebrew&quot;&gt;Homebrew&lt;/a&gt;&lt;/h3&gt; 
&lt;pre&gt;&lt;code&gt;# Using Homebrew (macOS and Linux)
brew install mq
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;&lt;a href=&quot;https://github.com/harehare/mq#docker&quot;&gt;Docker&lt;/a&gt;&lt;/h3&gt; 
&lt;pre&gt;&lt;code&gt;$ docker run --rm ghcr.io/harehare/mq:0.5.6
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;&lt;a href=&quot;https://github.com/harehare/mq#python&quot;&gt;Python&lt;/a&gt;&lt;/h3&gt; 
&lt;p&gt;You can use mq in Python through the &lt;code&gt;markdown-query&lt;/code&gt; package:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;# Install from PyPI
pip install markdown-query
&lt;/code&gt;&lt;/pre&gt;
	</description>
    </item>
    <item>
      <title>Mu (Code Editor)</title>
      <link>https://tedneward.github.io/Research/tools/mu/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/mu/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://codewith.mu/en/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/mu-editor/mu&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Ninja</title>
      <link>https://tedneward.github.io/Research/tools/ninja/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/ninja/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://ninja-build.org/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/ninja-build/ninja&quot;&gt;Github&lt;/a&gt;&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Benchmarking the Ninja build system 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;http://david.rothlis.net/ninja-benchmark/&quot;&gt;http://david.rothlis.net/ninja-benchmark/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Building Like (a) Ninja [Pt1] 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://vector-of-bool.github.io/2018/12/20/build-like-ninja-1.html&quot;&gt;https://vector-of-bool.github.io/2018/12/20/build-like-ninja-1.html&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;GN: a meta-build system that generates build files for Ninja 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://gn.googlesource.com/gn&quot;&gt;https://gn.googlesource.com/gn&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://is.gd/gn_intro&quot;&gt;https://is.gd/gn_intro&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Basic //build directory for GN-based projects 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://github.com/timniederhausen/gn-build&quot;&gt;https://github.com/timniederhausen/gn-build&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;ninjatracing: Convert .ninja_log files to chrome&apos;s about:tracing format. 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/nico/ninjatracing&quot;&gt;https://github.com/nico/ninjatracing&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Nomic GPT4All</title>
      <link>https://tedneward.github.io/Research/tools/nomic/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/nomic/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.nomic.ai/gpt4all&quot;&gt;Website&lt;/a&gt; | Commercial/closed&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Markdoc</title>
      <link>https://tedneward.github.io/Research/tools/markdoc/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/markdoc/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://markdoc.io/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/markdoc/markdoc&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Appears to have tools to render to an AST, which I find intriguing....&lt;/p&gt; 
&lt;p&gt;&lt;code&gt;npm install @markdoc/markdoc&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;then&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;const Markdoc = require(&apos;@markdoc/markdoc&apos;);
// or
import Markdoc from &apos;@markdoc/markdoc&apos;;

const doc = `
# Markdoc README

{% image src=&quot;/logo.svg&quot; /%}
`;

const ast = Markdoc.parse(doc);
const content = Markdoc.transform(ast);
return Markdoc.renderers.react(content, React);
&lt;/code&gt;&lt;/pre&gt;
	</description>
    </item>
    <item>
      <title>mdBook</title>
      <link>https://tedneward.github.io/Research/tools/mdbook/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/mdbook/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://rust-lang.github.io/mdBook/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/rust-lang/mdBook&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Meson</title>
      <link>https://tedneward.github.io/Research/tools/meson/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/meson/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;http://mesonbuild.com/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://mesonbuild.com/Videos.html&quot;&gt;Videos&lt;/a&gt; | &lt;a href=&quot;https://github.com/mesonbuild/meson&quot;&gt;Github&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Getting started with Meson build system and C++: &lt;a href=&quot;https://medium.com/@germandiagogomez/getting-started-with-meson-build-system-and-c-83270f444bee&quot;&gt;Part 1&lt;/a&gt; | &lt;a href=&quot;https://medium.com/@germandiagogomez/getting-started-with-meson-in-c-part-2-58150354ff17&quot;&gt;Part 2&lt;/a&gt; | &lt;a href=&quot;https://medium.com/@germandiagogomez/getting-started-with-meson-in-c-part-3-70b9bc419957&quot;&gt;Part 3&lt;/a&gt; | &lt;a href=&quot;https://medium.com/@germandiagogomez/getting-started-with-meson-part-4-8bceec6149e1&quot;&gt;Part 4&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Mint</title>
      <link>https://tedneward.github.io/Research/tools/mint/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/mint/index.html</guid>
      	<description>
	&lt;p&gt;&lt;code&gt;brew install mint&lt;/code&gt; | &lt;a href=&quot;https://github.com/yonaskolb/Mint&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Mockoon</title>
      <link>https://tedneward.github.io/Research/tools/mockoon/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/mockoon/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://mockoon.com&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/mockoon/mockoon&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>MSBuild</title>
      <link>https://tedneward.github.io/Research/tools/msbuild/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/msbuild/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/Microsoft/msbuild&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://docs.microsoft.com/en-us/visualstudio/msbuild/&quot;&gt;Docs&lt;/a&gt;&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;MSBuild (Visual C++) - &lt;a href=&quot;https://docs.microsoft.com/en-us/cpp/build/msbuild-visual-cpp&quot;&gt;https://docs.microsoft.com/en-us/cpp/build/msbuild-visual-cpp&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;Make VC++ Compiles Fast Through Parallel Compilation 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://randomascii.wordpress.com/2014/03/22/make-vc-compiles-fast-through-parallel-compilation/&quot;&gt;https://randomascii.wordpress.com/2014/03/22/make-vc-compiles-fast-through-parallel-compilation/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Microsoft AnyBuild 
  &lt;ul&gt; 
   &lt;li&gt;Remote build execution technology for use in MSBuild, Microsoft Build Accelerator, and other build engines&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/microsoft/AnyBuild&quot;&gt;https://github.com/microsoft/AnyBuild&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;MSBuild (Visual C++) - &lt;a href=&quot;https://docs.microsoft.com/en-us/cpp/build/msbuild-visual-cpp&quot;&gt;https://docs.microsoft.com/en-us/cpp/build/msbuild-visual-cpp&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;MSBuild Binary and Structured Log Viewer - &lt;a href=&quot;http://msbuildlog.com/&quot;&gt;http://msbuildlog.com/&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;MSBuildEditor 
  &lt;ul&gt; 
   &lt;li&gt;The MSBuild Editor extension provides improved support for editing MSBuild files in Visual Studio and Visual Studio for Mac.&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/mhutch/MonoDevelop.MSBuildEditor&quot;&gt;https://github.com/mhutch/MonoDevelop.MSBuildEditor&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Build Tools 
  &lt;ul&gt; 
   &lt;li&gt;build native and managed MSBuild-based applications without requiring the Visual Studio IDE. There are options to install the Visual C++ compilers and libraries, MFC, ATL, and C++/CLI support, and .NET and .NET Core support.&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://aka.ms/buildtools&quot;&gt;http://aka.ms/buildtools&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;GoingNative 63: C++ Build Tools - &lt;a href=&quot;https://channel9.msdn.com/Shows/C9-GoingNative/GoingNative-63-CPP-Build-Tools&quot;&gt;https://channel9.msdn.com/Shows/C9-GoingNative/GoingNative-63-CPP-Build-Tools&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.reedbeta.com/blog/custom-toolchain-with-msbuild/&quot;&gt;Using A Custom Toolchain In Visual Studio With MSBuild&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://miken-1gam.blogspot.com/2013/01/visual-studio-and-custom-build-rules.html&quot;&gt;Visual Studio and Custom Build Rules&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/BenVillalobos/msbuildism&quot;&gt;&quot;MSBuild is complicated. Let&apos;s lift the veil on it.&quot;&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>n8n</title>
      <link>https://tedneward.github.io/Research/tools/n8n/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/n8n/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://n8n.io&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/n8n-io/n8n&quot;&gt;Source&lt;/a&gt; | &lt;a href=&quot;https://docs.n8n.io/&quot;&gt;Docs&lt;/a&gt; | &lt;a href=&quot;https://n8n.io/integrations&quot;&gt;400+ Integrations&lt;/a&gt; | &lt;a href=&quot;https://n8n.io/workflows&quot;&gt;Example Workflows&lt;/a&gt; | &lt;a href=&quot;https://docs.n8n.io/advanced-ai/&quot;&gt;AI &amp;amp; LangChain Guide&lt;/a&gt; | &lt;a href=&quot;https://community.n8n.io/&quot;&gt;Community Forum&lt;/a&gt; | &lt;a href=&quot;https://community.n8n.io/c/tutorials/28&quot;&gt;Community Tutorials&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;n8n is a workflow automation platform that gives technical teams the flexibility of code with the speed of no-code. With 400+ integrations, native AI capabilities, and a fair-code license, n8n lets you build powerful automations while maintaining full control over your data and deployments.&lt;/p&gt; 
&lt;h2&gt;Quick Start&lt;/h2&gt; 
&lt;p&gt;Try n8n instantly with &lt;a href=&quot;https://docs.n8n.io/hosting/installation/npm/&quot;&gt;npx&lt;/a&gt; (requires &lt;a href=&quot;https://nodejs.org/en/&quot;&gt;Node.js&lt;/a&gt;):&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;npx n8n
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Or deploy with &lt;a href=&quot;https://docs.n8n.io/hosting/installation/docker/&quot;&gt;Docker&lt;/a&gt;:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;docker volume create n8n_data
docker run -it --rm --name n8n -p 5678:5678 -v n8n_data:/home/node/.n8n docker.n8n.io/n8nio/n8n
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Access the editor at &lt;a href=&quot;http://localhost:5678/&quot;&gt;http://localhost:5678&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>NirLauncher</title>
      <link>https://tedneward.github.io/Research/tools/nirlauncher/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/nirlauncher/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://launcher.nirsoft.net/&quot;&gt;Website&lt;/a&gt;&lt;/p&gt; 
&lt;h2&gt;Reading&lt;/h2&gt; 
&lt;h3&gt;Articles&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.makeuseof.com/portable-windows-toolkit-fits-on-usb-replaces-apps/&quot;&gt;https://www.makeuseof.com/portable-windows-toolkit-fits-on-usb-replaces-apps/&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>NotebookLM</title>
      <link>https://tedneward.github.io/Research/tools/notebooklm/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/notebooklm/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://notebooklm.google.com/&quot;&gt;Website&lt;/a&gt;&lt;/p&gt; 
&lt;h2&gt;Reading&lt;/h2&gt; 
&lt;h3&gt;Articles&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.xda-developers.com/learn-how-to-self-host-llm-with-notebooklm/&quot;&gt;How NotebookLM made self-hosting an LLM easier than I ever expected&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.fastcompany.com/91467915/notebooklm-guide-google-docs&quot;&gt;The complete guide to NotebookLM&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.makeuseof.com/i-tried-audio-video-overviews-notebooklm/&quot;&gt;I gave in and tried NotebookLM&apos;s popular features and it forever changed how I learn&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://pub.towardsai.net/the-notebooklm-workflow-that-changed-how-i-learn-any-technology-373f430a17e5&quot;&gt;The NotebookLM Workflow That Changed How I Learn Any Technology&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>flex</title>
      <link>https://tedneward.github.io/Research/tools/gnu/flex/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/gnu/flex/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/westes/flex/&quot;&gt;GNU Website&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Gollum</title>
      <link>https://tedneward.github.io/Research/tools/gollum/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/gollum/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/gollum/gollum&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Grav</title>
      <link>https://tedneward.github.io/Research/tools/grav/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/grav/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://getgrav.org/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/getgrav/grav&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Hatch</title>
      <link>https://tedneward.github.io/Research/tools/hatch/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/hatch/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://hatch.pypa.io/latest&quot;&gt;Website&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Hoarder</title>
      <link>https://tedneward.github.io/Research/tools/hoarder/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/hoarder/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://hoarder.app/&quot;&gt;Website&lt;/a&gt;&lt;br&gt; &lt;a href=&quot;https://github.com/hoarder-app/hoarder&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>HTML Tools</title>
      <link>https://tedneward.github.io/Research/tools/html-tools/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/html-tools/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://simonwillison.net/2025/Dec/10/html-tools/&quot;&gt;Article&lt;/a&gt; | &lt;a href=&quot;https://tools.simonwillison.net/&quot;&gt;&quot;over 150 of them&quot;&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;em&gt;There&apos;s... a lot to unpack here. In a good way.&lt;/em&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>IDA Pro</title>
      <link>https://tedneward.github.io/Research/tools/ida-pro/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/ida-pro/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://hex-rays.com/ida-pro/&quot;&gt;Website&lt;/a&gt; | Commercial with free download&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Imagor</title>
      <link>https://tedneward.github.io/Research/tools/imagor/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/imagor/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://imagor.net/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/cshum/imagor-studio&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;h2&gt;Getting Started&lt;/h2&gt; 
&lt;p&gt;Docker: &lt;code&gt;docker run -p 8000:8000 --rm -v $(pwd)/imagor-studio-data:/app/data -v ~/Pictures:/app/gallery -e DATABASE_URL=&quot;sqlite:///app/data/imagor-studio.db&quot; shumc/imagor-studio&lt;/code&gt;&lt;/p&gt; 
&lt;h2&gt;Reading&lt;/h2&gt; 
&lt;h3&gt;Articles, Blogs, Essays&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.xda-developers.com/imagor-self-hosted-image-gallery-and-editor-running-browser/&quot;&gt;Imagor is a self-hosted image gallery and editor, running entirely in your browser&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Instrew</title>
      <link>https://tedneward.github.io/Research/tools/instrew/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/instrew/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/aengelke/instrew&quot;&gt;Source&lt;/a&gt; | &lt;a href=&quot;https://conf.researchr.org/details/vee-2020/vee-2020-papers/5/Instrew-Leveraging-LLVM-for-High-Performance-Dynamic-Binary-Instrumentation&quot;&gt;Paper&lt;/a&gt; (by Alexis Engelke, Martin Schulz; VEE 2020)&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>jArchitect</title>
      <link>https://tedneward.github.io/Research/tools/jarchitect/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/jarchitect/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.jarchitect.com/&quot;&gt;Website&lt;/a&gt; | Commercial (free trial)&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>jc (JSON formatting tool)</title>
      <link>https://tedneward.github.io/Research/tools/jc/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/jc/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/kellyjonbrazil/jc&quot;&gt;Source&lt;/a&gt; | &lt;a href=&quot;https://blog.kellybrazil.com/2019/11/26/bringing-the-unix-philosophy-to-the-21st-century/&quot;&gt;&quot;Bringing the Unix Philosophy to the 21st Century&quot;&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Ironically, this is what &lt;a href=&quot;/languages/powershell&quot;&gt;PowerShell&lt;/a&gt; took as a fundamental principle: a pipeline/stream of objects, rather than just JSON.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Jekyll</title>
      <link>https://tedneward.github.io/Research/tools/jekyll/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/jekyll/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://jekyllrb.com/&quot;&gt;Website&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>jQAssistant</title>
      <link>https://tedneward.github.io/Research/tools/jqassistant/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/jqassistant/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://jqassistant.org/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/jqassistant&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;It is centered around three main use cases:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Easily carry out &lt;a href=&quot;https://en.wikipedia.org/wiki/Software_analytics&quot;&gt;Software Analytics&lt;/a&gt; to gain insights into your software systems&lt;/li&gt; 
 &lt;li&gt;Continuously verify the correct implementation of targeted design and architecture using provided or user-defined rules to reach defined quality goals&lt;/li&gt; 
 &lt;li&gt;Automatically enable &lt;a href=&quot;https://medium.com/geekculture/living-documentation-brief-history-and-evolution-of-the-concept-4492fafb5d7&quot;&gt;Living Documentation&lt;/a&gt; by generating documentation from the code and validating documentation against the implementation to avoid the documentation-code-gap and confusion&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>kalk.dev</title>
      <link>https://tedneward.github.io/Research/tools/kalk-dev/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/kalk-dev/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://kalk.dev/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/xoofx/kalk/&quot;&gt;Source&lt;/a&gt; | &lt;a href=&quot;https://kalk.dev/doc/&quot;&gt;Docs&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Komodo Edit</title>
      <link>https://tedneward.github.io/Research/tools/komodo/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/komodo/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;http://www.komodoide.com/komodo-edit&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/Komodo/KomodoEdit&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Lazydocker</title>
      <link>https://tedneward.github.io/Research/tools/lazydocker/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/lazydocker/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/jesseduffield/lazydocker&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Lincheck</title>
      <link>https://tedneward.github.io/Research/tools/lincheck/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/lincheck/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://kotlinlang.org/docs/lincheck-guide.html&quot;&gt;Website&lt;/a&gt; | JetBrains (no source?)&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>LLVM (toolchain)</title>
      <link>https://tedneward.github.io/Research/tools/llvm/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/llvm/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://llvm.org&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/llvm/llvm-project/&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Clang documentation - &lt;a href=&quot;http://clang.llvm.org/docs/&quot;&gt;http://clang.llvm.org/docs/&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;LLVM documentation - &lt;a href=&quot;http://llvm.org/docs/&quot;&gt;http://llvm.org/docs/&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>GNU Make</title>
      <link>https://tedneward.github.io/Research/tools/gnu/make/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/gnu/make/index.html</guid>
      	<description>
	&lt;p&gt;The original build tool for C/C++ source systems.&lt;/p&gt; 
&lt;h2&gt;&lt;a href=&quot;https://learnxinyminutes.com/docs/make/&quot;&gt;Learn X in Y Minutes: make&lt;/a&gt;&lt;/h2&gt; 
&lt;p&gt;A Makefile defines a graph of rules for creating a target (or targets). Its purpose is to do the minimum amount of work needed to update a target to the most recent version of the source.&lt;/p&gt; 
&lt;p&gt;There are many varieties of make in existence, however this article assumes that we are using GNU make which is the standard on Linux.&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-make&quot;&gt;
# Comments can be written like this.

# File should be named Makefile and then can be run as `make &amp;lt;target&amp;gt;`.
# Otherwise we use `make -f &quot;filename&quot; &amp;lt;target&amp;gt;`.

# Warning - only use TABS to indent in Makefiles, never spaces!

#-----------------------------------------------------------------------
# Basics
#-----------------------------------------------------------------------

# Rules are of the format
# target: &amp;lt;prerequisite&amp;gt;
# where prerequisites are optional.

# A rule - this rule will only run if file0.txt doesn&apos;t exist.
file0.txt:
	echo &quot;foo&quot; &amp;gt; file0.txt
		# Even comments in these &apos;recipe&apos; sections get passed to the shell.
		# Try `make file0.txt` or simply `make` - first rule is the default.

# This rule will only run if file0.txt is newer than file1.txt.
file1.txt: file0.txt
	cat file0.txt &amp;gt; file1.txt
		# use the same quoting rules as in the shell.
	@cat file0.txt &amp;gt;&amp;gt; file1.txt
		# @ stops the command from being echoed to stdout.
	-@echo &apos;hello&apos;
		# - means that make will keep going in the case of an error.
		# Try `make file1.txt` on the commandline.

# A rule can have multiple targets and multiple prerequisites
file2.txt file3.txt: file0.txt file1.txt
	touch file2.txt
	touch file3.txt

# Make will complain about multiple recipes for the same rule. Empty
# recipes don&apos;t count though and can be used to add new dependencies.

#-----------------------------------------------------------------------
# Phony Targets
#-----------------------------------------------------------------------

# A phony target. Any target that isn&apos;t a file.
# It will never be up to date so make will always try to run it.
all: maker process

# We can declare things out of order.
maker:
	touch ex0.txt ex1.txt

# Can avoid phony rules breaking when a real file has the same name by
.PHONY: all maker process
	# This is a special target. There are several others.

# A rule with a dependency on a phony target will always run
ex0.txt ex1.txt: maker

# Common phony targets are: all make clean install ...

#-----------------------------------------------------------------------
# Automatic Variables &amp;amp; Wildcards
#-----------------------------------------------------------------------

process: file*.txt	#using a wildcard to match filenames
	@echo $^	# $^ is a variable containing the list of prerequisites
	@echo $@	# prints the target name
	#(for multiple target rules, $@ is whichever caused the rule to run)
	@echo $&amp;lt;	# the first prerequisite listed
	@echo $?	# only the dependencies that are out of date
	@echo $+	# all dependencies including duplicates (unlike normal)
	#@echo $|	# all of the &apos;order only&apos; prerequisites

# Even if we split up the rule dependency definitions, $^ will find them
process: ex1.txt file0.txt
	# ex1.txt will be found but file0.txt will be deduplicated.

#-----------------------------------------------------------------------
# Patterns
#-----------------------------------------------------------------------

# Can teach make how to convert certain files into other files.

%.png: %.svg
	inkscape --export-png $^

# Pattern rules will only do anything if make decides to create the
# target.

# Directory paths are normally ignored when matching pattern rules. But
# make will try to use the most appropriate rule available.
small/%.png: %.svg
	inkscape --export-png --export-dpi 30 $^

# make will use the last version for a pattern rule that it finds.
%.png: %.svg
	@echo this rule is chosen

# However make will use the first pattern rule that can make the target
%.png: %.ps
	@echo this rule is not chosen if *.svg and *.ps are both present

# make already has some pattern rules built-in. For instance, it knows
# how to turn *.c files into *.o files.

# Older makefiles might use suffix rules instead of pattern rules
.png.ps:
	@echo this rule is similar to a pattern rule.

# Tell make about the suffix rule
.SUFFIXES: .png

#-----------------------------------------------------------------------
# Variables
#-----------------------------------------------------------------------
# aka. macros

# Variables are basically all string types

name = Ted
name2=&quot;Sarah&quot;

echo:
	@echo $(name)
	@echo ${name2}
	@echo $name    # This won&apos;t work, treated as $(n)ame.
	@echo $(name3) # Unknown variables are treated as empty strings.

# There are 4 places to set variables.
# In order of priority from highest to lowest:
# 1: commandline arguments
# 2: Makefile
# 3: shell environment variables - make imports these automatically.
# 4: make has some predefined variables

name4 ?= Jean
# Only set the variable if environment variable is not already defined.

override name5 = David
# Stops commandline arguments from changing this variable.

name4 +=grey
# Append values to variable (includes a space).

# Pattern-specific variable values (GNU extension).
echo: name2 = Sara # True within the matching rule
	# and also within its remade recursive dependencies
	# (except it can break when your graph gets too complicated!)

# Some variables defined automatically by make.
echo_inbuilt:
	echo $(CC)
	echo ${CXX}
	echo $(FC)
	echo ${CFLAGS}
	echo $(CPPFLAGS)
	echo ${CXXFLAGS}
	echo $(LDFLAGS)
	echo ${LDLIBS}

#-----------------------------------------------------------------------
# Variables 2
#-----------------------------------------------------------------------

# The first type of variables are evaluated each time they are used.
# This can be expensive, so a second type of variable exists which is
# only evaluated once. (This is a GNU make extension)

var := hello
var2 ::=  $(var) hello
#:= and ::= are equivalent.

# These variables are evaluated procedurally (in the order that they
# appear), thus breaking with the rest of the language !

# This doesn&apos;t work
var3 ::= $(var4) and good luck
var4 ::= good night

#-----------------------------------------------------------------------
# Functions
#-----------------------------------------------------------------------

# make has lots of functions available.

sourcefiles = $(wildcard *.c */*.c)
objectfiles = $(patsubst %.c,%.o,$(sourcefiles))

# Format is $(func arg0,arg1,arg2...)

# Some examples
ls:	* src/*
	@echo $(filter %.txt, $^)
	@echo $(notdir $^)
	@echo $(join $(dir $^),$(notdir $^))

#-----------------------------------------------------------------------
# Directives
#-----------------------------------------------------------------------

# Include other makefiles, useful for platform specific code
include foo.mk

sport = tennis
# Conditional compilation
report:
ifeq ($(sport),tennis)
	@echo &apos;game, set, match&apos;
else
	@echo &quot;They think it&apos;s all over; it is now&quot;
endif

# There are also ifneq, ifdef, ifndef

foo = true

ifdef $(foo)
bar = &apos;hello&apos;
endif
&lt;/code&gt;&lt;/pre&gt; 
&lt;hr&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;http://swcarpentry.github.io/make-novice/&quot;&gt;software carpentry tutorial&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;A more helpful makefile 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://jakemccrary.com/blog/2018/12/27/a-more-helpful-makefile/&quot;&gt;https://jakemccrary.com/blog/2018/12/27/a-more-helpful-makefile/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;A Super-Simple Makefile for Medium-Sized C/C++ Projects 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://spin.atomicobject.com/2016/08/26/makefile-c-projects/&quot;&gt;https://spin.atomicobject.com/2016/08/26/makefile-c-projects/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;A Tutorial on Portable Makefiles 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;http://nullprogram.com/blog/2017/08/20/&quot;&gt;http://nullprogram.com/blog/2017/08/20/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Makefile Tutorial 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://gist.github.com/isaacs/62a2d1825d04437c6f08&quot;&gt;https://gist.github.com/isaacs/62a2d1825d04437c6f08&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Notes for new Make users 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;http://gromnitsky.users.sourceforge.net/articles/notes-for-new-make-users/&quot;&gt;http://gromnitsky.users.sourceforge.net/articles/notes-for-new-make-users/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Propositions as Filenames, Builds as Proofs: The Essence of Make 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://bentnib.org/posts/2015-04-17-propositions-as-filenames-essence-of-make.html&quot;&gt;https://bentnib.org/posts/2015-04-17-propositions-as-filenames-essence-of-make.html&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Well documented Makefiles (available via &lt;code&gt;make help&lt;/code&gt;) 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://suva.sh/posts/well-documented-makefiles/&quot;&gt;https://suva.sh/posts/well-documented-makefiles/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;GNU Make&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;GNU Make - &lt;a href=&quot;http://www.gnu.org/software/make/&quot;&gt;http://www.gnu.org/software/make/&lt;/a&gt; 
  &lt;ul&gt; 
   &lt;li&gt;Manual - &lt;a href=&quot;https://www.gnu.org/software/make/manual/&quot;&gt;https://www.gnu.org/software/make/manual/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;An Empirical Analysis of GNU Make in Open Source Projects 
  &lt;ul&gt; 
   &lt;li&gt;2017 PhD Thesis; &lt;a href=&quot;http://research.cs.queensu.ca/~doug/research.html&quot;&gt;Douglas Martin&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://qspace.library.queensu.ca/handle/1974/15767&quot;&gt;https://qspace.library.queensu.ca/handle/1974/15767&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Makefile Corpus - &lt;a href=&quot;http://research.cs.queensu.ca/~doug/files/MakeEgs.tar.gz&quot;&gt;http://research.cs.queensu.ca/~doug/files/MakeEgs.tar.gz&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Makefile Framework - &lt;a href=&quot;http://research.cs.queensu.ca/~doug/files/MakeFramework.zip&quot;&gt;http://research.cs.queensu.ca/~doug/files/MakeFramework.zip&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;An Empirical Study of Unspecified Dependencies in Make-Based Build Systems 
  &lt;ul&gt; 
   &lt;li&gt;Empirical Software Engineering (2017)&lt;/li&gt; 
   &lt;li&gt;Cor-Paul Bezemer, Shane McIntosh, Bram Adams, Daniel M. German, Ahmed E. Hassan&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://doi.org/10.1007/s10664-017-9510-8&quot;&gt;https://doi.org/10.1007/s10664-017-9510-8&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://rebels.ece.mcgill.ca/journalpaper/2017/03/07/an-empirical-study-of-unspecified-dependencies-in-make-based-build-systems.html&quot;&gt;http://rebels.ece.mcgill.ca/journalpaper/2017/03/07/an-empirical-study-of-unspecified-dependencies-in-make-based-build-systems.html&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://sail.cs.queensu.ca/Downloads/EMSE2017_AnEmpiricalStudyOfUnspecifiedDependenciesInMake-BasedBuildSystems.pdf&quot;&gt;http://sail.cs.queensu.ca/Downloads/EMSE2017_AnEmpiricalStudyOfUnspecifiedDependenciesInMake-BasedBuildSystems.pdf&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Slides: &lt;a href=&quot;https://www.slideshare.net/corpaulbezemer/an-empirical-study-of-unspecified-dependencies-in-makebased-build-systems&quot;&gt;https://www.slideshare.net/corpaulbezemer/an-empirical-study-of-unspecified-dependencies-in-makebased-build-systems&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;GNU make - Paul D. Smith - &lt;a href=&quot;http://make.mad-scientist.net/&quot;&gt;http://make.mad-scientist.net/&lt;/a&gt; 
  &lt;ul&gt; 
   &lt;li&gt;Paul Smith&apos;s Rules of Makefiles - &lt;a href=&quot;http://make.mad-scientist.net/papers/rules-of-makefiles/&quot;&gt;http://make.mad-scientist.net/papers/rules-of-makefiles/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Deferred Simple Variable Expansion - &lt;a href=&quot;http://make.mad-scientist.net/deferred-simple-variable-expansion/&quot;&gt;http://make.mad-scientist.net/deferred-simple-variable-expansion/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;GNU Make articles - John Graham-Cumming 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;http://blog.jgc.org/2013/02/updated-list-of-my-gnu-make-articles.html&quot;&gt;http://blog.jgc.org/2013/02/updated-list-of-my-gnu-make-articles.html&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.cmcrossroads.com/keyword/type/3037?type=article&quot;&gt;https://www.cmcrossroads.com/keyword/type/3037?type=article&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.cmcrossroads.com/keyword/type/3169?type=article&quot;&gt;https://www.cmcrossroads.com/keyword/type/3169?type=article&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;GNU Make meets file names with spaces in them - &lt;a href=&quot;https://www.cmcrossroads.com/article/gnu-make-meets-file-names-spaces-them&quot;&gt;https://www.cmcrossroads.com/article/gnu-make-meets-file-names-spaces-them&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;GNU Make Standard Library - &lt;a href=&quot;http://gmsl.sourceforge.net/&quot;&gt;http://gmsl.sourceforge.net/&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;HOWTO: Intro to GNU make variables - &lt;a href=&quot;https://blog.melski.net/2015/01/07/howto-intro-to-gnu-make-variables/&quot;&gt;https://blog.melski.net/2015/01/07/howto-intro-to-gnu-make-variables/&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;Make is (probably) fine 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://blog.yossarian.net/2019/04/23/Make-is-probably-fine&quot;&gt;https://blog.yossarian.net/2019/04/23/Make-is-probably-fine&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Make it simple: An empirical analysis of GNU Make feature use in open source projects 
  &lt;ul&gt; 
   &lt;li&gt;International Conference on Program Comprehension 2015&lt;/li&gt; 
   &lt;li&gt;Douglas H Martin, James R Cordy, Bram Adams, Giulio Antoniol&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://maroon.cs.queensu.ca/home/cordy/Papers/MCAA_ICPC15_Makefiles.pdf&quot;&gt;http://maroon.cs.queensu.ca/home/cordy/Papers/MCAA_ICPC15_Makefiles.pdf&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Managing Projects with GNU Make 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;http://www.wanderinghorse.net/computing/make/&quot;&gt;http://www.wanderinghorse.net/computing/make/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://www.oreilly.com/openbook/make3/book/index.csp&quot;&gt;http://www.oreilly.com/openbook/make3/book/index.csp&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://notendur.hi.is/jonasson/software/make-book/&quot;&gt;https://notendur.hi.is/jonasson/software/make-book/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Properly using GNU-Make - &lt;a href=&quot;https://slashvar.github.io/2017/02/13/using-gnu-make.html&quot;&gt;https://slashvar.github.io/2017/02/13/using-gnu-make.html&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;Remake – GNU Make with comprehensible tracing and a debugger 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;http://bashdb.sourceforge.net/remake/&quot;&gt;http://bashdb.sourceforge.net/remake/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/rocky/remake&quot;&gt;https://github.com/rocky/remake&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;learn C the hard way &lt;a href=&quot;http://c.learncodethehardway.org/book/ex2.html&quot;&gt;ex2&lt;/a&gt; &lt;a href=&quot;http://c.learncodethehardway.org/book/ex28.html&quot;&gt;ex28&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;NMake&lt;/h4&gt; 
&lt;p&gt;&lt;a href=&quot;https://docs.microsoft.com/en-us/cpp/build/nmake-reference&quot;&gt;The Microsoft Program Maintenance Utility (NMAKE.EXE)&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Gradle</title>
      <link>https://tedneward.github.io/Research/tools/gradle/index/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/gradle/index/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://gradle.org/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/gradle/gradle&quot;&gt;Source&lt;/a&gt; | &lt;a href=&quot;https://plugins.gradle.org/&quot;&gt;Plugin Portal&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Docs: &lt;a href=&quot;https://docs.gradle.org/current/userguide/userguide.html&quot;&gt;User Guide&lt;/a&gt; | &lt;a href=&quot;https://docs.gradle.org/current/dsl/&quot;&gt;DSL Reference&lt;/a&gt; | &lt;a href=&quot;https://discuss.gradle.org/&quot;&gt;Forums&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://thoughts-on-cpp.com/2019/04/10/introduction-into-c-builds-with-gradle/&quot;&gt;Introduction into C++ Builds with Gradle&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://imperceptiblethoughts.com/shadow/introduction/&quot;&gt;Shadow plugin&lt;/a&gt;: &quot;Shadow is a Gradle plugin for combining a project&apos;s dependency classes and resources into a single output Jar. The combined Jar is often referred to a fat-jar or uber-jar. ... Shadowing a project output has 2 major use cases: (1) Creating an executable JAR distribution, &lt;a href=&quot;2&quot;&gt;and&lt;/a&gt; Bundling and relocating common dependencies in libraries to avoid classpath conflicts.&quot;&lt;/p&gt; 
&lt;h3&gt;Reading&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;http://spring.io/guides/gs/gradle/&quot;&gt;Building Java Projects with Gradle&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.syncfusion.com/ebooks/gradle_succinctly&quot;&gt;Gradle Succinctly&lt;/a&gt; - José Roberto Olivas Mendoza&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://docs.gradle.org/current/userguide/userguide.html&quot;&gt;Gradle User Guide&lt;/a&gt; - Hans Dockter, Adam Murdoch (&lt;a href=&quot;https://docs.gradle.org/current/userguide/userguide.pdf&quot;&gt;PDF&lt;/a&gt;)&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Notes&lt;/h3&gt; 
&lt;p&gt;Gradle uses a 1:1 relationship of a build script to a Project instance. Most &quot;magic&quot; comes from the use of plugins (listed below). Thus, the world&apos;s simplest Gradle build:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;// build.gradle.kts
println(&quot;Hello Gradle&quot;)
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;... when run with &lt;code&gt;gradle -b build.gradle.kts&lt;/code&gt;:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;~/Projects/Exploration.git/Gradle % gradle -b build.gradle.kts 

&amp;gt; Configure project :
Hello Gradle

&amp;gt; Task :help

Welcome to Gradle 8.10.

To run a build, run gradle &amp;lt;task&amp;gt; ...

To see a list of available tasks, run gradle tasks

To see more detail about a task, run gradle help --task &amp;lt;task&amp;gt;

To see a list of command-line options, run gradle --help

For more detail on using Gradle, see https://docs.gradle.org/8.10/userguide/command_line_interface.html

For troubleshooting, visit https://help.gradle.org

Deprecated Gradle features were used in this build, making it incompatible with Gradle 9.0.

You can use &apos;--warning-mode all&apos; to show the individual deprecation warnings and determine if they come from your own scripts or plugins.

For more on this, please refer to https://docs.gradle.org/8.10/userguide/command_line_interface.html#sec:command_line_warnings in the Gradle documentation.

BUILD SUCCESSFUL in 843ms
1 actionable task: 1 executed
&lt;/code&gt;&lt;/pre&gt; 
&lt;h2&gt;Common tasks&lt;/h2&gt; 
&lt;h3&gt;Execute &quot;run&quot; with command-line arguments&lt;/h3&gt; 
&lt;p&gt;&lt;code&gt;gradle run --args=&quot;one two three \&quot;four is a collection of words\&quot; five&quot;&lt;/code&gt; (must have all arguments in a single double-quoted string)&lt;/p&gt; 
&lt;h2&gt;Customizing&lt;/h2&gt; 
&lt;h3&gt;Keyword Expansion&lt;/h3&gt; 
&lt;p&gt;Found in Chapter 1 of &lt;em&gt;Gradle Beyond the Basics&lt;/em&gt; (OReilly, Tim Berglund)&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;// I think this is Groovy syntax
versionId = &apos;1.6&apos;

task copyProductionConfig(type: Copy) {
  from &apos;source&apos;
  include &apos;config.properties&apos;
  into &apos;build/war/WEB-INF/config&apos;
  expand([
    databaseHostname: &apos;db.company.com&apos;,
    version: versionId,
    buildNumber: (int)(Math.random() * 1000),
    date: new Date()
  ])
}
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;This will replace placeholders like the following:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;#
# Application configuration file
#
hostname: ${databaseHostname}
appVersion: ${version}
locale: en_us
initialConnections: 10
transferThrottle: 5400
queueTimeout: 30000
buildNumber: ${buildNumber}
buildDate: ${date.format(&quot;yyyyMMdd&apos;T&apos;HHmmssZ&quot;)}
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;Custom Task inside the build script&lt;/h3&gt; 
&lt;p&gt;Wrote a custom task that invokes &lt;code&gt;javap&lt;/code&gt; on compiled class files (&lt;a href=&quot;https://github.com/tedneward/Demo-JVM-Bytecode/blob/main/JavaExamples/app/build.gradle.kts&quot;&gt;here&lt;/a&gt;):&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;open class Javap: DefaultTask() {
    @Internal var workingDir = &quot;./build/classes/java/main&quot;
    @Internal var outputDir: String = &quot;&quot;
    @Internal lateinit var classFiles: List&amp;lt;String&amp;gt;
    @Internal lateinit var javapArguments: List&amp;lt;String&amp;gt;
    @Internal var projectDir = project.projectDir

    @TaskAction
    fun runCommand() {
        logger.warn(&quot;Running &apos;disasm&apos; replaces the marked javap files with newly-generated content!&quot;)
        for (classFile in classFiles) {
            val commandLine = (&quot;javap &quot; + javapArguments.joinToString(&quot; &quot;) + &quot; &quot; + classFile)
            try {
                val workingDir = File(projectDir, workingDir)
                val outputDir = File(projectDir, outputDir)
                val parts = commandLine.split(&quot;\\s&quot;.toRegex())
                // Transform the classFile string/path to a dotted name
                val dottedClassFile = classFile.split(&quot;/&quot;).joinToString(&quot;.&quot;)
                val outputFile = File(outputDir, dottedClassFile + &quot;.bytecode&quot;)
                val proc = ProcessBuilder(*parts.toTypedArray())
                        .directory(workingDir)
                        .redirectOutput(outputFile)
                        .redirectError(ProcessBuilder.Redirect.PIPE)
                        .start()

                proc.waitFor(60, TimeUnit.MINUTES)
                println(&quot;Success processing ${classFile}&quot;)
            } catch(e: Exception) {
                e.printStackTrace()
                println(&quot;Failure processing ${classFile}: ${e.message}&quot;)
            }
        }
    }
}

tasks.register&amp;lt;Javap&amp;gt;(&quot;disasm&quot;) {
    group = &quot;build&quot;
    description = &quot;Produce disassembly listings of Java code&quot;
    javapArguments = listOf(&quot;-v&quot;)
    outputDir = &quot;&quot;
    classFiles = listOf(
        &quot;com/newardassociates/demo/App.class&quot;,
        &quot;com/newardassociates/demo/Greeter.class&quot;,
        &quot;com/newardassociates/demo/Math.class&quot;,
        &quot;com/newardassociates/demo/Outer.class&quot;,
        &quot;com/newardassociates/demo/Outer\$Inner.class&quot;,
        &quot;com/newardassociates/demo/StringConcat.class&quot;,
        &quot;com/newardassociates/demo/Varargs.class&quot;,
    )
    dependsOn(&quot;compileJava&quot;)
}
&lt;/code&gt;&lt;/pre&gt; 
&lt;ul&gt; 
 &lt;li&gt;@TaskAction definitely is the magic to make Gradle invoke the task&lt;/li&gt; 
 &lt;li&gt;@Internal is required on the properties inside the task--Gradle apparently really wants to know whether it&apos;s an input, output, or internal property. I still need to figure out input and output properties on a custom task.&lt;/li&gt; 
 &lt;li&gt;I think &lt;code&gt;group&lt;/code&gt; and &lt;code&gt;description&lt;/code&gt; are inherited from &lt;code&gt;DefaultTask&lt;/code&gt;, so I should probably figure out how to pass those in a constructor or something&lt;/li&gt; 
 &lt;li&gt;There&apos;s probably a better way of dealing with multiple files, but this was sufficient for the Bytecode demos project.&lt;/li&gt; 
 &lt;li&gt;I should probably move those &quot;println&quot; statements over to use the logger instead&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Custom Task compiled as part of the build&lt;/h3&gt; 
&lt;h3&gt;Custom Task in a standalone JAR&lt;/h3&gt; 
&lt;hr&gt; 
&lt;h2&gt;Boilerplates&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/nenick/android-gradle-template&quot;&gt;android-gradle-template&lt;/a&gt; - Template project for developing Android app.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/vert-x/vertx-gradle-template&quot;&gt;vertx-gradle-template&lt;/a&gt; - Template project for developing Vert.x module.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/int128/gradle-plugin-starter&quot;&gt;gradle-plugin-starter&lt;/a&gt; - Template project for developing Gradle plugin.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/RallySoftware/gatling-with-gradle&quot;&gt;gatling-with-gradle&lt;/a&gt; - Sample project that demonstrates how to automate load testing with &lt;a href=&quot;http://gatling.io/&quot;&gt;Gatling&lt;/a&gt;.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Resources&lt;/h2&gt;
	</description>
    </item>
    <item>
      <title>GrimoireLab</title>
      <link>https://tedneward.github.io/Research/tools/grimoirelab/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/grimoirelab/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://chaoss.github.io/grimoirelab/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;http://github.com/chaoss/grimoirelab&quot;&gt;Source&lt;/a&gt; | &lt;a href=&quot;https://chaoss.github.io/grimoirelab-tutorial/&quot;&gt;Tutorial&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;GrimoireLab is a CHAOSS toolset for software development analytics. It includes a coordinated set of tools to retrieve data from systems used to support software development (repositories), store it in databases, enrich it by computing relevant metrics, and make it easy to run analytics and visualizations on it.&lt;/p&gt; 
&lt;p&gt;Currently, GrimoireLab toolkit is organized in the following repositories:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Data retrieval related components: 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/chaoss/grimoirelab-perceval&quot;&gt;Perceval&lt;/a&gt;: retrieval of data from data sources 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://github.com/chaoss/grimoirelab-perceval-opnfv&quot;&gt;Perceval (bundle for OPNFV)&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://github.com/chaoss/grimoirelab-perceval-mozilla&quot;&gt;Perceval (bundle for Mozilla)&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://github.com/chaoss/grimoirelab-perceval-puppet&quot;&gt;Perceval (bundle for Puppet)&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://github.com/chaoss/grimoirelab-perceval-weblate&quot;&gt;Perceval (bundle for Weblate)&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/chaoss/grimoirelab-graal&quot;&gt;Graal&lt;/a&gt;: source data analysis with external tools&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/chaoss/grimoirelab-kingarthur&quot;&gt;KingArthur&lt;/a&gt;: batch processing for massive retrieval&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Data enrichment related components: 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/chaoss/grimoirelab-elk&quot;&gt;GrimoireElk&lt;/a&gt;: storage and enrichment of data&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/chaoss/grimoirelab-cereslib&quot;&gt;Cereslib&lt;/a&gt;: generic data processor&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/chaoss/grimoirelab-sortinghat&quot;&gt;SortingHat&lt;/a&gt;: identity management&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Data consumption related components: 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/chaoss/grimoirelab-sigils&quot;&gt;Sigils&lt;/a&gt;: visualizations and dashboards&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/chaoss/grimoirelab-kidash&quot;&gt;Kidash&lt;/a&gt;: visualizations and dashboards manager&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/chaoss/grimoirelab-manuscripts&quot;&gt;Manuscripts&lt;/a&gt;: reporting&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Platform management, orchestration, and common utils: 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/chaoss/grimoirelab-mordred&quot;&gt;Mordred&lt;/a&gt;: orchestration&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/chaoss/grimoirelab-toolkit&quot;&gt;GrimoireLab Toolkit&lt;/a&gt;: common utilities&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Hevea</title>
      <link>https://tedneward.github.io/Research/tools/hevea/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/hevea/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://hevea.inria.fr/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/maranget/hevea&quot;&gt;Source&lt;/a&gt; | &lt;a href=&quot;https://hevea.inria.fr/distri/hevea-2.37-manual.pdf&quot;&gt;Docs&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Homebrew (Linuxbrew)</title>
      <link>https://tedneward.github.io/Research/tools/homebrew/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/homebrew/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://brew.sh/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/Homebrew/brew&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Install script: &lt;code&gt;/bin/bash -c &quot;$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)&quot;&lt;/code&gt;&lt;/p&gt; 
&lt;h2&gt;Notes&lt;/h2&gt; 
&lt;p&gt;Generate a Brewfile (all the Homebrew-installed packages) by running:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;brew bundle dump --force
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;&lt;code&gt;brew bundle dump&lt;/code&gt; also includes installed VS Code extensions!&lt;/p&gt; 
&lt;p&gt;Install everything in the Brewfile by running:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;brew bundle install --file=./Brewfile
&lt;/code&gt;&lt;/pre&gt;
	</description>
    </item>
    <item>
      <title>Huginn</title>
      <link>https://tedneward.github.io/Research/tools/huginn/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/huginn/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/huginn&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;h2&gt;Reading&lt;/h2&gt; 
&lt;h3&gt;Articles&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.xda-developers.com/huginn-free-open-source-ifttt-alternative/&quot;&gt;&quot;Huginn is a free, open-source IFTTT alternative that&apos;s much more powerful&quot;&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>IKOS (Inference Kernel for Open Static Analyzers)</title>
      <link>https://tedneward.github.io/Research/tools/ikos/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/ikos/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/NASA-SW-VnV/ikos&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>ImHex</title>
      <link>https://tedneward.github.io/Research/tools/imhex/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/imhex/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://imhex.werwolv.net/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/WerWolv/ImHex&quot;&gt;Source&lt;/a&gt; | &lt;a href=&quot;https://imhex.werwolv.net/docs/&quot;&gt;Pattern Language Docs&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>JaCoCo (Java Code Coverage)</title>
      <link>https://tedneward.github.io/Research/tools/jacoco/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/jacoco/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.jacoco.org/jacoco/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/jacoco/jacoco/&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;h2&gt;Reading&lt;/h2&gt; 
&lt;h3&gt;Articles&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://blog.picnic.nl/how-to-find-dead-code-in-your-java-services-d167c8f22838&quot;&gt;https://blog.picnic.nl/how-to-find-dead-code-in-your-java-services-d167c8f22838&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Java Decompiler</title>
      <link>https://tedneward.github.io/Research/tools/java-decompiler/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/java-decompiler/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://java-decompiler.github.io/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/java-decompiler&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Features:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;JD-Core and JD-GUI are written in Java.&lt;/li&gt; 
 &lt;li&gt;JD-Core works with most current compilers including the following: 
  &lt;ul&gt; 
   &lt;li&gt;JDK 1.1.8, JDK 1.3.1, JDK 1.4.2, JDK 1.5.0, JDK 1.6.0, JDK 1.7.0, JDK 1.8.0, JDK 9.0.1, JDK 10.0.2&lt;/li&gt; 
   &lt;li&gt;jrockit90_150_06&lt;/li&gt; 
   &lt;li&gt;jikes-1.22&lt;/li&gt; 
   &lt;li&gt;harmony-jdk-r533500&lt;/li&gt; 
   &lt;li&gt;Eclipse Java Compiler v_677_R32x, 3.2.1 release&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;JD-GUI supports Drag and Drop.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt;JD-GUI supports CLASS, JAR, WAR, EAR, AAR, KAR, JMOD &amp;amp; ZIP files.&lt;/li&gt; 
 &lt;li&gt;JD-GUI displays color coded Java source code.&lt;/li&gt; 
 &lt;li&gt;JD-GUI allows you to browse the CLASS files and Java modules hierarchy.&lt;/li&gt; 
 &lt;li&gt;JD-GUI lets you drag and drop LOG files, decompile CLASS files, and display the line of code that appears in Java stack traces.&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>jcpp</title>
      <link>https://tedneward.github.io/Research/tools/jcpp/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/jcpp/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/shevek/jcpp&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>JFlex</title>
      <link>https://tedneward.github.io/Research/tools/jflex/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/jflex/index.html</guid>
      	<description>
	&lt;p&gt;&quot;A lexical analyzer generator takes as input a specification with a set of regular expressions and corresponding actions. It generates a program (a lexer) that reads input, matches the input against the regular expressions in the spec file, and runs the corresponding action if a regular expression matched. Lexers usually are the first front-end step in compilers, matching keywords, comments, operators, etc, and generating an input token stream for parsers. Lexers can also be used for many other purposes.&lt;/p&gt; 
&lt;p&gt;&quot;JFlex lexers are based on deterministic finite automata (DFAs). They are fast, without expensive backtracking.&lt;/p&gt; 
&lt;p&gt;&quot;JFlex is designed to work together with the LALR parser generator CUP by Scott Hudson, and the Java modification of Berkeley Yacc BYacc/J by Bob Jamison. It can also be used together with other parser generators like ANTLR or as a standalone tool.&quot;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://jflex.de/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/jflex-de/&quot;&gt;Github&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>jrnl</title>
      <link>https://tedneward.github.io/Research/tools/jrnl/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/jrnl/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://jrnl.sh/en/stable/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/jrnl-org/jrnl&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Command-line composing and viewing of a &quot;journal file&quot; or files, which may be encrypted if desired.&lt;/p&gt; 
&lt;p&gt;Config file default is &lt;code&gt;$HOME/.config/jrnl/jrnl.yaml&lt;/code&gt; (macOS) or &lt;code&gt;%USERPROFILE%\.config\jrnl\jrnl.yaml&lt;/code&gt; (Windows).&lt;/p&gt; 
&lt;h1&gt;Basic usage&lt;/h1&gt; 
&lt;p&gt;&lt;em&gt;(from the GitHub documentation page)&lt;/em&gt;&lt;/p&gt; 
&lt;p&gt;&lt;code&gt;jrnl&lt;/code&gt; has two modes: &lt;strong&gt;composing&lt;/strong&gt; and &lt;strong&gt;viewing&lt;/strong&gt;. Whenever you don&apos;t enter any arguments that start with a dash (&lt;code&gt;-&lt;/code&gt;) or double-dash (&lt;code&gt;--&lt;/code&gt;), you&apos;re in composing mode, meaning that you can write your entry on the command line.&lt;/p&gt; 
&lt;p&gt;We intentionally break a convention on command line arguments: all arguments starting with a &lt;em&gt;single dash&lt;/em&gt; (&lt;code&gt;-&lt;/code&gt;) will &lt;em&gt;filter&lt;/em&gt; your journal before viewing it. Filter arguments can be combined arbitrarily. Arguments with a &lt;em&gt;double dash&lt;/em&gt; (&lt;code&gt;--&lt;/code&gt;) will &lt;em&gt;control&lt;/em&gt; how your journal is displayed or exported. Control arguments are mutually exclusive (i.e., you can only specify one way to display or export your journal at a time).&lt;/p&gt; 
&lt;p&gt;For a list of commands, enter &lt;code&gt;jrnl --help&lt;/code&gt;.&lt;/p&gt; 
&lt;h2&gt;Composing Entries&lt;/h2&gt; 
&lt;p&gt;Composing mode is entered by either starting &lt;code&gt;jrnl&lt;/code&gt; without any arguments -- which will launch an external editor -- or by just writing an entry on the command line:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;jrnl today at 3am: I just met Steve Buscemi in a bar! What a nice guy.
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;!!! note&lt;br&gt; Most shells contain a certain number of reserved characters, such as &lt;code&gt;#&lt;/code&gt; and&lt;br&gt; &lt;code&gt;*&lt;/code&gt;. These characters, as well as unbalanced single or double quotation&lt;br&gt; marks, parentheses, and others, likely will cause problems. Although&lt;br&gt; reserved characters can be escaped using &lt;code&gt;\&lt;/code&gt;, this is not ideal for&lt;br&gt; long-form writing. The solution: first enter &lt;code&gt;jrnl&lt;/code&gt; and hit &lt;code&gt;return&lt;/code&gt;. You&lt;br&gt; can then enter the text of your journal entry. Alternatively, you can &lt;a href=&quot;./advanced.md&quot;&gt;use&lt;br&gt; an external editor&lt;/a&gt;.&lt;/p&gt; 
&lt;p&gt;You can also import an entry directly from a file:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;jrnl &amp;lt; my_entry.txt
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;Specifying Date and Time&lt;/h3&gt; 
&lt;p&gt;If you don&apos;t specify a date and time (e.g., &lt;code&gt;jrnl finished writing letter to brother&lt;/code&gt;), &lt;code&gt;jrnl&lt;/code&gt; will create an entry using the current date and time. For retrospective entries, you can use a timestamp to tell &lt;code&gt;jrnl&lt;/code&gt; where to put the entry. Timestamps can be entered using a variety of formats. Here are some that work:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;at 6am&lt;/li&gt; 
 &lt;li&gt;yesterday&lt;/li&gt; 
 &lt;li&gt;last monday&lt;/li&gt; 
 &lt;li&gt;sunday at noon&lt;/li&gt; 
 &lt;li&gt;2 march 2012&lt;/li&gt; 
 &lt;li&gt;7 apr&lt;/li&gt; 
 &lt;li&gt;5/20/1998 at 23:42&lt;/li&gt; 
 &lt;li&gt;2020-05-22T15:55-04:00&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;If you don&apos;t use a timestamp, &lt;code&gt;jrnl&lt;/code&gt; will create an entry using the current time. If you use a date only (no time), &lt;code&gt;jrnl&lt;/code&gt; will use the default time specified in your &lt;a href=&quot;./reference-config-file.md#default_hour-and-default_minute&quot;&gt;configuration file&lt;/a&gt;. Behind the scenes, &lt;code&gt;jrnl&lt;/code&gt; reorganizes entries in chronological order.&lt;/p&gt; 
&lt;h3&gt;Using Tags&lt;/h3&gt; 
&lt;p&gt;&lt;code&gt;jrnl&lt;/code&gt; supports tags. The default tag symbol is &lt;code&gt;@&lt;/code&gt; (largely because &lt;code&gt;#&lt;/code&gt; is a reserved character). You can specify your own tag symbol in the &lt;a href=&quot;./reference-config-file.md#tagsymbols&quot;&gt;configuration file&lt;/a&gt;. To use tags, preface the desired tag with the symbol:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;jrnl Had a wonderful day at the @beach with @Tom and @Anna.
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Although you can use capitals while tagging an entry, searches by tag are case-insensitive.&lt;/p&gt; 
&lt;p&gt;There is no limit to how many tags you can use in an entry.&lt;/p&gt; 
&lt;h3&gt;Starring Entries&lt;/h3&gt; 
&lt;p&gt;To mark an entry as a favorite, simply &quot;star&quot; it using an asterisk (&lt;code&gt;*&lt;/code&gt;):&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;jrnl last sunday *: Best day of my life.
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;If you don&apos;t want to add a date (i.e., you want the date to be entered as &lt;em&gt;now&lt;/em&gt;), the following options are equivalent:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;code&gt;jrnl *: Best day of my life.&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;jrnl *Best day of my life.&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;jrnl Best day of my life.*&lt;/code&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;!!! note&lt;br&gt; Make sure that the asterisk (&lt;code&gt;*&lt;/code&gt;) is &lt;strong&gt;not&lt;/strong&gt; surrounded by whitespaces.&lt;br&gt; &lt;code&gt;jrnl Best day of my life! *&lt;/code&gt; will not work because the &lt;code&gt;*&lt;/code&gt; character has a&lt;br&gt; special meaning in most shells.&lt;/p&gt; 
&lt;h2&gt;Viewing and Searching Entries&lt;/h2&gt; 
&lt;p&gt;&lt;code&gt;jrnl&lt;/code&gt; can display entries in a variety of ways.&lt;/p&gt; 
&lt;p&gt;To view all entries, enter:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;jrnl -to today
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;&lt;code&gt;jrnl&lt;/code&gt; provides several filtering commands, prefaced by a single dash (&lt;code&gt;-&lt;/code&gt;), that allow you to find a more specific range of entries. For example,&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;jrnl -n 10
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;lists the ten most recent entries. &lt;code&gt;jrnl -10&lt;/code&gt; is even more concise and works the same way. If you want to see all of the entries you wrote from the beginning of last year until the end of this past March, you would enter&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;jrnl -from &quot;last year&quot; -to march
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Filter criteria that use more than one word require surrounding quotes (&lt;code&gt;&quot;&quot;&lt;/code&gt;).&lt;/p&gt; 
&lt;p&gt;To see entries on a particular date, use &lt;code&gt;-on&lt;/code&gt;:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;jrnl -on yesterday
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;Text Search&lt;/h3&gt; 
&lt;p&gt;The &lt;code&gt;-contains&lt;/code&gt; command displays all entries containing the text you enter after it. This may be helpful when you&apos;re searching for entries and you can&apos;t remember if you tagged any words when you wrote them.&lt;/p&gt; 
&lt;p&gt;You may realize that you use a word a lot and want to turn it into a tag in all&lt;br&gt; of your previous entries.&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;jrnl -contains &quot;dogs&quot; --edit
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;opens your external editor so that you can add a tag symbol (&lt;code&gt;@&lt;/code&gt; by default) to all instances of the word &quot;dogs.&quot;&lt;/p&gt; 
&lt;h3&gt;Filtering by Tag&lt;/h3&gt; 
&lt;p&gt;You can filter your journal entries by tag. For example,&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;jrnl @pinkie @WorldDomination
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;displays all entries in which either &lt;code&gt;@pinkie&lt;/code&gt; or &lt;code&gt;@WorldDomination&lt;/code&gt; occurred. Tag filters can be combined with other filters:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;jrnl -n 5 @pinkie -and @WorldDomination
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;displays the last five entries containing &lt;em&gt;both&lt;/em&gt; &lt;code&gt;@pinkie&lt;/code&gt; &lt;em&gt;and&lt;/em&gt; &lt;code&gt;@worldDomination&lt;/code&gt;. You can change which symbols you&apos;d like to use for tagging in the &lt;a href=&quot;./reference-config-file.md#tagsymbols&quot;&gt;configuration file&lt;/a&gt;.&lt;/p&gt; 
&lt;p&gt;!!! note&lt;br&gt; Entering &lt;code&gt;jrnl @pinkie @WorldDomination&lt;/code&gt; will display entries in which both&lt;br&gt; tags are present because, although no command line arguments are given, all&lt;br&gt; of the input strings look like tags. &lt;code&gt;jrnl&lt;/code&gt; will assume you want to filter&lt;br&gt; by tag, rather than create a new entry that consists only of tags.&lt;/p&gt; 
&lt;p&gt;To view a list of all tags in the journal, enter:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;jrnl --tags
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;Viewing Starred Entries&lt;/h3&gt; 
&lt;p&gt;To display only your favorite (starred) entries, enter&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;jrnl -starred
&lt;/code&gt;&lt;/pre&gt; 
&lt;h2&gt;Editing Entries&lt;/h2&gt; 
&lt;p&gt;You can edit entries after writing them. This is particularly useful when your journal file is encrypted. To use this feature, you need to have an external editor configured in your &lt;a href=&quot;./reference-config-file.md#editor&quot;&gt;configuration file&lt;/a&gt;. You can also edit only the entries that match specific search criteria. For example,&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;jrnl -to 1950 @texas -and @history --edit
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;opens your external editor displaying all entries tagged with &lt;code&gt;@texas&lt;/code&gt; and &lt;code&gt;@history&lt;/code&gt; that were written before 1950. After making changes, save and close the file, and only those entries will be modified (and encrypted, if applicable).&lt;/p&gt; 
&lt;p&gt;If you are using multiple journals, it&apos;s easy to edit specific entries from specific journals. Simply prefix the filter string with the name of the journal. For example,&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;jrnl work -n 1 --edit
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;opens the most recent entry in the &apos;work&apos; journal in your external editor.&lt;/p&gt; 
&lt;h2&gt;Deleting Entries&lt;/h2&gt; 
&lt;p&gt;The &lt;code&gt;--delete&lt;/code&gt; command opens an interactive interface for deleting entries. The date and title of each entry in the journal are presented one at a time, and you can choose whether to keep or delete each entry.&lt;/p&gt; 
&lt;p&gt;If no filters are specified, &lt;code&gt;jrnl&lt;/code&gt; will ask you to keep or delete each entry in the entire journal, one by one. If there are a lot of entries in the journal, it may be more efficient to filter entries before passing the &lt;code&gt;--delete&lt;/code&gt; command.&lt;/p&gt; 
&lt;p&gt;Here&apos;s an example. Say you have a journal into which you&apos;ve imported the last 12 years of blog posts. You use the &lt;code&gt;@book&lt;/code&gt; tag a lot, and for some reason you want to delete some, but not all, of the entries in which you used that tag, but only the ones you wrote at some point in 2004 or earlier. You&apos;re not sure which entries you want to keep, and you want to look through them before deciding. This is what you might enter:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;jrnl -to 2004 @book --delete
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;&lt;code&gt;jrnl&lt;/code&gt; will show you only the relevant entries, and you can choose the ones you want to delete.&lt;/p&gt; 
&lt;p&gt;You may want to delete &lt;em&gt;all&lt;/em&gt; of the entries containing &lt;code&gt;@book&lt;/code&gt; that you wrote in 2004 or earlier. If there are dozens or hundreds, the easiest way would be to use an external editor. Open an editor with the entries you want to delete...&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;jrnl -to 2004 @book --edit
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;...select everything, delete it, save and close, and all of those entries are removed from the journal.&lt;/p&gt; 
&lt;h2&gt;Listing Journals&lt;/h2&gt; 
&lt;p&gt;To list all of your journals:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;jrnl --list
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;The journals displayed correspond to those specified in the &lt;code&gt;jrnl&lt;/code&gt; &lt;a href=&quot;./reference-config-file.md#journals&quot;&gt;configuration file&lt;/a&gt;.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Kapersky Rescue Disk</title>
      <link>https://tedneward.github.io/Research/tools/kapersky-rescue-disk/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/kapersky-rescue-disk/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.kaspersky.co.in/downloads/free-rescue-disk&quot;&gt;Download&lt;/a&gt; but this URL doesn&apos;t seem to display anything?&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Krakatau</title>
      <link>https://tedneward.github.io/Research/tools/krakatau/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/krakatau/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/Storyyeller/Krakatau&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Ledger</title>
      <link>https://tedneward.github.io/Research/tools/ledger/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/ledger/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://ledger-cli.org/index.html&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://git.ledger-cli.org/ledger&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>LitmusKt</title>
      <link>https://tedneward.github.io/Research/tools/litmuskt/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/litmuskt/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/Jetbrains-Research/litmuskt&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;h2&gt;Reading&lt;/h2&gt; 
&lt;h3&gt;Articles/Papers&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://blog.jetbrains.com/research/2025/10/litmuskt-concurrency-testing/&quot;&gt;Finding Order in the Mayhem: A Novel Concurrency Testing Tool that Improved the Kotlin Compiler&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://media.githubusercontent.com/media/anlun/publicFiles/master/papers/Moiseenko-al-Programming21-full.pdf&quot;&gt;A Survey of Programming Language Memory Models&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>LMStudio</title>
      <link>https://tedneward.github.io/Research/tools/lmstudio/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/lmstudio/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://lmstudio.ai/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/lmstudio-ai/lms&quot;&gt;Source&lt;/a&gt; | &lt;a href=&quot;https://lmstudio.ai/docs/developer&quot;&gt;Docs&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>GNU stow</title>
      <link>https://tedneward.github.io/Research/tools/gnu/stow/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/gnu/stow/index.html</guid>
      	<description>
	&lt;h2&gt;Articles&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://tamerlan.dev/how-i-manage-my-dotfiles-using-gnu-stow/&quot;&gt;How I manage my dotfiles using GNU stow&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Gradle plugins</title>
      <link>https://tedneward.github.io/Research/tools/gradle/plugins/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/gradle/plugins/index.html</guid>
      	<description>
	&lt;blockquote&gt; 
 &lt;p&gt;&quot;Official plugin&quot; means that it&apos;s provided as a builtin plugin by Gradle.&lt;/p&gt; 
&lt;/blockquote&gt; 
&lt;h3&gt;Language&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://docs.gradle.org/current/userguide/java_plugin.html&quot;&gt;java&lt;/a&gt; - Official plugin that adds Java compilation, testing and bundling capabilities.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://docs.gradle.org/current/userguide/groovy_plugin.html&quot;&gt;groovy&lt;/a&gt; - Official plugin that adds support for building Groovy projects.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://docs.gradle.org/current/userguide/scala_plugin.html&quot;&gt;scala&lt;/a&gt; - Official plugin that adds support for building Scala projects.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://docs.gradle.org/current/userguide/antlr_plugin.html&quot;&gt;antlr&lt;/a&gt; - Official plugin that adds support for generating parsers using &lt;a href=&quot;http://www.antlr.org/&quot;&gt;Antlr&lt;/a&gt;.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://docs.gradle.org/current/userguide/native_software.html&quot;&gt;assembler&lt;/a&gt; - Official plugin that adds native assembly language capabilities to a project.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://docs.gradle.org/current/userguide/native_software.html&quot;&gt;c&lt;/a&gt; - Official plugin that adds C source compilation capabilities to a project.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://docs.gradle.org/current/userguide/native_software.html&quot;&gt;cpp&lt;/a&gt; - Official plugin that adds C++ source compilation capabilities to a project.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://docs.gradle.org/current/userguide/native_software.html&quot;&gt;objective-c&lt;/a&gt; - Official plugin that adds Objective-C source compilation capabilities to a project.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://docs.gradle.org/current/userguide/native_software.html&quot;&gt;objective-cpp&lt;/a&gt; - Official plugin that adds Objective-C++ source compilation capabilities to a project.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/evant/gradle-retrolambda&quot;&gt;gradle-retrolambda&lt;/a&gt; - Get Java lambda support in Java 6, 7 and Android.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/clojurephant/clojurephant&quot;&gt;clojurephant&lt;/a&gt; - Clojure/ClojureScript support for Gradle&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Code quality&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://docs.gradle.org/current/userguide/findbugs_plugin.html&quot;&gt;findbugs&lt;/a&gt; - Official plugin that performs quality checks on Java source files using &lt;a href=&quot;http://findbugs.sourceforge.net/&quot;&gt;FindBugs&lt;/a&gt;.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://plugins.gradle.org/plugin/com.github.spotbugs&quot;&gt;spotbugs&lt;/a&gt; - Official plugin that performs quality checks on Java source files using &lt;a href=&quot;https://spotbugs.github.io/&quot;&gt;SpotBugs&lt;/a&gt;.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://docs.gradle.org/current/userguide/checkstyle_plugin.html&quot;&gt;checkstyle&lt;/a&gt; - Official plugin that performs quality checks on Java source files using &lt;a href=&quot;http://checkstyle.sourceforge.net/index.html&quot;&gt;Checkstyle&lt;/a&gt;.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/diffplug/spotless/tree/master/plugin-gradle&quot;&gt;spotless&lt;/a&gt; - Checks and applies formatting rules using the Eclipse, google-java-format, ktlint, scalafmt, and also user-defined rules.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://docs.gradle.org/current/userguide/pmd_plugin.html&quot;&gt;pmd&lt;/a&gt; - Official plugin that performs quality checks on your project&apos;s Java source files using &lt;a href=&quot;http://pmd.sourceforge.net/&quot;&gt;PMD&lt;/a&gt;.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://docs.gradle.org/current/userguide/jdepend_plugin.html&quot;&gt;jdepend&lt;/a&gt; - Official plugin that performs quality checks on your project&apos;s source files using &lt;a href=&quot;http://clarkware.com/software/JDepend.html&quot;&gt;JDepend&lt;/a&gt;.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://docs.gradle.org/current/userguide/codenarc_plugin.html&quot;&gt;codenarc&lt;/a&gt; - Official plugin that Performs quality checks on Groovy source files using &lt;a href=&quot;http://codenarc.sourceforge.net/index.html&quot;&gt;CodeNarc&lt;/a&gt;.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://docs.gradle.org/current/userguide/jacoco_plugin.html&quot;&gt;jacoco&lt;/a&gt; - Official plugin that provides integration with the &lt;a href=&quot;http://www.eclemma.org/jacoco/&quot;&gt;JaCoCo&lt;/a&gt; code coverage library for Java.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/stevesaliman/gradle-cobertura-plugin&quot;&gt;gradle-cobertura-plugin&lt;/a&gt; - Use cobertura.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/kt3k/coveralls-gradle-plugin&quot;&gt;coveralls-gradle-plugin&lt;/a&gt; - Send coverage data to &lt;a href=&quot;https://coveralls.io/&quot;&gt;coveralls.io&lt;/a&gt;.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/scoverage/gradle-scoverage&quot;&gt;gradle-scoverage&lt;/a&gt; - Enable the use of Scoverage in a Gradle Scala project.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/tbroyer/gradle-errorprone-plugin&quot;&gt;gradle-errorprone-plugin&lt;/a&gt; - Use the &lt;a href=&quot;https://github.com/google/error-prone&quot;&gt;error-prone&lt;/a&gt; compiler for Java.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/ksoichiro/gradle-spelling-plugin&quot;&gt;gradle-spelling-plugin&lt;/a&gt; - Inspect spelling using custom blacklist.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/simonharrer/gradle-modernizer-plugin&quot;&gt;gradle-modernizer-plugin&lt;/a&gt; - Detect uses of legacy Java APIs.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Code generation&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/tcawley/gradle-protobuf-plugin&quot;&gt;gradle-protobuf-plugin&lt;/a&gt; - Compile &lt;a href=&quot;https://developers.google.com/protocol-buffers/&quot;&gt;Google Protocol Buffers&lt;/a&gt; files.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/ewerk/gradle-plugins/tree/master/querydsl-plugin&quot;&gt;querydsl-plugin&lt;/a&gt; - Generate &lt;a href=&quot;http://www.querydsl.com/&quot;&gt;Querydsl&lt;/a&gt; classes.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Java application development&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/tbroyer/gradle-apt-plugin&quot;&gt;gradle-apt-plugin&lt;/a&gt; - Make it easier/safer to use Java annotation processors.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/darylteo/vertx-gradle-plugin&quot;&gt;vertx-gradle-plugin&lt;/a&gt; - Unofficial plugin for starting Vert.x projects.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Web application development&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;http://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#build-tool-plugins-gradle-plugin&quot;&gt;spring-boot&lt;/a&gt; - Provide Spring Boot support.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/akhikhl/gretty&quot;&gt;gretty&lt;/a&gt; - Run web apps on jetty and tomcat.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/bmuschko/gradle-tomcat-plugin&quot;&gt;gradle-tomcat-plugin&lt;/a&gt; - Support deployment of your web application to an embedded Tomcat web container.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/zeroturnaround/gradle-jrebel-plugin&quot;&gt;gradle-jrebel-plugin&lt;/a&gt; - Generate rebel.xml configuration file.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/eriwen/gradle-js-plugin&quot;&gt;gradle-js-plugin&lt;/a&gt; - Manage JavaScript.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/kellyrob99/gradle-jslint-plugin&quot;&gt;gradle-jslint-plugin&lt;/a&gt; - Run JSLint static analysis against JavaScipt code.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/srs/gradle-node-plugin&quot;&gt;gradle-node-plugin&lt;/a&gt; - Run NodeJS scripts.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/srs/gradle-gulp-plugin&quot;&gt;gradle-gulp-plugin&lt;/a&gt; - Run Gulp tasks.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/srs/gradle-grunt-plugin&quot;&gt;gradle-grunt-plugin&lt;/a&gt; - Run Grunt tasks.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/craigburke/bower-installer-gradle&quot;&gt;bower-installer-plugin&lt;/a&gt; - Manage client-side dependencies.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/EvidentSolutions/apina&quot;&gt;apina&lt;/a&gt; - Creates client-side TypeScript from server-side APIs.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/bertramdev/asset-pipeline&quot;&gt;asset-pipeline&lt;/a&gt; - Manage and process static assets in JVM applications.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/ksoichiro/gradle-web-resource-plugin&quot;&gt;gradle-web-resource-plugin&lt;/a&gt; - Use CoffeeScript, LESS and Bower libraries without Node.js/npm.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/robfletcher/gradle-compass&quot;&gt;gradle-compass&lt;/a&gt; - Compile and watche SASS files.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/noamt/rest-gradle-plugin&quot;&gt;rest-gradle-plugin&lt;/a&gt; - Perform REST requests.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://plugins.gradle.org/plugin/org.gretty&quot;&gt;Gretty&lt;/a&gt; - Advanced gradle plugin for running web-apps on jetty and tomcat. &lt;a href=&quot;https://gretty-gradle-plugin.github.io/gretty-doc/&quot;&gt;https://gretty-gradle-plugin.github.io/gretty-doc/&lt;/a&gt; Add this plugin to your build using the plugins DSL: &lt;pre&gt;&lt;code&gt;plugins {
  id(&quot;org.gretty&quot;) version &quot;4.1.7&quot;
}
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Android application development&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;Dependency management&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/JakeWharton/sdk-manager-plugin&quot;&gt;sdk-manager-plugin&lt;/a&gt; - Download and manage Android SDK.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/nhachicha/android-native-dependencies&quot;&gt;android-native-dependencies&lt;/a&gt; - Gradle plugin for resolving and downloading Android native dependencies (.so)&lt;/li&gt; 
 &lt;li&gt;Alternative language&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/groovy/groovy-android-gradle-plugin&quot;&gt;groovy-android-gradle-plugin&lt;/a&gt; - Support the Groovy language for building Android apps.&lt;/li&gt; 
 &lt;li&gt;APK handling&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/KeepSafe/dexcount-gradle-plugin&quot;&gt;dexcount-gradle-plugin&lt;/a&gt; - Report the number of method references in APK.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/ihrthk/android-gradle-mulchannel-plugin&quot;&gt;android-gradle-mulchannel-plugin&lt;/a&gt; - Generate multiple apks from different channel.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/vanniktech/gradle-android-apk-size-plugin&quot;&gt;gradle-android-apk-size-plugin&lt;/a&gt; - Gradle plugin that generates CSV files with apk size per output and variant of an apk.&lt;/li&gt; 
 &lt;li&gt;Build variant handling&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/moallemi/gradle-advanced-build-version&quot;&gt;gradle-advanced-build-version&lt;/a&gt; - Generate the Android version code and version name automatically.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/tmiyamon/gradle-config&quot;&gt;gradle-config&lt;/a&gt; - Handle variant specific settings with yaml format.&lt;/li&gt; 
 &lt;li&gt;Icons&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/gfx/gradle-android-ribbonizer-plugin&quot;&gt;gradle-android-ribbonizer-plugin&lt;/a&gt; - Add a ribbon to launcher icons of Android apps.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/splatte/gradle-android-appiconoverlay&quot;&gt;gradle-android-appiconoverlay&lt;/a&gt; - Automatically overlay the app icon with the current git commit SHA1.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/tmiyamon/gradle-mdicons&quot;&gt;gradle-mdicons&lt;/a&gt; - Manage material design icons.&lt;/li&gt; 
 &lt;li&gt;Releasing&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/deploygate/gradle-deploygate-plugin&quot;&gt;gradle-deploygate-plugin&lt;/a&gt; - Build and deploy apps to DeployGate.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/testfairy/testfairy-gradle-plugin&quot;&gt;testfairy-gradle-plugin&lt;/a&gt; - Official plugin to upload signed builds to TestFairy.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/Triple-T/gradle-play-publisher&quot;&gt;gradle-play-publisher&lt;/a&gt; - Manage your complete Play Store presence in your repository: Listing, Release Notes, APKs and App Bundles.&lt;/li&gt; 
 &lt;li&gt;Testing&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/Centril/gradle-plugin-robospock&quot;&gt;gradle-plugin-robospock&lt;/a&gt; - Configure robospock (gradle + spock + roboelectric) easily.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/bjoernQ/unmock-plugin&quot;&gt;unmock-plugin&lt;/a&gt; - Allow you to use selected classes from a real Android-Jarfile for Android unit testing.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/AutoScout24/gradle-monkey-plugin&quot;&gt;gradle-monkey-plugin&lt;/a&gt; - Run Android monkey tests.&lt;/li&gt; 
 &lt;li&gt;Miscellaneous&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/stephanenicolas/ormlite-android-gradle-plugin&quot;&gt;ormlite-android-gradle-plugin&lt;/a&gt; - Generate an ORMLite configuration file and boost DAOs creations.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/ksoichiro/gradle-eclipse-aar-plugin&quot;&gt;gradle-eclipse-aar-plugin&lt;/a&gt; - Use Android AAR libraries on Eclipse.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/ksoichiro/gradle-android-git&quot;&gt;gradle-android-git&lt;/a&gt; - Manage Git dependency for Android apps.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/Karumi/Shot&quot;&gt;Shot&lt;/a&gt; - Shot is a Gradle plugin that simplifies the execution of screenshot tests using &lt;a href=&quot;http://facebook.github.io/screenshot-tests-for-android/&quot;&gt;Screenshot Tests For Android by Facebook&lt;/a&gt;.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;iOS and Mac application development&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/openbakery/gradle-xcodePlugin&quot;&gt;gradle-xcodePlugin&lt;/a&gt; - Build iOS and Mac projects.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/j2objc-contrib/j2objc-gradle&quot;&gt;j2objc-gradle&lt;/a&gt; - Enable Java source to be part of an iOS application&apos;s build.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Editor and IDE integration&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://docs.gradle.org/current/userguide/eclipse_plugin.html&quot;&gt;eclipse&lt;/a&gt; - Official plugin that generates files that are used by &lt;a href=&quot;http://eclipse.org/&quot;&gt;Eclipse IDE&lt;/a&gt;.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://docs.gradle.org/current/userguide/idea_plugin.html&quot;&gt;idea&lt;/a&gt; - Official plugin that generates files that are used by &lt;a href=&quot;http://www.jetbrains.com/idea/index.html&quot;&gt;Intellij IDEA IDE&lt;/a&gt;.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://docs.gradle.org/current/userguide/native_software.html&quot;&gt;visual-studio&lt;/a&gt; - Official plugin that adds integration with Visual Studio.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/diffplug/goomph&quot;&gt;goomph&lt;/a&gt; - Downloads an Eclipse IDE with all required plugins and creates a workspace with specified settings and projects.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/phildopus/gradle-sublimetext-plugin&quot;&gt;gradle-sublimetext-plugin&lt;/a&gt; - Generate Sublime Text 2 project file.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/Scuilion/gradle-syntastic-plugin&quot;&gt;gradle-syntastic-plugin&lt;/a&gt; - Integrate Java project with Vim and Syntastic.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Templating&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/aalmiray/markdown-gradle-plugin&quot;&gt;markdown-gradle-plugin&lt;/a&gt; - Convert Markdown to HTML.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/67726e/gradle-twirl&quot;&gt;gradle-twirl&lt;/a&gt; - Provide &lt;a href=&quot;https://github.com/playframework/twirl&quot;&gt;Twirl&lt;/a&gt; template compilation and integration.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Database&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;http://flywaydb.org/documentation/gradle/&quot;&gt;flyway-gradle-plugin&lt;/a&gt; - &lt;a href=&quot;http://flywaydb.org/&quot;&gt;Flyway&lt;/a&gt; database migration tasks.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/liquibase/liquibase-gradle-plugin&quot;&gt;liquibase-gradle-plugin&lt;/a&gt; - Use &lt;a href=&quot;http://liquibase.org/&quot;&gt;Liquibase&lt;/a&gt; to manage your database upgrades.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/marceloemanoel/gradle-migrations-plugin&quot;&gt;gradle-migrations-plugin&lt;/a&gt; - Provide gradle build integration with &lt;a href=&quot;https://code.google.com/p/mybatis/wiki/Migration&quot;&gt;mybatis migrations&lt;/a&gt;.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/marklogic-community/ml-gradle&quot;&gt;ml-gradle&lt;/a&gt; - Automate everything involving &lt;a href=&quot;https://developer.marklogic.com/&quot;&gt;MarkLogic&lt;/a&gt;.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Dependency management&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/ben-manes/gradle-versions-plugin&quot;&gt;gradle-versions-plugin&lt;/a&gt; - Provide a task to determine which dependencies have updates.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/Ullink/gradle-nuget-plugin&quot;&gt;gradle-nuget-plugin&lt;/a&gt; - Execute NuGet.exe from Gradle.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/wfhartford/gradle-dependency-analyze&quot;&gt;gradle-dependency-analyze&lt;/a&gt; - Dependency analysis plugin for gradle.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/nebula-plugins/gradle-dependency-lock-plugin&quot;&gt;gradle-dependency-lock-plugin&lt;/a&gt; - Allow people using dynamic dependency versions to lock them to specific versions.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/layerhq/gradle-git-repo-plugin&quot;&gt;gradle-git-repo-plugin&lt;/a&gt; - Use a private git repo as a Maven repository.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/jmfayard/buildSrcVersions&quot;&gt;buildSrcVersions&lt;/a&gt; - Painless dependencies management.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Debugging&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/tkruse/gradle-groovysh-plugin&quot;&gt;gradle-groovysh-plugin&lt;/a&gt; - Start an interactive groovy shells.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Testing&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/alphagov/gradle-gatling-plugin&quot;&gt;gradle-gatling-plugin&lt;/a&gt; - Run &lt;a href=&quot;http://gatling.io/&quot;&gt;Gatling&lt;/a&gt; scenarios.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/ksoichiro/gradle-console-reporter&quot;&gt;gradle-console-reporter&lt;/a&gt; - Report test result to console.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/radarsh/gradle-test-logger-plugin&quot;&gt;gradle-test-logger-plugin&lt;/a&gt; - A Gradle plugin for printing beautiful logs on the console while running tests.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/Softeq/itest-gradle-plugin&quot;&gt;gradle-itest-plugin&lt;/a&gt; - This plugin adds integration testing support to the project&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Building&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/passy/build-time-tracker-plugin&quot;&gt;build-time-tracker-plugin&lt;/a&gt; - Continuously track and report your build times.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/nebula-plugins/gradle-metrics-plugin&quot;&gt;gradle-metrics-plugin&lt;/a&gt; - Collect Gradle build metrics and persist them to an external datastore.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://nebula-plugins.github.io/&quot;&gt;nebula-plugin&lt;/a&gt; - A collection of Gradle plugins providing repeatable builds, immutable deployments and helping eliminate boilerplate code.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Packaging&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/rholder/gradle-one-jar&quot;&gt;gradle-one-jar&lt;/a&gt; - Build self-contained executable jars that include all dependencies.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/ksoichiro/gradle-build-info-plugin&quot;&gt;gradle-build-info-plugin&lt;/a&gt; - Include build information such as Git commit ID to your JAR.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/ksoichiro/gradle-replacer&quot;&gt;gradle-replacer&lt;/a&gt; - Provide a minimalistic template engine feature.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Releasing&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/int128/gradle-ssh-plugin&quot;&gt;gradle-ssh-plugin&lt;/a&gt; - Provide SSH facilities for continuous delivery.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://docs.gradle.org/current/userguide/maven_plugin.html&quot;&gt;maven&lt;/a&gt; - Official plugin that adds support for publishing artifacts to Maven repositories.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://plugins.gradle.org/plugin/com.gradle.plugin-publish&quot;&gt;plugin-publish&lt;/a&gt; - Publish plugins to the Gradle Plugin Portal.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/bintray/gradle-bintray-plugin&quot;&gt;gradle-bintray-plugin&lt;/a&gt; - Publish artifacts to Bintray.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/bmuschko/gradle-nexus-plugin&quot;&gt;gradle-nexus-plugin&lt;/a&gt; - Configure and upload artifacts to Sonatype Nexus.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/researchgate/gradle-release&quot;&gt;gradle-release&lt;/a&gt; - Automate releasing process. Similar to the Maven release plugin.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/diffplug/spotless-changelog&quot;&gt;spotless-changelog&lt;/a&gt; - Parses changelog to calculate next version, then updates changelog on publish.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Notification&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://docs.gradle.org/current/userguide/announce_plugin.html&quot;&gt;announce&lt;/a&gt; - Official plugin that publishes messages to platforms such as Twitter or Growl.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/Mindera/gradle-slack-plugin&quot;&gt;gradle-slack-plugin&lt;/a&gt; - Send messages to Slack after each build.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Cloud services&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/classmethod-aws/gradle-aws-plugin&quot;&gt;gradle-aws-plugin&lt;/a&gt; - Manage AWS resouces.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/skhatri/gradle-s3-plugin&quot;&gt;gradle-s3-plugin&lt;/a&gt; - Upload files to / download files from S3.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/nebula-plugins/gradle-stash-plugin&quot;&gt;gradle-stash-plugin&lt;/a&gt; - Interact with the Stash SCM.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/melix/gradle-cf-plugin&quot;&gt;gradle-cf-plugin&lt;/a&gt; - Interact with CloudFoundry.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;SCM&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/ajoberstar/gradle-git&quot;&gt;gradle-git&lt;/a&gt; - Set of plugin to interact with Git repositories, publish files to gh-page, etc.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/martoe/gradle-svntools-plugin&quot;&gt;gradle-svntools-plugin&lt;/a&gt; - Provide various SVN-related tasks.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/novabyte/gradle-snapshot-plugin&quot;&gt;gradle-snapshot-plugin&lt;/a&gt; - Generate build metadata from SCM tools.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;CI&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/jfrogdev/build-info&quot;&gt;build-info&lt;/a&gt; - Artifactory&apos;s open integration layer for the CI servers and build tools.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;VM and container&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/bmuschko/gradle-vagrant-plugin&quot;&gt;gradle-vagrant-plugin&lt;/a&gt; - Manage Vagrant boxes.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/bmuschko/gradle-docker-plugin&quot;&gt;bmuschko/gradle-docker-plugin&lt;/a&gt; - Gradle plugin for managing Docker images and containers.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/nebula-plugins/nebula-docker-plugin&quot;&gt;nebula-docker-plugin&lt;/a&gt; - Nebula gradle plugin for reducing boilerplate in creating docker images.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/palantir/gradle-docker&quot;&gt;palantir/gradle-docker&lt;/a&gt; - Build and push Docker images.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/Transmode/gradle-docker&quot;&gt;Transmode/gradle-docker&lt;/a&gt; - Build Docker images.&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Grunt</title>
      <link>https://tedneward.github.io/Research/tools/grunt/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/grunt/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://gruntjs.com/&quot;&gt;Website&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Hex Fiend</title>
      <link>https://tedneward.github.io/Research/tools/hexfiend/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/hexfiend/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://hexfiend.com/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/ridiculousfish/HexFiend/&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>HonKit</title>
      <link>https://tedneward.github.io/Research/tools/honkit/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/honkit/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://honkit.netlify.app/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/honkit/honkit&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;A fork of Gitbook. Can generate PDF, ePub, or Mobi files.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Hugo</title>
      <link>https://tedneward.github.io/Research/tools/hugo/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/hugo/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://gohugo.io/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/gohugoio/hugo&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Ilograph Diagramming Language (IDL)</title>
      <link>https://tedneward.github.io/Research/tools/ilograph/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/ilograph/index.html</guid>
      	<description>
	&lt;p&gt;Ilographs are advanced, interactive diagrams that allow users to see systems from multiple perspectives and levels of detail. Ilograph is a diagramming platform for system, software, network, cloud and other engineers.&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://www.ilograph.com/docs/editing/idl/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://www.ilograph.com/docs/&quot;&gt;Ilograph Diagramming Website&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Infer Static Analyzer</title>
      <link>https://tedneward.github.io/Research/tools/infer/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/infer/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;http://fbinfer.com/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/facebook/infer&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;h2&gt;Articles&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://neelbhatt.com/2021/03/07/first-look-at-infersharp-a-c-version-of-facebooks-infer/&quot;&gt;First look at InferSharp: A C# version of Facebook’s Infer&lt;/a&gt; &lt;a href=&quot;https://github.com/microsoft/infersharp&quot;&gt;InferSharp&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>JAD</title>
      <link>https://tedneward.github.io/Research/tools/jad/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/jad/index.html</guid>
      	<description>
	&lt;p&gt;Not updated since Java5, not open-source, written in C++ (and it was &lt;em&gt;fast&lt;/em&gt;). &lt;a href=&quot;http://www.javadecompilers.com/jad&quot;&gt;Last known available download site&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>JavaCC</title>
      <link>https://tedneward.github.io/Research/tools/javacc/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/javacc/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://javacc.github.io/javacc/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/javacc/javacc&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Features:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt; &lt;p&gt;JavaCC generates top-down (recursive descent) parsers as opposed to bottom-up parsers generated by YACC-like tools. This allows the use of more general grammars, although left-recursion is disallowed. Top-down parsers have a number of other advantages (besides more general grammars) such as being easier to debug, having the ability to parse to any non-terminal in the grammar, and also having the ability to pass values (attributes) both up and down the parse tree during parsing.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;By default, JavaCC generates an LL(1) parser. However, there may be portions of grammar that are not LL(1). JavaCC offers the capabilities of syntactic and semantic lookahead to resolve shift-shift ambiguities locally at these points. For example, the parser is LL(k) only at such points, but remains LL(1) everywhere else for better performance. Shift-reduce and reduce-reduce conflicts are not an issue for top-down parsers.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;JavaCC generates parsers that are 100% pure Java, so there is no runtime dependency on JavaCC and no special porting effort required to run on different machine platforms.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;JavaCC allows extended BNF specifications - such as (A)&lt;em&gt;, (A)+ etc - within the lexical and the grammar specifications. Extended BNF relieves the need for left-recursion to some extent. In fact, extended BNF is often easier to read as in A ::= y(x)&lt;/em&gt; versus A ::= Ax|y.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;The lexical specifications (such as regular expressions, strings) and the grammar specifications (the BNF) are both written together in the same file. It makes grammars easier to read since it is possible to use regular expressions inline in the grammar specification, and also easier to maintain.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;The lexical analyzer of JavaCC can handle full Unicode input, and lexical specifications may also include any Unicode character. This facilitates descriptions of language elements such as Java identifiers that allow certain Unicode characters (that are not ASCII), but not others.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;JavaCC offers Lex-like lexical state and lexical action capabilities. Specific aspects in JavaCC that are superior to other tools are the first class status it offers concepts such as TOKEN, MORE, SKIP and state changes. This allows cleaner specifications as well as better error and warning messages from JavaCC.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Tokens that are defined as special tokens in the lexical specification are ignored during parsing, but these tokens are available for processing by the tools. A useful application of this is in the processing of comments.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Lexical specifications can define tokens not to be case-sensitive either at the global level for the entire lexical specification, or on an individual lexical specification basis.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;JavaCC comes with JJTree, an extremely powerful tree building pre-processor.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;JavaCC also includes JJDoc, a tool that converts grammar files to documentation files, optionally in HTML.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;JavaCC offers many options to customize its behavior and the behavior of the generated parsers. Examples of such options are the kinds of Unicode processing to perform on the input stream, the number of tokens of ambiguity checking to perform etc.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;JavaCC error reporting is among the best in parser generators. JavaCC generated parsers are able to clearly point out the location of parse errors with complete diagnostic information.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Using options DEBUG_PARSER, DEBUG_LOOKAHEAD, and DEBUG_TOKEN_MANAGER, users can get in-depth analysis of the parsing and the token processing steps.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;The JavaCC release includes a wide range of examples including Java and HTML grammars. The examples, along with their documentation, are a great way to get acquainted with JavaCC.&lt;/p&gt; &lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>jcstress</title>
      <link>https://tedneward.github.io/Research/tools/jcstress/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/jcstress/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://openjdk.org/projects/code-tools/jcstress/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/openjdk/jcstress&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;In order to understand jcstress tests and maybe write your own, it might be useful to work through the jcstress-samples. The samples come in three groups:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;APISample target to explain the jcstress API;&lt;/li&gt; 
 &lt;li&gt;JMMSample target to explain the basics of Java Memory Model;&lt;/li&gt; 
 &lt;li&gt;ConcurrencySample show the interesting concurrent behaviors of standard library.&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>J-Integra</title>
      <link>https://tedneward.github.io/Research/tools/jintegra/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/jintegra/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://j-integra.intrinsyc.com/&quot;&gt;Website&lt;/a&gt; | Commercial&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>JSDB (JavaScript for Databases)</title>
      <link>https://tedneward.github.io/Research/tools/jsdb/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/jsdb/index.html</guid>
      	<description>
	&lt;p&gt;&quot;JSDB® is a JavaScript shell designed with network-centric programming in mind. It can be used as a database interface, XML processor, and internet-oriented scripting language. JSDB can do nearly any batch processing task that Visual Basic can do, and it has drivers to let you read and send email, query a MySQL database, and run regular expression searches, without having to learn a specific SQL syntax or install a bunch of ActiveX components. JSDB has everything you need to write a web server or database middleware, with a graphical debugger, itself written in JSDB.&quot;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;http://www.jsdb.org/&quot;&gt;Website&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Kiota</title>
      <link>https://tedneward.github.io/Research/tools/kiota/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/kiota/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://learn.microsoft.com/en-us/openapi/kiota/overview&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/microsoft/kiota&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;The goal is to eliminate the need to take a dependency on a different API SDK for every API that you need to call. Kiota API clients provide a strongly typed experience with all the features you expect from a high quality API SDK, but without having to learn a new library for every HTTP API.&lt;/p&gt; 
&lt;p&gt;This library builds on top of the Microsoft.OpenAPI.NET library to ensure comprehensive support for APIs that use OpenAPI descriptions. One of the goals of the project is to provide the best code generator support possible for OpenAPI and JSON Schema features. The conceptual documentation describes how kiota works and the high level concepts, this readme documents how to get started with Kiota.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Kubernetes</title>
      <link>https://tedneward.github.io/Research/tools/kubernetes/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/kubernetes/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://kubernetes.io/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://kubernetes.io/docs/home/&quot;&gt;Docs&lt;/a&gt; | &lt;a href=&quot;https://github.com/kubernetes/kubernetes&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Kubernetes is a portable, extensible, open-source platform for managing containerized workloads and services, that facilitates both declarative configuration and automation.&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://resources.linuxfoundation.org/LF+Projects/CNCF/TheNewStack_Book2_KubernetesDeploymentAndSecurityPatterns.pdf&quot;&gt;Kubernetes Deployment &amp;amp; Security Patterns&lt;/a&gt; - Alex Williams (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.digitalocean.com/community/curriculums/kubernetes-for-full-stack-developers&quot;&gt;Kubernetes for Full-Stack Developers&lt;/a&gt; - Jamon Camisso, Hanif Jetha, Katherine Juell (PDF, EPUB)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://livro.descomplicandokubernetes.com.br/en/&quot;&gt;Uncomplicating Kubernetes&lt;/a&gt; - Jeferson Fernando&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;Features:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Automated rollouts and rollbacks: Kubernetes progressively rolls out changes to your application or its configuration, while monitoring application health to ensure it doesn&apos;t kill all your instances at the same time. If something goes wrong, Kubernetes will rollback the change for you. Take advantage of a growing ecosystem of deployment solutions.&lt;/li&gt; 
 &lt;li&gt;Service discovery and load balancing: No need to modify your application to use an unfamiliar service discovery mechanism. Kubernetes gives Pods their own IP addresses and a single DNS name for a set of Pods, and can load-balance across them.&lt;/li&gt; 
 &lt;li&gt;Storage orchestration: Automatically mount the storage system of your choice, whether from local storage, a public cloud provider such as GCP or AWS, or a network storage system such as NFS, iSCSI, Gluster, Ceph, Cinder, or Flocker.&lt;/li&gt; 
 &lt;li&gt;Secret and configuration management: Deploy and update secrets and application configuration without rebuilding your image and without exposing secrets in your stack configuration.&lt;/li&gt; 
 &lt;li&gt;Automatic bin packing: Automatically places containers based on their resource requirements and other constraints, while not sacrificing availability. Mix critical and best-effort workloads in order to drive up utilization and save even more resources.&lt;/li&gt; 
 &lt;li&gt;Batch execution: In addition to services, Kubernetes can manage your batch and CI workloads, replacing containers that fail, if desired.&lt;/li&gt; 
 &lt;li&gt;IPv4/IPv6 dual-stack: Allocation of IPv4 and IPv6 addresses to Pods and Services&lt;/li&gt; 
 &lt;li&gt;Horizontal scaling: Scale your application up and down with a simple command, with a UI, or automatically based on CPU usage.&lt;/li&gt; 
 &lt;li&gt;Self-healing: Restarts containers that fail, replaces and reschedules containers when nodes die, kills containers that don&apos;t respond to your user-defined health check, and doesn&apos;t advertise them to clients until they are ready to serve.&lt;/li&gt; 
 &lt;li&gt;Designed for extensibility: Add features to your Kubernetes cluster without changing upstream source code.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;hr&gt; 
&lt;p&gt;Kubernetes scope levels:&lt;/p&gt; 
&lt;p&gt;&lt;img src=&quot;https://media-exp1.licdn.com/dms/image/C4D22AQFGGnID0n3O7w/feedshare-shrink_800/0/1646199387172?e=1649289600&amp;amp;v=beta&amp;amp;t=tOpWwoqDw4YOWpwnKN-OqSM_M53vSTPWdyQnyo1jlik&quot; alt=&quot;&quot;&gt;&lt;/p&gt; 
&lt;p&gt;Project (Strongest network/data/metadata isolation)&lt;br&gt; ... contains Cluster(s) (Strongest control plane isolation, stronger network/data isolation, strong metadata isolation)&lt;br&gt; ... contains Node(s) (stronger resource/network/data isolation)&lt;br&gt; ... contains Pod(s) (Some network isolation, some more resource isolation)&lt;br&gt; ... contains Container(s) (Some resource isolation, kernel security isolation)&lt;br&gt; ... with Namespaces (Some control plane isolation, service account isolation) being inside Cluster and encircling Pods&lt;/p&gt; 
&lt;hr&gt; 
&lt;h2&gt;Articles&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://medium.com/@mikhail_advani/kubernetes-in-cluster-traffic-encryption-using-cert-manager-b70c2101a12d&quot;&gt;Kubernetes in-cluster traffic encryption using cert manager&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;hr&gt; 
&lt;h2&gt;Related Projects&lt;/h2&gt; 
&lt;p&gt;&lt;a href=&quot;https://github.com/kyverno/kyverno&quot;&gt;kyverno&lt;/a&gt;: Kubernetes Native Policy Management&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Leo</title>
      <link>https://tedneward.github.io/Research/tools/leo/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/leo/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;http://www.leoeditor.com/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/leo-editor&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Live Boot (operating systems)</title>
      <link>https://tedneward.github.io/Research/tools/live-boot/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/live-boot/index.html</guid>
      	<description>
	&lt;h2&gt;Reading&lt;/h2&gt; 
&lt;h3&gt;Articles/Blogs/Essays&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://support.system76.com/articles/live-disk/&quot;&gt;Live Disk Creation&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>LobeHub</title>
      <link>https://tedneward.github.io/Research/tools/lobehub/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/lobehub/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://lobehub.com/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/lobehub/lobehub&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;LobeHub is the ultimate space for work and life: to find, build, and collaborate with agent teammates that grow with you. We’re building the world’s largest human–agent co-evolving network.&lt;/p&gt; 
&lt;h2&gt;👋🏻 Getting Started &amp;amp; Join Our Community&lt;/h2&gt; 
&lt;p&gt;We are a group of e/acc design-engineers, hoping to provide modern design components and tools for AIGC.&lt;br&gt; By adopting the Bootstrapping approach, we aim to provide developers and users with a more open, transparent, and user-friendly product ecosystem.&lt;/p&gt; 
&lt;h2&gt;✨ Features&lt;/h2&gt; 
&lt;p&gt;Today’s agents are one-off, task-driven tools. They lack context, live in isolation, and require manual hand-offs between different windows and models. While some maintain memory, it is often global, shallow, and impersonal. In this mode, users are forced to toggle between fragmented conversations, making it difficult to form structured productivity.&lt;/p&gt; 
&lt;p&gt;LobeHub is a work-and-lifestyle space to find, build, and collaborate with agent teammates that grow with you. In LobeHub, we treat &lt;strong&gt;Agents as the unit of work&lt;/strong&gt;, providing an infrastructure where humans and agents co-evolve.&lt;/p&gt; 
&lt;h3&gt;Create: Agents as the Unit of Work&lt;/h3&gt; 
&lt;p&gt;Building a personalized AI team starts with the &lt;strong&gt;Agent Builder&lt;/strong&gt;. You can describe what you need once, and the agent setup starts right away, applying auto-configurations so you can use it instantly.&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;strong&gt;Unified Intelligence&lt;/strong&gt;: Seamlessly access any model and any modality—all under your control.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;10,000+ Skills&lt;/strong&gt;: Connect your agents to the skills you use every day with a library of over 10,000 tools and MCP-compatible plugins.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Collaborate: Scale New Forms of Collaboration Networks&lt;/h3&gt; 
&lt;p&gt;LobeHub introduces &lt;strong&gt;Agent Groups&lt;/strong&gt;, allowing you to work with agents like real teammates. The system assembles the right agents for the task, enabling parallel collaboration and iterative improvement.&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;strong&gt;Pages&lt;/strong&gt;: Write and refine content with multiple agents in one place with a shared context.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Schedule&lt;/strong&gt;: Schedule runs and let agents do the work at the right time, even while you are away.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Project&lt;/strong&gt;: Organize work by project to keep everything structured and easy to track.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Workspace&lt;/strong&gt;: A shared space for teams to collaborate with agents, ensuring clear ownership and visibility across the organization.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Evolve: Co-evolution of Humans and Agents&lt;/h3&gt; 
&lt;p&gt;The best AI is one that understands you deeply. LobeHub features &lt;strong&gt;Personal Memory&lt;/strong&gt; that builds a clear understanding of your needs.&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;strong&gt;Continual Learning&lt;/strong&gt;: Your agents learn from how you work, adapting their behavior to act at the right moment.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;White-Box Memory&lt;/strong&gt;: We believe in transparency. Your agents use structured, editable memory, giving you full control over what they remember.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;MCP Plugin One-Click Installation&lt;/h3&gt; 
&lt;p&gt;&lt;strong&gt;Seamlessly Connect Your AI to the World&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;Unlock the full potential of your AI by enabling smooth, secure, and dynamic interactions with external tools, data sources, and services. LobeHub&apos;s MCP (Model Context Protocol) plugin system breaks down the barriers between your AI and the digital ecosystem, allowing for unprecedented connectivity and functionality.&lt;/p&gt; 
&lt;p&gt;Transform your conversations into powerful workflows by connecting to databases, APIs, file systems, and more. Experience the freedom of AI that truly understands and interacts with your world.&lt;/p&gt; 
&lt;h3&gt;MCP Marketplace&lt;/h3&gt; 
&lt;p&gt;&lt;strong&gt;Discover, Connect, Extend&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;Browse a growing library of MCP plugins to expand your AI&apos;s capabilities and streamline your workflows effortlessly. Visit &lt;a href=&quot;https://lobehub.com/mcp&quot;&gt;lobehub.com/mcp&lt;/a&gt; to explore the MCP Marketplace, which offers a curated collection of integrations that enhance your AI&apos;s ability to work with various tools and services.&lt;/p&gt; 
&lt;p&gt;From productivity tools to development environments, discover new ways to extend your AI&apos;s reach and effectiveness. Connect with the community and find the perfect plugins for your specific needs.&lt;/p&gt; 
&lt;h3&gt;Desktop App&lt;/h3&gt; 
&lt;p&gt;&lt;strong&gt;Peak Performance, Zero Distractions&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;Get the full LobeHub experience without browser limitations—comprehensive, focused, and always ready to go. Our desktop application provides a dedicated environment for your AI interactions, ensuring optimal performance and minimal distractions.&lt;/p&gt; 
&lt;p&gt;Experience faster response times, better resource management, and a more stable connection to your AI assistant. The desktop app is designed for users who demand the best performance from their AI tools.&lt;/p&gt; 
&lt;h3&gt;Smart Internet Search&lt;/h3&gt; 
&lt;p&gt;&lt;strong&gt;Online Knowledge On Demand&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;With real-time internet access, your AI keeps up with the world—news, data, trends, and more. Stay informed and get the most current information available, enabling your AI to provide accurate and up-to-date responses.&lt;/p&gt; 
&lt;p&gt;Access live information, verify facts, and explore current events without leaving your conversation. Your AI becomes a gateway to the world&apos;s knowledge, always current and comprehensive.&lt;/p&gt; 
&lt;h3&gt;&lt;a href=&quot;https://lobehub.com/docs/usage/features/cot&quot;&gt;Chain of Thought&lt;/a&gt;&lt;/h3&gt; 
&lt;p&gt;Experience AI reasoning like never before. Watch as complex problems unfold step by step through our innovative Chain of Thought (CoT) visualization. This breakthrough feature provides unprecedented transparency into AI&apos;s decision-making process, allowing you to observe how conclusions are reached in real-time.&lt;/p&gt; 
&lt;p&gt;By breaking down complex reasoning into clear, logical steps, you can better understand and validate the AI&apos;s problem-solving approach. Whether you&apos;re debugging, learning, or simply curious about AI reasoning, CoT visualization transforms abstract thinking into an engaging, interactive experience.&lt;/p&gt; 
&lt;h3&gt;&lt;a href=&quot;https://lobehub.com/docs/usage/features/branching-conversations&quot;&gt;Branching Conversations&lt;/a&gt;&lt;/h3&gt; 
&lt;p&gt;Introducing a more natural and flexible way to chat with AI. With Branch Conversations, your discussions can flow in multiple directions, just like human conversations do. Create new conversation branches from any message, giving you the freedom to explore different paths while preserving the original context.&lt;/p&gt; 
&lt;p&gt;Choose between two powerful modes:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;strong&gt;Continuation Mode:&lt;/strong&gt; Seamlessly extend your current discussion while maintaining valuable context&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Standalone Mode:&lt;/strong&gt; Start fresh with a new topic based on any previous message&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;This groundbreaking feature transforms linear conversations into dynamic, tree-like structures, enabling deeper exploration of ideas and more productive interactions.&lt;/p&gt; 
&lt;h3&gt;&lt;a href=&quot;https://lobehub.com/docs/usage/features/artifacts&quot;&gt;Artifacts Support&lt;/a&gt;&lt;/h3&gt; 
&lt;p&gt;Experience the power of Claude Artifacts, now integrated into LobeHub. This revolutionary feature expands the boundaries of AI-human interaction, enabling real-time creation and visualization of diverse content formats.&lt;/p&gt; 
&lt;p&gt;Create and visualize with unprecedented flexibility:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Generate and display dynamic SVG graphics&lt;/li&gt; 
 &lt;li&gt;Build and render interactive HTML pages in real-time&lt;/li&gt; 
 &lt;li&gt;Produce professional documents in multiple formats&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;&lt;a href=&quot;https://lobehub.com/blog/knowledge-base&quot;&gt;File Upload /Knowledge Base&lt;/a&gt;&lt;/h3&gt; 
&lt;p&gt;LobeHub supports file upload and knowledge base functionality. You can upload various types of files including documents, images, audio, and video, as well as create knowledge bases, making it convenient for users to manage and search for files. Additionally, you can utilize files and knowledge base features during conversations, enabling a richer dialogue experience.&lt;/p&gt; 
&lt;h3&gt;&lt;a href=&quot;https://lobehub.com/docs/usage/features/multi-ai-providers&quot;&gt;Multi-Model Service Provider Support&lt;/a&gt;&lt;/h3&gt; 
&lt;p&gt;In the continuous development of LobeHub, we deeply understand the importance of diversity in model service providers for meeting the needs of the community when providing AI conversation services. Therefore, we have expanded our support to multiple model service providers, rather than being limited to a single one, in order to offer users a more diverse and rich selection of conversations.&lt;/p&gt; 
&lt;p&gt;In this way, LobeHub can more flexibly adapt to the needs of different users, while also providing developers with a wider range of choices.&lt;/p&gt; 
&lt;h3&gt;&lt;a href=&quot;https://lobehub.com/docs/usage/features/local-llm&quot;&gt;Local Large Language Model (LLM) Support&lt;/a&gt;&lt;/h3&gt; 
&lt;p&gt;To meet the specific needs of users, LobeHub also supports the use of local models based on &lt;a href=&quot;https://ollama.ai&quot;&gt;Ollama&lt;/a&gt;, allowing users to flexibly use their own or third-party models.&lt;/p&gt; 
&lt;h3&gt;&lt;a href=&quot;https://lobehub.com/docs/usage/features/vision&quot;&gt;Model Visual Recognition&lt;/a&gt;&lt;/h3&gt; 
&lt;p&gt;LobeHub now supports OpenAI&apos;s latest &lt;a href=&quot;https://platform.openai.com/docs/guides/vision&quot;&gt;&lt;code&gt;gpt-4-vision&lt;/code&gt;&lt;/a&gt; model with visual recognition capabilities,&lt;br&gt; a multimodal intelligence that can perceive visuals. Users can easily upload or drag and drop images into the dialogue box,&lt;br&gt; and the agent will be able to recognize the content of the images and engage in intelligent conversation based on this,&lt;br&gt; creating smarter and more diversified chat scenarios.&lt;/p&gt; 
&lt;p&gt;This feature opens up new interactive methods, allowing communication to transcend text and include a wealth of visual elements.&lt;br&gt; Whether it&apos;s sharing images in daily use or interpreting images within specific industries, the agent provides an outstanding conversational experience.&lt;/p&gt; 
&lt;h3&gt;&lt;a href=&quot;https://lobehub.com/docs/usage/features/tts&quot;&gt;TTS &amp;amp; STT Voice Conversation&lt;/a&gt;&lt;/h3&gt; 
&lt;p&gt;LobeHub supports Text-to-Speech (TTS) and Speech-to-Text (STT) technologies, enabling our application to convert text messages into clear voice outputs,&lt;br&gt; allowing users to interact with our conversational agent as if they were talking to a real person. Users can choose from a variety of voices to pair with the agent.&lt;/p&gt; 
&lt;p&gt;Moreover, TTS offers an excellent solution for those who prefer auditory learning or desire to receive information while busy.&lt;br&gt; In LobeHub, we have meticulously selected a range of high-quality voice options (OpenAI Audio, Microsoft Edge Speech) to meet the needs of users from different regions and cultural backgrounds.&lt;br&gt; Users can choose the voice that suits their personal preferences or specific scenarios, resulting in a personalized communication experience.&lt;/p&gt; 
&lt;h3&gt;&lt;a href=&quot;https://lobehub.com/docs/usage/features/text-to-image&quot;&gt;Text to Image Generation&lt;/a&gt;&lt;/h3&gt; 
&lt;p&gt;With support for the latest text-to-image generation technology, LobeHub now allows users to invoke image creation tools directly within conversations with the agent. By leveraging the capabilities of AI tools such as &lt;a href=&quot;https://openai.com/dall-e-3&quot;&gt;&lt;code&gt;DALL-E 3&lt;/code&gt;&lt;/a&gt;, &lt;a href=&quot;https://www.midjourney.com/&quot;&gt;&lt;code&gt;MidJourney&lt;/code&gt;&lt;/a&gt;, and &lt;a href=&quot;https://pollinations.ai/&quot;&gt;&lt;code&gt;Pollinations&lt;/code&gt;&lt;/a&gt;, the agents are now equipped to transform your ideas into images.&lt;/p&gt; 
&lt;p&gt;This enables a more private and immersive creative process, allowing for the seamless integration of visual storytelling into your personal dialogue with the agent.&lt;/p&gt; 
&lt;h3&gt;&lt;a href=&quot;https://lobehub.com/docs/usage/features/plugin-system&quot;&gt;Plugin System (Function Calling)&lt;/a&gt;&lt;/h3&gt; 
&lt;p&gt;The plugin ecosystem of LobeHub is an important extension of its core functionality, greatly enhancing the practicality and flexibility of the LobeHub assistant.&lt;/p&gt; 
&lt;p&gt;
 &lt;video controls src=&quot;https://github.com/lobehub/lobehub/assets/28616219/f29475a3-f346-4196-a435-41a6373ab9e2&quot; muted=&quot;false&quot;&gt;&lt;/video&gt;&lt;/p&gt; 
&lt;p&gt;By utilizing plugins, LobeHub assistants can obtain and process real-time information, such as searching for web information and providing users with instant and relevant news.&lt;/p&gt; 
&lt;p&gt;In addition, these plugins are not limited to news aggregation, but can also extend to other practical functions, such as quickly searching documents, generating images, obtaining data from various platforms like Bilibili, Steam, and interacting with various third-party services.&lt;/p&gt; 
&lt;h3&gt;&lt;a href=&quot;https://lobehub.com/docs/usage/features/agent-market&quot;&gt;Agent Market (GPTs)&lt;/a&gt;&lt;/h3&gt; 
&lt;p&gt;In LobeHub Agent Marketplace, creators can discover a vibrant and innovative community that brings together a multitude of well-designed agents,&lt;br&gt; which not only play an important role in work scenarios but also offer great convenience in learning processes.&lt;br&gt; Our marketplace is not just a showcase platform but also a collaborative space. Here, everyone can contribute their wisdom and share the agents they have developed.&lt;/p&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;[!TIP]&lt;/p&gt; 
 &lt;p&gt;By &lt;a href=&quot;https://github.com/lobehub/lobe-chat-agents&quot;&gt;🤖/🏪 Submit Agents&lt;/a&gt;, you can easily submit your agent creations to our platform.&lt;br&gt; Importantly, LobeHub has established a sophisticated automated internationalization (i18n) workflow,&lt;br&gt; capable of seamlessly translating your agent into multiple language versions.&lt;br&gt; This means that no matter what language your users speak, they can experience your agent without barriers.&lt;/p&gt; 
 &lt;p&gt;[!IMPORTANT]&lt;/p&gt; 
 &lt;p&gt;We welcome all users to join this growing ecosystem and participate in the iteration and optimization of agents.&lt;br&gt; Together, we can create more interesting, practical, and innovative agents, further enriching the diversity and practicality of the agent offerings.&lt;/p&gt; 
&lt;/blockquote&gt; &lt;!-- AGENT LIST --&gt; 
&lt;table&gt; 
 &lt;thead&gt; 
  &lt;tr&gt;
   &lt;th&gt; Recent Submits &lt;/th&gt;
   &lt;th&gt; Description &lt;/th&gt;
  &lt;/tr&gt; 
 &lt;/thead&gt; 
 &lt;tbody&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;a href=&quot;https://lobechat.com/discover/assistant/lateral-thinking-puzzle&quot;&gt;Turtle Soup Host&lt;/a&gt;&lt;br&gt;&lt;sup&gt;By &lt;strong&gt;&lt;a href=&quot;https://github.com/CSY2022&quot;&gt;CSY2022&lt;/a&gt;&lt;/strong&gt; on &lt;strong&gt;2025-06-19&lt;/strong&gt;&lt;/sup&gt; &lt;/td&gt;
   &lt;td&gt; A turtle soup host needs to provide the scenario, the complete story (truth of the event), and the key point (the condition for guessing correctly).&lt;br&gt;&lt;code&gt;turtle-soup&lt;/code&gt; &lt;code&gt;reasoning&lt;/code&gt; &lt;code&gt;interaction&lt;/code&gt; &lt;code&gt;puzzle&lt;/code&gt; &lt;code&gt;role-playing&lt;/code&gt; &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;a href=&quot;https://lobechat.com/discover/assistant/academic-writing-assistant&quot;&gt;Academic Writing Assistant&lt;/a&gt;&lt;br&gt;&lt;sup&gt;By &lt;strong&gt;&lt;a href=&quot;https://github.com/swarfte&quot;&gt;swarfte&lt;/a&gt;&lt;/strong&gt; on &lt;strong&gt;2025-06-17&lt;/strong&gt;&lt;/sup&gt; &lt;/td&gt;
   &lt;td&gt; Expert in academic research paper writing and formal documentation&lt;br&gt;&lt;code&gt;academic-writing&lt;/code&gt; &lt;code&gt;research&lt;/code&gt; &lt;code&gt;formal-style&lt;/code&gt; &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;a href=&quot;https://lobechat.com/discover/assistant/food-reviewer&quot;&gt;Gourmet Reviewer🍟&lt;/a&gt;&lt;br&gt;&lt;sup&gt;By &lt;strong&gt;&lt;a href=&quot;https://github.com/renhai-lab&quot;&gt;renhai-lab&lt;/a&gt;&lt;/strong&gt; on &lt;strong&gt;2025-06-17&lt;/strong&gt;&lt;/sup&gt; &lt;/td&gt;
   &lt;td&gt; Food critique expert&lt;br&gt;&lt;code&gt;gourmet&lt;/code&gt; &lt;code&gt;review&lt;/code&gt; &lt;code&gt;writing&lt;/code&gt; &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;a href=&quot;https://lobechat.com/discover/assistant/java-development&quot;&gt;Minecraft Senior Developer&lt;/a&gt;&lt;br&gt;&lt;sup&gt;By &lt;strong&gt;&lt;a href=&quot;https://github.com/iamyuuk&quot;&gt;iamyuuk&lt;/a&gt;&lt;/strong&gt; on &lt;strong&gt;2025-06-17&lt;/strong&gt;&lt;/sup&gt; &lt;/td&gt;
   &lt;td&gt; Expert in advanced Java development and Minecraft mod and server plugin development&lt;br&gt;&lt;code&gt;development&lt;/code&gt; &lt;code&gt;programming&lt;/code&gt; &lt;code&gt;minecraft&lt;/code&gt; &lt;code&gt;java&lt;/code&gt; &lt;/td&gt;
  &lt;/tr&gt; 
 &lt;/tbody&gt; 
&lt;/table&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;📊 Total agents: &lt;a href=&quot;https://lobechat.com/discover/assistants&quot;&gt;&lt;kbd&gt;&lt;strong&gt;505&lt;/strong&gt;&lt;/kbd&gt;&lt;/a&gt;&lt;/p&gt; 
&lt;/blockquote&gt; &lt;!-- AGENT LIST --&gt; 
&lt;div align=&quot;right&quot;&gt; 
 &lt;p&gt;&lt;a href=&quot;#readme-top&quot;&gt;![][back-to-top]&lt;/a&gt;&lt;/p&gt; 
&lt;/div&gt; 
&lt;p&gt;&lt;a href=&quot;https://lobehub.com/docs/usage/features/database&quot;&gt;&lt;img src=&quot;https://github.com/user-attachments/assets/f1697c8b-d1fb-4dac-ba05-153c6295d91d&quot; alt=&quot;&quot;&gt;&lt;/a&gt;&lt;/p&gt; 
&lt;h3&gt;&lt;a href=&quot;https://lobehub.com/docs/usage/features/database&quot;&gt;Support Local / Remote Database&lt;/a&gt;&lt;/h3&gt; 
&lt;p&gt;LobeHub supports the use of both server-side and local databases. Depending on your needs, you can choose the appropriate deployment solution:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;strong&gt;Local database&lt;/strong&gt;: suitable for users who want more control over their data and privacy protection. LobeHub uses CRDT (Conflict-Free Replicated Data Type) technology to achieve multi-device synchronization. This is an experimental feature aimed at providing a seamless data synchronization experience.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Server-side database&lt;/strong&gt;: suitable for users who want a more convenient user experience. LobeHub supports PostgreSQL as a server-side database. For detailed documentation on how to configure the server-side database, please visit &lt;a href=&quot;https://lobehub.com/docs/self-hosting/advanced/server-database&quot;&gt;Configure Server-side Database&lt;/a&gt;.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;Regardless of which database you choose, LobeHub can provide you with an excellent user experience.&lt;/p&gt; 
&lt;div align=&quot;right&quot;&gt; 
 &lt;p&gt;&lt;a href=&quot;#readme-top&quot;&gt;![][back-to-top]&lt;/a&gt;&lt;/p&gt; 
&lt;/div&gt; 
&lt;p&gt;&lt;a href=&quot;https://lobehub.com/docs/usage/features/auth&quot;&gt;&lt;img src=&quot;https://github.com/user-attachments/assets/80bb232e-19d1-4f97-98d6-e291f3585e6d&quot; alt=&quot;&quot;&gt;&lt;/a&gt;&lt;/p&gt; 
&lt;h3&gt;&lt;a href=&quot;https://lobehub.com/docs/usage/features/auth&quot;&gt;Support Multi-User Management&lt;/a&gt;&lt;/h3&gt; 
&lt;p&gt;LobeHub supports multi-user management and provides flexible user authentication solutions:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;strong&gt;Better Auth&lt;/strong&gt;: LobeHub integrates &lt;code&gt;Better Auth&lt;/code&gt;, a modern and flexible authentication library that supports multiple authentication methods, including OAuth, email login, credential login, magic links, and more. With &lt;code&gt;Better Auth&lt;/code&gt;, you can easily implement user registration, login, session management, social login, multi-factor authentication (MFA), and other functions to ensure the security and privacy of user data.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;div align=&quot;right&quot;&gt; 
 &lt;p&gt;&lt;a href=&quot;#readme-top&quot;&gt;![][back-to-top]&lt;/a&gt;&lt;/p&gt; 
&lt;/div&gt; 
&lt;p&gt;&lt;a href=&quot;https://lobehub.com/docs/usage/features/pwa&quot;&gt;&lt;img src=&quot;https://github.com/user-attachments/assets/9647f70f-b71b-43b6-9564-7cdd12d1c24d&quot; alt=&quot;&quot;&gt;&lt;/a&gt;&lt;/p&gt; 
&lt;h3&gt;&lt;a href=&quot;https://lobehub.com/docs/usage/features/pwa&quot;&gt;Progressive Web App (PWA)&lt;/a&gt;&lt;/h3&gt; 
&lt;p&gt;We deeply understand the importance of providing a seamless experience for users in today&apos;s multi-device environment.&lt;br&gt; Therefore, we have adopted Progressive Web Application (&lt;a href=&quot;https://support.google.com/chrome/answer/9658361&quot;&gt;PWA&lt;/a&gt;) technology,&lt;br&gt; a modern web technology that elevates web applications to an experience close to that of native apps.&lt;/p&gt; 
&lt;p&gt;Through PWA, LobeHub can offer a highly optimized user experience on both desktop and mobile devices while maintaining high-performance characteristics.&lt;br&gt; Visually and in terms of feel, we have also meticulously designed the interface to ensure it is indistinguishable from native apps,&lt;br&gt; providing smooth animations, responsive layouts, and adapting to different device screen resolutions.&lt;/p&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;[!NOTE]&lt;/p&gt; 
 &lt;p&gt;If you are unfamiliar with the installation process of PWA, you can add LobeHub as your desktop application (also applicable to mobile devices) by following these steps:&lt;/p&gt; 
 &lt;ul&gt; 
  &lt;li&gt;Launch the Chrome or Edge browser on your computer.&lt;/li&gt; 
  &lt;li&gt;Visit the LobeHub webpage.&lt;/li&gt; 
  &lt;li&gt;In the upper right corner of the address bar, click on the &lt;kbd&gt;Install&lt;/kbd&gt; icon.&lt;/li&gt; 
  &lt;li&gt;Follow the instructions on the screen to complete the PWA Installation.&lt;/li&gt; 
 &lt;/ul&gt; 
&lt;/blockquote&gt; 
&lt;div align=&quot;right&quot;&gt; 
 &lt;p&gt;&lt;a href=&quot;#readme-top&quot;&gt;![][back-to-top]&lt;/a&gt;&lt;/p&gt; 
&lt;/div&gt; 
&lt;p&gt;&lt;a href=&quot;https://lobehub.com/docs/usage/features/mobile&quot;&gt;&lt;img src=&quot;https://github.com/user-attachments/assets/32cf43c4-96bd-4a4c-bfb6-59acde6fe380&quot; alt=&quot;&quot;&gt;&lt;/a&gt;&lt;/p&gt; 
&lt;h3&gt;&lt;a href=&quot;https://lobehub.com/docs/usage/features/mobile&quot;&gt;Mobile Device Adaptation&lt;/a&gt;&lt;/h3&gt; 
&lt;p&gt;We have carried out a series of optimization designs for mobile devices to enhance the user&apos;s mobile experience. Currently, we are iterating on the mobile user experience to achieve smoother and more intuitive interactions. If you have any suggestions or ideas, we welcome you to provide feedback through GitHub Issues or Pull Requests.&lt;/p&gt; 
&lt;div align=&quot;right&quot;&gt; 
 &lt;p&gt;&lt;a href=&quot;#readme-top&quot;&gt;![][back-to-top]&lt;/a&gt;&lt;/p&gt; 
&lt;/div&gt; 
&lt;p&gt;&lt;a href=&quot;https://lobehub.com/docs/usage/features/theme&quot;&gt;&lt;img src=&quot;https://github.com/user-attachments/assets/b47c39f1-806f-492b-8fcb-b0fa973937c1&quot; alt=&quot;&quot;&gt;&lt;/a&gt;&lt;/p&gt; 
&lt;h3&gt;&lt;a href=&quot;https://lobehub.com/docs/usage/features/theme&quot;&gt;Custom Themes&lt;/a&gt;&lt;/h3&gt; 
&lt;p&gt;As a design-engineering-oriented application, LobeHub places great emphasis on users&apos; personalized experiences,&lt;br&gt; hence introducing flexible and diverse theme modes, including a light mode for daytime and a dark mode for nighttime.&lt;br&gt; Beyond switching theme modes, a range of color customization options allow users to adjust the application&apos;s theme colors according to their preferences.&lt;br&gt; Whether it&apos;s a desire for a sober dark blue, a lively peach pink, or a professional gray-white, users can find their style of color choices in LobeHub.&lt;/p&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;[!TIP]&lt;/p&gt; 
 &lt;p&gt;The default configuration can intelligently recognize the user&apos;s system color mode and automatically switch themes to ensure a consistent visual experience with the operating system.&lt;br&gt; For users who like to manually control details, LobeHub also offers intuitive setting options and a choice between chat bubble mode and document mode for conversation scenarios.&lt;/p&gt; 
&lt;/blockquote&gt; 
&lt;div align=&quot;right&quot;&gt; 
 &lt;p&gt;&lt;a href=&quot;#readme-top&quot;&gt;![][back-to-top]&lt;/a&gt;&lt;/p&gt; 
&lt;/div&gt; 
&lt;h3&gt;&lt;code&gt;*&lt;/code&gt; What&apos;s more&lt;/h3&gt; 
&lt;p&gt;Beside these features, LobeHub also have much better basic technique underground:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;[x] 💨 &lt;strong&gt;Quick Deployment&lt;/strong&gt;: Using the Vercel platform or docker image, you can deploy with just one click and complete the process within 1 minute without any complex configuration.&lt;/li&gt; 
 &lt;li&gt;[x] 🌐 &lt;strong&gt;Custom Domain&lt;/strong&gt;: If users have their own domain, they can bind it to the platform for quick access to the dialogue agent from anywhere.&lt;/li&gt; 
 &lt;li&gt;[x] 🔒 &lt;strong&gt;Privacy Protection&lt;/strong&gt;: All data is stored locally in the user&apos;s browser, ensuring user privacy.&lt;/li&gt; 
 &lt;li&gt;[x] 💎 &lt;strong&gt;Exquisite UI Design&lt;/strong&gt;: With a carefully designed interface, it offers an elegant appearance and smooth interaction. It supports light and dark themes and is mobile-friendly. PWA support provides a more native-like experience.&lt;/li&gt; 
 &lt;li&gt;[x] 🗣️ &lt;strong&gt;Smooth Conversation Experience&lt;/strong&gt;: Fluid responses ensure a smooth conversation experience. It fully supports Markdown rendering, including code highlighting, LaTex formulas, Mermaid flowcharts, and more.&lt;/li&gt; 
&lt;/ul&gt;  
&lt;blockquote&gt; 
 &lt;p&gt;✨ more features will be added when LobeHub evolve.&lt;/p&gt; 
&lt;/blockquote&gt; 
&lt;div align=&quot;right&quot;&gt; 
 &lt;p&gt;&lt;a href=&quot;#readme-top&quot;&gt;![][back-to-top]&lt;/a&gt;&lt;/p&gt; 
&lt;/div&gt; 
&lt;h2&gt;🛳 Self Hosting&lt;/h2&gt; 
&lt;p&gt;LobeHub provides Self-Hosted Version with Vercel, Alibaba Cloud, and &lt;a href=&quot;https://hub.docker.com/r/lobehub/lobehub&quot;&gt;Docker Image&lt;/a&gt;. This allows you to deploy your own chatbot within a few minutes without any prior knowledge.&lt;/p&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;[!TIP]&lt;/p&gt; 
 &lt;p&gt;Learn more about &lt;a href=&quot;https://lobehub.com/docs/self-hosting/start&quot;&gt;📘 Build your own LobeHub&lt;/a&gt; by checking it out.&lt;/p&gt; 
&lt;/blockquote&gt; 
&lt;h3&gt;&lt;code&gt;A&lt;/code&gt; Deploying with Vercel, Zeabur , Sealos or Alibaba Cloud&lt;/h3&gt; 
&lt;p&gt;&quot;If you want to deploy this service yourself on Vercel, Zeabur or Alibaba Cloud, you can follow these steps:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Prepare your &lt;a href=&quot;https://platform.openai.com/account/api-keys&quot;&gt;OpenAI API Key&lt;/a&gt;.&lt;/li&gt; 
 &lt;li&gt;Click the button below to start deployment: Log in directly with your GitHub account, and remember to fill in the &lt;code&gt;OPENAI_API_KEY&lt;/code&gt;(required) on the environment variable section.&lt;/li&gt; 
 &lt;li&gt;After deployment, you can start using it.&lt;/li&gt; 
 &lt;li&gt;Bind a custom domain (optional): The DNS of the domain assigned by Vercel is polluted in some areas; binding a custom domain can connect directly.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;div align=&quot;center&quot;&gt; 
 &lt;table&gt; 
  &lt;thead&gt; 
   &lt;tr&gt;
    &lt;th align=&quot;center&quot;&gt; Deploy with Vercel &lt;/th&gt;
    &lt;th align=&quot;center&quot;&gt; Deploy with Zeabur &lt;/th&gt;
    &lt;th align=&quot;center&quot;&gt; Deploy with Sealos &lt;/th&gt;
    &lt;th align=&quot;center&quot;&gt; Deploy with RepoCloud &lt;/th&gt;
    &lt;th align=&quot;center&quot;&gt; Deploy with Alibaba Cloud &lt;/th&gt;
   &lt;/tr&gt; 
  &lt;/thead&gt; 
  &lt;tbody&gt; 
   &lt;tr&gt;
    &lt;td align=&quot;center&quot;&gt; &lt;a href=&quot;https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2Flobehub%2Flobehub&amp;amp;env=OPENAI_API_KEY&amp;amp;envDescription=Find%20your%20OpenAI%20API%20Key%20by%20click%20the%20right%20Learn%20More%20button.&amp;amp;envLink=https%3A%2F%2Fplatform.openai.com%2Faccount%2Fapi-keys&amp;amp;project-name=lobehub&amp;amp;repository-name=lobehub&quot;&gt;&lt;img src=&quot;https://vercel.com/button&quot; alt=&quot;&quot;&gt;&lt;/a&gt; &lt;/td&gt;
    &lt;td align=&quot;center&quot;&gt; &lt;a href=&quot;https://zeabur.com/templates/VZGGTI&quot;&gt;&lt;img src=&quot;https://zeabur.com/button.svg&quot; alt=&quot;&quot;&gt;&lt;/a&gt; &lt;/td&gt;
    &lt;td align=&quot;center&quot;&gt; &lt;a href=&quot;https://template.usw.sealos.io/deploy?templateName=lobehub-db&quot;&gt;&lt;img src=&quot;https://raw.githubusercontent.com/labring-actions/templates/main/Deploy-on-Sealos.svg&quot; alt=&quot;&quot;&gt;&lt;/a&gt; &lt;/td&gt;
    &lt;td align=&quot;center&quot;&gt; &lt;a href=&quot;https://repocloud.io/details/?app_id=248&quot;&gt;&lt;img src=&quot;https://d16t0pc4846x52.cloudfront.net/deploylobe.svg&quot; alt=&quot;&quot;&gt;&lt;/a&gt; &lt;/td&gt;
    &lt;td align=&quot;center&quot;&gt; &lt;a href=&quot;https://computenest.console.aliyun.com/service/instance/create/default?type=user&amp;amp;ServiceName=LobeHub%E7%A4%BE%E5%8C%BA%E7%89%88&quot;&gt;&lt;img src=&quot;https://service-info-public.oss-cn-hangzhou.aliyuncs.com/computenest-en.svg&quot; alt=&quot;&quot;&gt;&lt;/a&gt; &lt;/td&gt;
   &lt;/tr&gt; 
  &lt;/tbody&gt; 
 &lt;/table&gt; 
&lt;/div&gt; 
&lt;h4&gt;After Fork&lt;/h4&gt; 
&lt;p&gt;After fork, only retain the upstream sync action and disable other actions in your repository on GitHub.&lt;/p&gt; 
&lt;h4&gt;Keep Updated&lt;/h4&gt; 
&lt;p&gt;If you have deployed your own project following the one-click deployment steps in the README, you might encounter constant prompts indicating &quot;updates available.&quot; This is because Vercel defaults to creating a new project instead of forking this one, resulting in an inability to detect updates accurately.&lt;/p&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;[!TIP]&lt;/p&gt; 
 &lt;p&gt;We suggest you redeploy using the following steps, &lt;a href=&quot;https://lobehub.com/docs/self-hosting/advanced/upstream-sync&quot;&gt;📘 Auto Sync With Latest&lt;/a&gt;&lt;/p&gt; 
&lt;/blockquote&gt; 
&lt;p&gt;&lt;br&gt;&lt;/p&gt; 
&lt;h3&gt;&lt;code&gt;B&lt;/code&gt; Deploying with Docker&lt;/h3&gt; 
&lt;p&gt;&lt;a href=&quot;https://hub.docker.com/r/lobehub/lobehub&quot;&gt;&lt;img src=&quot;https://img.shields.io/docker/v/lobehub/lobehub?color=369eff&amp;amp;label=docker&amp;amp;labelColor=black&amp;amp;logo=docker&amp;amp;logoColor=white&amp;amp;style=flat-square&amp;amp;sort=semver&quot; alt=&quot;&quot;&gt;&lt;/a&gt;&lt;br&gt; &lt;a href=&quot;https://hub.docker.com/r/lobehub/lobehub&quot;&gt;&lt;img src=&quot;https://img.shields.io/docker/image-size/lobehub/lobehub?color=369eff&amp;amp;labelColor=black&amp;amp;style=flat-square&amp;amp;sort=semver&quot; alt=&quot;&quot;&gt;&lt;/a&gt;&lt;br&gt; &lt;a href=&quot;https://hub.docker.com/r/lobehub/lobehub&quot;&gt;&lt;img src=&quot;https://img.shields.io/docker/pulls/lobehub/lobehub?color=45cc11&amp;amp;labelColor=black&amp;amp;style=flat-square&amp;amp;sort=semver&quot; alt=&quot;&quot;&gt;&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;We provide a Docker image for deploying the LobeHub service on your own private device. Use the following command to start the LobeHub service:&lt;/p&gt; 
&lt;ol&gt; 
 &lt;li&gt;create a folder to for storage files&lt;/li&gt; 
&lt;/ol&gt; 
&lt;pre&gt;&lt;code class=&quot;language-fish&quot;&gt;$ mkdir lobehub-db &amp;amp;&amp;amp; cd lobehub-db
&lt;/code&gt;&lt;/pre&gt; 
&lt;ol&gt; 
 &lt;li&gt;init the LobeHub infrastructure&lt;/li&gt; 
&lt;/ol&gt; 
&lt;pre&gt;&lt;code class=&quot;language-fish&quot;&gt;bash &amp;lt;(curl -fsSL https://lobe.li/setup.sh)
&lt;/code&gt;&lt;/pre&gt; 
&lt;ol&gt; 
 &lt;li&gt;Start the LobeHub service&lt;/li&gt; 
&lt;/ol&gt; 
&lt;pre&gt;&lt;code class=&quot;language-fish&quot;&gt;docker compose up -d
&lt;/code&gt;&lt;/pre&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;[!NOTE]&lt;/p&gt; 
 &lt;p&gt;For detailed instructions on deploying with Docker, please refer to the &lt;a href=&quot;https://lobehub.com/docs/self-hosting/server-database/docker-compose&quot;&gt;📘 Docker Deployment Guide&lt;/a&gt;&lt;/p&gt; 
&lt;/blockquote&gt; 
&lt;p&gt;&lt;br&gt;&lt;/p&gt; 
&lt;h3&gt;Environment Variable&lt;/h3&gt; 
&lt;p&gt;This project provides some additional configuration items set with environment variables:&lt;/p&gt; 
&lt;table&gt; 
 &lt;thead&gt; 
  &lt;tr&gt;
   &lt;th&gt; Environment Variable &lt;/th&gt;
   &lt;th&gt; Required &lt;/th&gt;
   &lt;th&gt; Description &lt;/th&gt;
   &lt;th&gt; Example &lt;/th&gt;
  &lt;/tr&gt; 
 &lt;/thead&gt; 
 &lt;tbody&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;OPENAI_API_KEY&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Yes &lt;/td&gt;
   &lt;td&gt; This is the API key you apply on the OpenAI account page &lt;/td&gt;
   &lt;td&gt; &lt;code&gt;sk-xxxxxx...xxxxxx&lt;/code&gt; &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;OPENAI_PROXY_URL&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; No &lt;/td&gt;
   &lt;td&gt; If you manually configure the OpenAI interface proxy, you can use this configuration item to override the default OpenAI API request base URL &lt;/td&gt;
   &lt;td&gt; &lt;code&gt;https://api.chatanywhere.cn&lt;/code&gt; or &lt;code&gt;https://aihubmix.com/v1&lt;/code&gt; &lt;br&gt;The default value is&lt;br&gt;&lt;code&gt;https://api.openai.com/v1&lt;/code&gt; &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;OPENAI_MODEL_LIST&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; No &lt;/td&gt;
   &lt;td&gt; Used to control the model list. Use &lt;code&gt;+&lt;/code&gt; to add a model, &lt;code&gt;-&lt;/code&gt; to hide a model, and &lt;code&gt;model_name=display_name&lt;/code&gt; to customize the display name of a model, separated by commas. &lt;/td&gt;
   &lt;td&gt; &lt;code&gt;qwen-7b-chat,+glm-6b,-gpt-3.5-turbo&lt;/code&gt; &lt;/td&gt;
  &lt;/tr&gt; 
 &lt;/tbody&gt; 
&lt;/table&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;[!NOTE]&lt;/p&gt; 
 &lt;p&gt;The complete list of environment variables can be found in the &lt;a href=&quot;https://lobehub.com/docs/self-hosting/environment-variables&quot;&gt;📘 Environment Variables&lt;/a&gt;&lt;/p&gt; 
&lt;/blockquote&gt; 
&lt;div align=&quot;right&quot;&gt; 
 &lt;p&gt;&lt;a href=&quot;#readme-top&quot;&gt;![][back-to-top]&lt;/a&gt;&lt;/p&gt; 
&lt;/div&gt; 
&lt;h2&gt;📦 Ecosystem&lt;/h2&gt; 
&lt;table&gt; 
 &lt;thead&gt; 
  &lt;tr&gt;
   &lt;th&gt; NPM &lt;/th&gt;
   &lt;th&gt; Repository &lt;/th&gt;
   &lt;th&gt; Description &lt;/th&gt;
   &lt;th&gt; Version &lt;/th&gt;
  &lt;/tr&gt; 
 &lt;/thead&gt; 
 &lt;tbody&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;a href=&quot;https://www.npmjs.com/package/@lobehub/ui&quot;&gt;@lobehub/ui&lt;/a&gt; &lt;/td&gt;
   &lt;td&gt; &lt;a href=&quot;https://github.com/lobehub/lobe-ui&quot;&gt;lobehub/lobe-ui&lt;/a&gt; &lt;/td&gt;
   &lt;td&gt; Open-source UI component library dedicated to building AIGC web applications. &lt;/td&gt;
   &lt;td&gt; &lt;a href=&quot;https://www.npmjs.com/package/@lobehub/ui&quot;&gt;&lt;img src=&quot;https://img.shields.io/npm/v/@lobehub/ui?color=369eff&amp;amp;labelColor=black&amp;amp;logo=npm&amp;amp;logoColor=white&amp;amp;style=flat-square&quot; alt=&quot;&quot;&gt;&lt;/a&gt; &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;a href=&quot;https://www.npmjs.com/package/@lobehub/icons&quot;&gt;@lobehub/icons&lt;/a&gt; &lt;/td&gt;
   &lt;td&gt; &lt;a href=&quot;https://github.com/lobehub/lobe-icons&quot;&gt;lobehub/lobe-icons&lt;/a&gt; &lt;/td&gt;
   &lt;td&gt; Popular AI / LLM Model Brand SVG Logo and Icon Collection. &lt;/td&gt;
   &lt;td&gt; &lt;a href=&quot;https://www.npmjs.com/package/@lobehub/icons&quot;&gt;&lt;img src=&quot;https://img.shields.io/npm/v/@lobehub/icons?color=369eff&amp;amp;labelColor=black&amp;amp;logo=npm&amp;amp;logoColor=white&amp;amp;style=flat-square&quot; alt=&quot;&quot;&gt;&lt;/a&gt; &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;a href=&quot;https://www.npmjs.com/package/@lobehub/tts&quot;&gt;@lobehub/tts&lt;/a&gt; &lt;/td&gt;
   &lt;td&gt; &lt;a href=&quot;https://github.com/lobehub/lobe-tts&quot;&gt;lobehub/lobe-tts&lt;/a&gt; &lt;/td&gt;
   &lt;td&gt; High-quality &amp;amp; reliable TTS/STT React Hooks library &lt;/td&gt;
   &lt;td&gt; &lt;a href=&quot;https://www.npmjs.com/package/@lobehub/tts&quot;&gt;&lt;img src=&quot;https://img.shields.io/npm/v/@lobehub/tts?color=369eff&amp;amp;labelColor=black&amp;amp;logo=npm&amp;amp;logoColor=white&amp;amp;style=flat-square&quot; alt=&quot;&quot;&gt;&lt;/a&gt; &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;a href=&quot;https://www.npmjs.com/package/@lobehub/lint&quot;&gt;@lobehub/lint&lt;/a&gt; &lt;/td&gt;
   &lt;td&gt; &lt;a href=&quot;https://github.com/lobehub/lobe-lint&quot;&gt;lobehub/lobe-lint&lt;/a&gt; &lt;/td&gt;
   &lt;td&gt; Configurations for ESlint, Stylelint, Commitlint, Prettier, Remark, and Semantic Release for LobeHub. &lt;/td&gt;
   &lt;td&gt; &lt;a href=&quot;https://www.npmjs.com/package/@lobehub/lint&quot;&gt;&lt;img src=&quot;https://img.shields.io/npm/v/@lobehub/lint?color=369eff&amp;amp;labelColor=black&amp;amp;logo=npm&amp;amp;logoColor=white&amp;amp;style=flat-square&quot; alt=&quot;&quot;&gt;&lt;/a&gt; &lt;/td&gt;
  &lt;/tr&gt; 
 &lt;/tbody&gt; 
&lt;/table&gt; 
&lt;div align=&quot;right&quot;&gt; 
 &lt;p&gt;&lt;a href=&quot;#readme-top&quot;&gt;![][back-to-top]&lt;/a&gt;&lt;/p&gt; 
&lt;/div&gt; 
&lt;h2&gt;🧩 Plugins&lt;/h2&gt; 
&lt;p&gt;Plugins provide a means to extend the &lt;a href=&quot;https://lobehub.com/blog/openai-function-call&quot;&gt;Function Calling&lt;/a&gt; capabilities of LobeHub. They can be used to introduce new function calls and even new ways to render message results. If you are interested in plugin development, please refer to our &lt;a href=&quot;https://lobehub.com/docs/usage/plugins/development&quot;&gt;📘 Plugin Development Guide&lt;/a&gt; in the Wiki.&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/lobehub/lobe-chat-plugins&quot;&gt;lobe-chat-plugins&lt;/a&gt;: This is the plugin index for LobeHub. It accesses index.json from this repository to display a list of available plugins for LobeHub to the user.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/lobehub/chat-plugin-template&quot;&gt;chat-plugin-template&lt;/a&gt;: This is the plugin template for LobeHub plugin development.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/lobehub/chat-plugin-sdk&quot;&gt;@lobehub/chat-plugin-sdk&lt;/a&gt;: The LobeHub Plugin SDK assists you in creating exceptional chat plugins for LobeHub.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/lobehub/chat-plugins-gateway&quot;&gt;@lobehub/chat-plugins-gateway&lt;/a&gt;: The LobeHub Plugins Gateway is a backend service that provides a gateway for LobeHub plugins. We deploy this service using Vercel. The primary API POST /api/v1/runner is deployed as an Edge Function.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;[!NOTE]&lt;/p&gt; 
 &lt;p&gt;The plugin system is currently undergoing major development. You can learn more in the following issues:&lt;/p&gt; 
 &lt;ul&gt; 
  &lt;li&gt;[x] &lt;a href=&quot;https://github.com/lobehub/lobehub/issues/73&quot;&gt;&lt;strong&gt;Plugin Phase 1&lt;/strong&gt;&lt;/a&gt;: Implement separation of the plugin from the main body, split the plugin into an independent repository for maintenance, and realize dynamic loading of the plugin.&lt;/li&gt; 
  &lt;li&gt;[x] &lt;a href=&quot;https://github.com/lobehub/lobehub/issues/97&quot;&gt;&lt;strong&gt;Plugin Phase 2&lt;/strong&gt;&lt;/a&gt;: The security and stability of the plugin&apos;s use, more accurately presenting abnormal states, the maintainability of the plugin architecture, and developer-friendly.&lt;/li&gt; 
  &lt;li&gt;[x] &lt;a href=&quot;https://github.com/lobehub/lobehub/issues/149&quot;&gt;&lt;strong&gt;Plugin Phase 3&lt;/strong&gt;&lt;/a&gt;: Higher-level and more comprehensive customization capabilities, support for plugin authentication, and examples.&lt;/li&gt; 
 &lt;/ul&gt; 
&lt;/blockquote&gt; 
&lt;div align=&quot;right&quot;&gt; 
 &lt;p&gt;&lt;a href=&quot;#readme-top&quot;&gt;![][back-to-top]&lt;/a&gt;&lt;/p&gt; 
&lt;/div&gt; 
&lt;h2&gt;🔗 More Products&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;strong&gt;&lt;a href=&quot;https://github.com/lobehub/sd-webui-lobe-theme&quot;&gt;🅰️ Lobe SD Theme&lt;/a&gt;:&lt;/strong&gt; Modern theme for Stable Diffusion WebUI, exquisite interface design, highly customizable UI, and efficiency-boosting features.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;&lt;a href=&quot;https://github.com/lobehub/lobe-midjourney-webui&quot;&gt;⛵️ Lobe Midjourney WebUI&lt;/a&gt;:&lt;/strong&gt; WebUI for Midjourney, leverages AI to quickly generate a wide array of rich and diverse images from text prompts, sparking creativity and enhancing conversations.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;&lt;a href=&quot;https://github.com/lobehub/lobe-commit/tree/master/packages/lobe-i18n&quot;&gt;🌏 Lobe i18n&lt;/a&gt; :&lt;/strong&gt; Lobe i18n is an automation tool for the i18n (internationalization) translation process, powered by ChatGPT. It supports features such as automatic splitting of large files, incremental updates, and customization options for the OpenAI model, API proxy, and temperature.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;&lt;a href=&quot;https://github.com/lobehub/lobe-commit/tree/master/packages/lobe-commit&quot;&gt;💌 Lobe Commit&lt;/a&gt;:&lt;/strong&gt; Lobe Commit is a CLI tool that leverages Langchain/ChatGPT to generate Gitmoji-based commit messages.&lt;/li&gt; 
&lt;/ul&gt; &lt;!-- LINK GROUP --&gt;
	</description>
    </item>
    <item>
      <title>bash (command-line shell)</title>
      <link>https://tedneward.github.io/Research/tools/gnu/bash/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/gnu/bash/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.gnu.org/software/bash/&quot;&gt;GNU bash Website&lt;/a&gt; | &lt;a href=&quot;https://savannah.gnu.org/projects/bash/&quot;&gt;Source&lt;/a&gt; | &lt;a href=&quot;https://www.gnu.org/software/bash/manual/bash.pdf&quot;&gt;GNU Bash manual&lt;/a&gt;&lt;/p&gt; 
&lt;h2&gt;Reading, Places&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;http://tldp.org/LDP/abs/html/&quot;&gt;Advanced Bash-Scripting Guide&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://mywiki.wooledge.org/BashGuide&quot;&gt;Bash Guide&lt;/a&gt; - Maarten Billemont &lt;a href=&quot;http://s.ntnu.no/bashguide.pdf&quot;&gt;(PDF)&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.tldp.org/LDP/Bash-Beginners-Guide/html/&quot;&gt;Bash Guide for Beginners (2008)&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://wiki.bash-hackers.org/&quot;&gt;Bash-hackers wiki&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://goalkicker.com/BashBook/&quot;&gt;Bash Notes for Professionals&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://tldp.org/HOWTO/Bash-Prog-Intro-HOWTO.html&quot;&gt;BASH Programming (2000)&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.gnu.org/software/bash/manual/bashref.html&quot;&gt;Bash Reference Manual&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://web.archive.org/web/20180328183806/http://gdrcorelec.ups-tlse.fr/files/bash.pdf&quot;&gt;Bash tutorial&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://magpi.raspberrypi.org/books/command-line-second-edition/pdf/download&quot;&gt;Conquer the Command Line&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.softcover.io/read/fc6c09de/unix_commands&quot;&gt;Conquering the Command Line&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://devhints.io/bash&quot;&gt;Devhints&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.hypexr.org/bash_tutorial.php&quot;&gt;Getting Started with BASH&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://google.github.io/styleguide/shell.xml&quot;&gt;Google Shell Style Guide&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/bobbyiliev/introduction-to-bash-scripting&quot;&gt;Introduction to Bash Scripting&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://launchschool.com/books/command_line&quot;&gt;Introduction to the Command Line&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://learnxinyminutes.com/docs/bash/&quot;&gt;Learn bash in y minutes&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.freeos.com/guides/lsst/&quot;&gt;Linux Shell Scripting Tutorial - A Beginner&apos;s Handbook (2002)&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://bash.cyberciti.biz/guide/Main_Page&quot;&gt;Linux Shell Scripting Tutorial (LSST) v2.0&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://dev.to/dhupee/make-your-linux-terminal-enjoyable-to-use-3j47&quot;&gt;&quot;Make Your Linux Terminal Enjoyable to Use&quot;&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://wiki.bash-hackers.org/syntax/shellvars&quot;&gt;Shell vars&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.shellcheck.net/&quot;&gt;ShellCheck&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://devmanual.gentoo.org/tools-reference/bash/index.html&quot;&gt;shell - Standard Shell&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://slackbook.org&quot;&gt;Slackbook (2005)&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://guide.bash.academy&quot;&gt;The Bash Academy&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://linuxcommand.org/tlcl.php&quot;&gt;The Linux Command Line&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://linuxcommand.org/lc3_writing_shell_scripts.php&quot;&gt;Writing Shell Scripts&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Articles/Blogs/Essays&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.howtogeek.com/bash-variables-i-use-in-almost-every-script/&quot;&gt;7 Bash variables I use in almost every script&lt;/a&gt;:&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Supporting tools/projects&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://direnv.net/&quot;&gt;direnv&lt;/a&gt; (&lt;a href=&quot;https://github.com/direnv/direnv&quot;&gt;Source&lt;/a&gt;): unclutter your .profile&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.gnu.org/software/parallel/parallel.html&quot;&gt;parallel&lt;/a&gt;: build and execute shell command lines from standard input in parallel&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;&quot;Dotfiles&quot;&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;Seems like &lt;code&gt;.bash_profile&lt;/code&gt; gets loaded first if present, and if found, doesn&apos;t look for &lt;code&gt;.bashrc&lt;/code&gt; any further; &lt;code&gt;.bash_profile&lt;/code&gt; thus would need to directly source &lt;code&gt;.bashrc&lt;/code&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;&lt;code&gt;.bashrc&lt;/code&gt;:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;# see /usr/share/doc/bash/examples/startup-files (in the package bash-doc)
# for examples

# If not running interactively, don&apos;t do anything
case $- in
    *i*) ;;
      *) return;;
esac

# don&apos;t put duplicate lines or lines starting with space in the history.
# See bash(1) for more options
HISTCONTROL=ignoreboth

# append to the history file, don&apos;t overwrite it
shopt -s histappend

# for setting history length see HISTSIZE and HISTFILESIZE in bash(1)
HISTSIZE=1000
HISTFILESIZE=2000

# check the window size after each command and, if necessary,
# update the values of LINES and COLUMNS.
shopt -s checkwinsize

# If set, the pattern &quot;**&quot; used in a pathname expansion context will
# match all files and zero or more directories and subdirectories.
#shopt -s globstar

# make less more friendly for non-text input files, see lesspipe(1)
[ -x /usr/bin/lesspipe ] &amp;amp;&amp;amp; eval &quot;$(SHELL=/bin/sh lesspipe)&quot;

# set variable identifying the chroot you work in (used in the prompt below)
if [ -z &quot;${debian_chroot:-}&quot; ] &amp;amp;&amp;amp; [ -r /etc/debian_chroot ]; then
    debian_chroot=$(cat /etc/debian_chroot)
fi

# set a fancy prompt (non-color, unless we know we &quot;want&quot; color)
case &quot;$TERM&quot; in
    xterm-color|*-256color) color_prompt=yes;;
esac

# uncomment for a colored prompt, if the terminal has the capability; turned
# off by default to not distract the user: the focus in a terminal window
# should be on the output of commands, not on the prompt
#force_color_prompt=yes

if [ -n &quot;$force_color_prompt&quot; ]; then
    if [ -x /usr/bin/tput ] &amp;amp;&amp;amp; tput setaf 1 &amp;gt;&amp;amp;/dev/null; then
        # We have color support; assume it&apos;s compliant with Ecma-48
        # (ISO/IEC-6429). (Lack of such support is extremely rare, and such
        # a case would tend to support setf rather than setaf.)
        color_prompt=yes
    else
        color_prompt=
    fi
fi

if [ &quot;$color_prompt&quot; = yes ]; then
    PS1=&apos;${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ &apos;
else
    PS1=&apos;${debian_chroot:+($debian_chroot)}\u@\h:\w\$ &apos;
fi
unset color_prompt force_color_prompt

# If this is an xterm set the title to user@host:dir
case &quot;$TERM&quot; in
xterm*|rxvt*)
    PS1=&quot;\[\e]0;${debian_chroot:+($debian_chroot)}\u@\h: \w\a\]$PS1&quot;
    ;;
*)
    ;;
esac

# enable color support of ls and also add handy aliases
if [ -x /usr/bin/dircolors ]; then
    test -r ~/.dircolors &amp;amp;&amp;amp; eval &quot;$(dircolors -b ~/.dircolors)&quot; || eval &quot;$(dircolors -b)&quot;
    alias ls=&apos;ls --color=auto&apos;
    #alias dir=&apos;dir --color=auto&apos;
    #alias vdir=&apos;vdir --color=auto&apos;

    alias grep=&apos;grep --color=auto&apos;
    alias fgrep=&apos;fgrep --color=auto&apos;
    alias egrep=&apos;egrep --color=auto&apos;
fi

# colored GCC warnings and errors
#export GCC_COLORS=&apos;error=01;31:warning=01;35:note=01;36:caret=01;32:locus=01:quote=01&apos;

# some more ls aliases
alias ll=&apos;ls -alF&apos;
alias la=&apos;ls -A&apos;
alias l=&apos;ls -CF&apos;

# Add an &quot;alert&quot; alias for long running commands.  Use like so:
#   sleep 10; alert
alias alert=&apos;notify-send --urgency=low -i &quot;$([ $? = 0 ] &amp;amp;&amp;amp; echo terminal || echo error)&quot; &quot;$(history|tail -n1|sed -e &apos;\&apos;&apos;s/^\s*[0-9]\+\s*//;s/[;&amp;amp;|]\s*alert$//&apos;\&apos;&apos;)&quot;&apos;

# Alias definitions.
# You may want to put all your additions into a separate file like
# ~/.bash_aliases, instead of adding them here directly.
# See /usr/share/doc/bash-doc/examples in the bash-doc package.

if [ -f ~/.bash_aliases ]; then
    . ~/.bash_aliases
fi

# enable programmable completion features (you don&apos;t need to enable
# this, if it&apos;s already enabled in /etc/bash.bashrc and /etc/profile
# sources /etc/bash.bashrc).
if ! shopt -oq posix; then
  if [ -f /usr/share/bash-completion/bash_completion ]; then
    . /usr/share/bash-completion/bash_completion
  elif [ -f /etc/bash_completion ]; then
    . /etc/bash_completion
  fi
fi

LS_COLORS=$LS_COLORS:&apos;di=0;35:ln=36&apos; ; export LS_COLORS
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;&lt;code&gt;.dircolors&lt;/code&gt;: I think we can generate this, but here&apos;s the color scheme I&apos;ve found best (personally) for WSL and native-Linux bash.&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;# Configuration file for dircolors, a utility to help you set the
# LS_COLORS environment variable used by GNU ls with the --color option.
# Copyright (C) 1996-2023 Free Software Foundation, Inc.
# Copying and distribution of this file, with or without modification,
# are permitted provided the copyright notice and this notice are preserved.
#
# The keywords COLOR, OPTIONS, and EIGHTBIT (honored by the
# slackware version of dircolors) are recognized but ignored.
# Global config options can be specified before TERM or COLORTERM entries
# ===================================================================
# Terminal filters
# ===================================================================
# Below are TERM or COLORTERM entries, which can be glob patterns, which
# restrict following config to systems with matching environment variables.
COLORTERM ?*
TERM Eterm
TERM ansi
TERM *color*
TERM con[0-9]*x[0-9]*
TERM cons25
TERM console
TERM cygwin
TERM *direct*
TERM dtterm
TERM gnome
TERM hurd
TERM jfbterm
TERM konsole
TERM kterm
TERM linux
TERM linux-c
TERM mlterm
TERM putty
TERM rxvt*
TERM screen*
TERM st
TERM terminator
TERM tmux*
TERM vt100
TERM xterm*
# ===================================================================
# Basic file attributes
# ===================================================================
# Below are the color init strings for the basic file types.
# One can use codes for 256 or more colors supported by modern terminals.
# The default color codes use the capabilities of an 8 color terminal
# with some additional attributes as per the following codes:
# Attribute codes:
# 00=none 01=bold 04=underscore 05=blink 07=reverse 08=concealed
# Text color codes:
# 30=black 31=red 32=green 33=yellow 34=blue 35=magenta 36=cyan 37=white
# Background color codes:
# 40=black 41=red 42=green 43=yellow 44=blue 45=magenta 46=cyan 47=white
#NORMAL 00 # no color code at all
#FILE 00 # regular file: use no color at all
RESET 0 # reset to &quot;normal&quot; color
DIR 01;34 # directory
LINK 01;36 # symbolic link. (If you set this to &apos;target&apos; instead of a
 # numerical value, the color is as for the file pointed to.)
MULTIHARDLINK 00 # regular file with more than one link
FIFO 40;33 # pipe
SOCK 01;35 # socket
DOOR 01;35 # door
BLK 40;33;01 # block device driver
CHR 40;33;01 # character device driver
ORPHAN 40;31;01 # symlink to nonexistent file, or non-stat&apos;able file ...
MISSING 00 # ... and the files they point to
SETUID 37;41 # file that is setuid (u+s)
SETGID 30;43 # file that is setgid (g+s)
CAPABILITY 00 # file with capability (very expensive to lookup)
STICKY_OTHER_WRITABLE 30;42 # dir that is sticky and other-writable (+t,o+w)
OTHER_WRITABLE 34;107 # dir that is other-writable (o+w) and not sticky
STICKY 37;44 # dir with the sticky bit set (+t) and not other-writable
# This is for files with execute permission:
EXEC 01;32
# ===================================================================
# File extension attributes
# ===================================================================
# List any file extensions like &apos;.gz&apos; or &apos;.tar&apos; that you would like ls
# to color below. Put the suffix, a space, and the color init string.
# (and any comments you want to add after a &apos;#&apos;).
# Suffixes are matched case insensitively, but if you define different
# init strings for separate cases, those will be honored.
#
# If you use DOS-style suffixes, you may want to uncomment the following:
#.cmd 01;32 # executables (bright green)
#.exe 01;32
#.com 01;32
#.btm 01;32
#.bat 01;32
# Or if you want to color scripts even if they do not have the
# executable bit actually set.
#.sh 01;32
#.csh 01;32
# archives or compressed (bright red)
.tar 01;31
.tgz 01;31
.arc 01;31
.arj 01;31
.taz 01;31
.lha 01;31
.lz4 01;31
.lzh 01;31
.lzma 01;31
.tlz 01;31
.txz 01;31
.tzo 01;31
.t7z 01;31
.zip 01;31
.z 01;31
.dz 01;31
.gz 01;31
.lrz 01;31
.lz 01;31
.lzo 01;31
.xz 01;31
.zst 01;31
.tzst 01;31
.bz2 01;31
.bz 01;31
.tbz 01;31
.tbz2 01;31
.tz 01;31
.deb 01;31
.rpm 01;31
.jar 01;31
.war 01;31
.ear 01;31
.sar 01;31
.rar 01;31
.alz 01;31
.ace 01;31
.zoo 01;31
.cpio 01;31
.7z 01;31
.rz 01;31
.cab 01;31
.wim 01;31
.swm 01;31
.dwm 01;31
.esd 01;31
# image formats
.avif 01;35
.jpg 01;35
.jpeg 01;35
.mjpg 01;35
.mjpeg 01;35
.gif 01;35
.bmp 01;35
.pbm 01;35
.pgm 01;35
.ppm 01;35
.tga 01;35
.xbm 01;35
.xpm 01;35
.tif 01;35
.tiff 01;35
.png 01;35
.svg 01;35
.svgz 01;35
.mng 01;35
.pcx 01;35
.mov 01;35
.mpg 01;35
.mpeg 01;35
.m2v 01;35
.mkv 01;35
.webm 01;35
.webp 01;35
.ogm 01;35
.mp4 01;35
.m4v 01;35
.mp4v 01;35
.vob 01;35
.qt 01;35
.nuv 01;35
.wmv 01;35
.asf 01;35
.rm 01;35
.rmvb 01;35
.flc 01;35
.avi 01;35
.fli 01;35
.flv 01;35
.gl 01;35
.dl 01;35
.xcf 01;35
.xwd 01;35
.yuv 01;35
.cgm 01;35
.emf 01;35
# https://wiki.xiph.org/MIME_Types_and_File_Extensions
.ogv 01;35
.ogx 01;35
# audio formats
.aac 00;36
.au 00;36
.flac 00;36
.m4a 00;36
.mid 00;36
.midi 00;36
.mka 00;36
.mp3 00;36
.mpc 00;36
.ogg 00;36
.ra 00;36
.wav 00;36
# https://wiki.xiph.org/MIME_Types_and_File_Extensions
.oga 00;36
.opus 00;36
.spx 00;36
.xspf 00;36
# backup files
*~ 00;90
*# 00;90
.bak 00;90
.crdownload 00;90
.dpkg-dist 00;90
.dpkg-new 00;90
.dpkg-old 00;90
.dpkg-tmp 00;90
.old 00;90
.orig 00;90
.part 00;90
.rej 00;90
.rpmnew 00;90
.rpmorig 00;90
.rpmsave 00;90
.swp 00;90
.tmp 00;90
.ucf-dist 00;90
.ucf-new 00;90
.ucf-old 00;90
#
# Subsequent TERM or COLORTERM entries, can be used to add / override
# config specific to those matching environment variables.
&lt;/code&gt;&lt;/pre&gt; 
&lt;h2&gt;&lt;a href=&quot;https://github.com/Randy8080/reference/blob/main/bash.md&quot;&gt;Cheat sheet&lt;/a&gt;&lt;/h2&gt; 
&lt;h3&gt;Getting started&lt;/h3&gt; 
&lt;h3&gt;hello.sh&lt;/h3&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;#!/bin/bash

VAR=&quot;world&quot;
echo &quot;Hello $VAR!&quot; # =&amp;gt; Hello world!
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Execute the script&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-shell&quot;&gt;$ bash hello.sh
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;Variables&lt;/h3&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;NAME=&quot;John&quot;

echo ${NAME}    # =&amp;gt; John
echo $NAME      # =&amp;gt; John
echo &quot;$NAME&quot;    # =&amp;gt; John
echo &apos;$NAME&apos;    # =&amp;gt; $NAME
echo &quot;${NAME}!&quot; # =&amp;gt; John!

NAME = &quot;John&quot; # =&amp;gt; Error (about space)
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;Comments&lt;/h3&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;# This is an inline Bash comment.
&lt;/code&gt;&lt;/pre&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;: &apos;
This is a
very neat comment
in bash
&apos;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Multi-line comments use &lt;code&gt;:&apos;&lt;/code&gt; to open and &lt;code&gt;&apos;&lt;/code&gt; to close&lt;/p&gt; 
&lt;h3&gt;Arguments&lt;/h3&gt; 
&lt;table&gt; 
 &lt;thead&gt; 
  &lt;tr&gt;
   &lt;th&gt; Expression &lt;/th&gt;
   &lt;th&gt; Description &lt;/th&gt;
  &lt;/tr&gt; 
 &lt;/thead&gt; 
 &lt;tbody&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;$1&lt;/code&gt; … &lt;code&gt;$9&lt;/code&gt;&lt;/td&gt;
   &lt;td&gt; Parameter 1 ... 9 &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;$0&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Name of the script itself &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;$1&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; First argument &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;${10}&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Positional parameter 10 &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;$#&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Number of arguments &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;$$&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Process id of the shell &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;$*&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; All arguments &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;$@&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; All arguments, starting from first &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;$-&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Current options &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;$_&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Last argument of the previous command &lt;/td&gt;
  &lt;/tr&gt; 
 &lt;/tbody&gt; 
&lt;/table&gt; 
&lt;p&gt;See: &lt;a href=&quot;http://wiki.bash-hackers.org/syntax/shellvars#special_parameters_and_shell_variables&quot;&gt;Special parameters&lt;/a&gt;.&lt;/p&gt; 
&lt;h3&gt;Functions&lt;/h3&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;get_name() {
    echo &quot;John&quot;
}

echo &quot;You are $(get_name)&quot;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;See: &lt;a href=&quot;#functions-2&quot;&gt;Functions&lt;/a&gt;&lt;/p&gt; 
&lt;h3&gt;Conditionals {#conditionals-example}&lt;/h3&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;if [[ -z &quot;$string&quot; ]]; then
    echo &quot;String is empty&quot;
elif [[ -n &quot;$string&quot; ]]; then
    echo &quot;String is not empty&quot;
fi
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;See: &lt;a href=&quot;#conditionals-2&quot;&gt;Conditionals&lt;/a&gt;&lt;/p&gt; 
&lt;h3&gt;Brace expansion&lt;/h3&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;echo {A,B}.js
&lt;/code&gt;&lt;/pre&gt; 
&lt;hr&gt; 
&lt;table&gt; 
 &lt;thead&gt; 
  &lt;tr&gt;
   &lt;th&gt; Expression &lt;/th&gt;
   &lt;th&gt; Description &lt;/th&gt;
  &lt;/tr&gt; 
 &lt;/thead&gt; 
 &lt;tbody&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;{A,B}&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Same as &lt;code&gt;A B&lt;/code&gt; &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;{A,B}.js&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Same as &lt;code&gt;A.js B.js&lt;/code&gt; &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;{1..5}&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Same as &lt;code&gt;1 2 3 4 5&lt;/code&gt; &lt;/td&gt;
  &lt;/tr&gt; 
 &lt;/tbody&gt; 
&lt;/table&gt; 
&lt;p&gt;See: &lt;a href=&quot;http://wiki.bash-hackers.org/syntax/expansion/brace&quot;&gt;Brace expansion&lt;/a&gt;&lt;/p&gt; 
&lt;h3&gt;Shell execution&lt;/h3&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;echo &quot;I&apos;m in $(PWD)&quot;
# Same
echo &quot;I&apos;m in `pwd`&quot;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;See: &lt;a href=&quot;http://wiki.bash-hackers.org/syntax/expansion/cmdsubst&quot;&gt;Command substitution&lt;/a&gt;&lt;/p&gt; 
&lt;h2&gt;Parameter expansions {.cols-3}&lt;/h2&gt; 
&lt;h3&gt;Syntax {.row-span-2}&lt;/h3&gt; 
&lt;table&gt; 
 &lt;thead&gt; 
  &lt;tr&gt;
   &lt;th&gt; Code &lt;/th&gt;
   &lt;th&gt; Description &lt;/th&gt;
  &lt;/tr&gt; 
 &lt;/thead&gt; 
 &lt;tbody&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;${FOO%suffix}&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Remove suffix &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;${FOO#prefix}&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Remove prefix &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;${FOO%%suffix}&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Remove long suffix &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;${FOO##prefix}&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Remove long prefix &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;${FOO/from/to}&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Replace first match &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;${FOO//from/to}&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Replace all &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;${FOO/%from/to}&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Replace suffix &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;${FOO/#from/to}&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Replace prefix &lt;/td&gt;
  &lt;/tr&gt; 
 &lt;/tbody&gt; 
&lt;/table&gt; 
&lt;h4&gt;Substrings&lt;/h4&gt; 
&lt;table&gt; 
 &lt;thead&gt; 
  &lt;tr&gt;
   &lt;th&gt; Expression &lt;/th&gt;
   &lt;th&gt; Description &lt;/th&gt;
  &lt;/tr&gt; 
 &lt;/thead&gt; 
 &lt;tbody&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;${FOO:0:3}&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Substring &lt;em&gt;(position, length)&lt;/em&gt; &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;${FOO:(-3):3}&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Substring from the right &lt;/td&gt;
  &lt;/tr&gt; 
 &lt;/tbody&gt; 
&lt;/table&gt; 
&lt;h4&gt;Length&lt;/h4&gt; 
&lt;table&gt; 
 &lt;thead&gt; 
  &lt;tr&gt;
   &lt;th&gt; Expression &lt;/th&gt;
   &lt;th&gt; Description &lt;/th&gt;
  &lt;/tr&gt; 
 &lt;/thead&gt; 
 &lt;tbody&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;${#FOO}&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Length of &lt;code&gt;$FOO&lt;/code&gt; &lt;/td&gt;
  &lt;/tr&gt; 
 &lt;/tbody&gt; 
&lt;/table&gt; 
&lt;h4&gt;Default values&lt;/h4&gt; 
&lt;table&gt; 
 &lt;thead&gt; 
  &lt;tr&gt;
   &lt;th&gt; Expression &lt;/th&gt;
   &lt;th&gt; Description &lt;/th&gt;
  &lt;/tr&gt; 
 &lt;/thead&gt; 
 &lt;tbody&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;${FOO:-val}&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; &lt;code&gt;$FOO&lt;/code&gt;, or &lt;code&gt;val&lt;/code&gt; if unset &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;${FOO:=val}&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Set &lt;code&gt;$FOO&lt;/code&gt; to &lt;code&gt;val&lt;/code&gt; if unset &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;${FOO:+val}&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; &lt;code&gt;val&lt;/code&gt; if &lt;code&gt;$FOO&lt;/code&gt; is set &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;${FOO:?message}&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Show message and exit if &lt;code&gt;$FOO&lt;/code&gt; is unset &lt;/td&gt;
  &lt;/tr&gt; 
 &lt;/tbody&gt; 
&lt;/table&gt; 
&lt;h3&gt;Substitution&lt;/h3&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;echo ${food:-Cake}  #=&amp;gt; $food or &quot;Cake&quot;
&lt;/code&gt;&lt;/pre&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;STR=&quot;/path/to/foo.cpp&quot;
echo ${STR%.cpp}    # /path/to/foo
echo ${STR%.cpp}.o  # /path/to/foo.o
echo ${STR%/*}      # /path/to

echo ${STR##*.}     # cpp (extension)
echo ${STR##*/}     # foo.cpp (basepath)

echo ${STR#*/}      # path/to/foo.cpp
echo ${STR##*/}     # foo.cpp

echo ${STR/foo/bar} # /path/to/bar.cpp
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;Slicing&lt;/h3&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;name=&quot;John&quot;
echo ${name}           # =&amp;gt; John
echo ${name:0:2}       # =&amp;gt; Jo
echo ${name::2}        # =&amp;gt; Jo
echo ${name::-1}       # =&amp;gt; Joh
echo ${name:(-1)}      # =&amp;gt; n
echo ${name:(-2)}      # =&amp;gt; hn
echo ${name:(-2):2}    # =&amp;gt; hn

length=2
echo ${name:0:length}  # =&amp;gt; Jo
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;See: &lt;a href=&quot;http://wiki.bash-hackers.org/syntax/pe&quot;&gt;Parameter expansion&lt;/a&gt;&lt;/p&gt; 
&lt;h3&gt;basepath &amp;amp; dirpath&lt;/h3&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;SRC=&quot;/path/to/foo.cpp&quot;
&lt;/code&gt;&lt;/pre&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;BASEPATH=${SRC##*/}   
echo $BASEPATH  # =&amp;gt; &quot;foo.cpp&quot;


DIRPATH=${SRC%$BASEPATH}
echo $DIRPATH   # =&amp;gt; &quot;/path/to/&quot;
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;Transform&lt;/h3&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;STR=&quot;HELLO WORLD!&quot;
echo ${STR,}   # =&amp;gt; hELLO WORLD!
echo ${STR,,}  # =&amp;gt; hello world!

STR=&quot;hello world!&quot;
echo ${STR^}   # =&amp;gt; Hello world!
echo ${STR^^}  # =&amp;gt; HELLO WORLD!

ARR=(hello World)
echo &quot;${ARR[@],}&quot; # =&amp;gt; hello world
echo &quot;${ARR[@]^}&quot; # =&amp;gt; Hello World
&lt;/code&gt;&lt;/pre&gt; 
&lt;h2&gt;Arrays {.cols-3}&lt;/h2&gt; 
&lt;h3&gt;Defining arrays&lt;/h3&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;Fruits=(&apos;Apple&apos; &apos;Banana&apos; &apos;Orange&apos;)

Fruits[0]=&quot;Apple&quot;
Fruits[1]=&quot;Banana&quot;
Fruits[2]=&quot;Orange&quot;

ARRAY2=(foo{1..2}) # =&amp;gt; foo1 foo2
ARRAY3=({A..D})    # =&amp;gt; A B C D

# declare construct
declare -a Numbers=(1 2 3 4 5 6)
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;Indexing&lt;/h3&gt; 
&lt;table&gt; 
 &lt;thead&gt; 
  &lt;tr&gt;
   &lt;th&gt; - &lt;/th&gt;
   &lt;th&gt; - &lt;/th&gt;
  &lt;/tr&gt; 
 &lt;/thead&gt; 
 &lt;tbody&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;${Fruits[0]}&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; First element &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;${Fruits[-1]}&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Last element &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;${Fruits[*]}&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; All elements &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;${Fruits[@]}&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; All elements &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;${#Fruits[@]}&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Number of all &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;${#Fruits}&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Length of 1st &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;${#Fruits[3]}&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Length of nth &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;${Fruits[@]:3:2}&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Range &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;${!Fruits[@]}&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Keys of all &lt;/td&gt;
  &lt;/tr&gt; 
 &lt;/tbody&gt; 
&lt;/table&gt; 
&lt;h3&gt;Iteration&lt;/h3&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;Fruits=(&apos;Apple&apos; &apos;Banana&apos; &apos;Orange&apos;)

for e in &quot;${Fruits[@]}&quot;; do
    echo $e
done
&lt;/code&gt;&lt;/pre&gt; 
&lt;h4&gt;With index&lt;/h4&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;for i in &quot;${!Fruits[@]}&quot;; do
  printf &quot;%s\t%s\n&quot; &quot;$i&quot; &quot;${Fruits[$i]}&quot;
done

&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;Operations {.col-span-2}&lt;/h3&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;Fruits=(&quot;${Fruits[@]}&quot; &quot;Watermelon&quot;)     # Push
Fruits+=(&apos;Watermelon&apos;)                   # Also Push
Fruits=( ${Fruits[@]/Ap*/} )             # Remove by regex match
unset Fruits[2]                          # Remove one item
Fruits=(&quot;${Fruits[@]}&quot;)                  # Duplicate
Fruits=(&quot;${Fruits[@]}&quot; &quot;${Veggies[@]}&quot;)  # Concatenate
lines=(`cat &quot;logfile&quot;`)                  # Read from file
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;Arrays as arguments&lt;/h3&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;function extract()
{
    local -n myarray=$1
    local idx=$2
    echo &quot;${myarray[$idx]}&quot;
}
Fruits=(&apos;Apple&apos; &apos;Banana&apos; &apos;Orange&apos;)
extract Fruits 2     # =&amp;gt; Orangle
&lt;/code&gt;&lt;/pre&gt; 
&lt;h2&gt;Dictionaries {.cols-3}&lt;/h2&gt; 
&lt;h3&gt;Defining&lt;/h3&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;declare -A sounds
&lt;/code&gt;&lt;/pre&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;sounds[dog]=&quot;bark&quot;
sounds[cow]=&quot;moo&quot;
sounds[bird]=&quot;tweet&quot;
sounds[wolf]=&quot;howl&quot;
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;Working with dictionaries&lt;/h3&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;echo ${sounds[dog]} # Dog&apos;s sound
echo ${sounds[@]}   # All values
echo ${!sounds[@]}  # All keys
echo ${#sounds[@]}  # Number of elements
unset sounds[dog]   # Delete dog
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;Iteration&lt;/h3&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;for val in &quot;${sounds[@]}&quot;; do
    echo $val
done
&lt;/code&gt;&lt;/pre&gt; 
&lt;hr&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;for key in &quot;${!sounds[@]}&quot;; do
    echo $key
done
&lt;/code&gt;&lt;/pre&gt; 
&lt;h2&gt;Conditionals {.cols-3}&lt;/h2&gt; 
&lt;h3&gt;Integer conditions&lt;/h3&gt; 
&lt;table&gt; 
 &lt;thead&gt; 
  &lt;tr&gt;
   &lt;th&gt; Condition &lt;/th&gt;
   &lt;th&gt; Description &lt;/th&gt;
  &lt;/tr&gt; 
 &lt;/thead&gt; 
 &lt;tbody&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;[[ NUM -eq NUM ]]&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; &lt;yel&gt;
     Eq
    &lt;/yel&gt;ual &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;[[ NUM -ne NUM ]]&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; &lt;yel&gt;
     N
    &lt;/yel&gt;ot &lt;yel&gt;
     e
    &lt;/yel&gt;qual &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;[[ NUM -lt NUM ]]&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; &lt;yel&gt;
     L
    &lt;/yel&gt;ess &lt;yel&gt;
     t
    &lt;/yel&gt;han &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;[[ NUM -le NUM ]]&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; &lt;yel&gt;
     L
    &lt;/yel&gt;ess than or &lt;yel&gt;
     e
    &lt;/yel&gt;qual &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;[[ NUM -gt NUM ]]&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; &lt;yel&gt;
     G
    &lt;/yel&gt;reater &lt;yel&gt;
     t
    &lt;/yel&gt;han &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;[[ NUM -ge NUM ]]&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; &lt;yel&gt;
     G
    &lt;/yel&gt;reater than or &lt;yel&gt;
     e
    &lt;/yel&gt;qual &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;(( NUM &amp;lt; NUM ))&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Less than &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;(( NUM &amp;lt;= NUM ))&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Less than or equal &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;(( NUM &amp;gt; NUM ))&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Greater than &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;(( NUM &amp;gt;= NUM ))&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Greater than or equal &lt;/td&gt;
  &lt;/tr&gt; 
 &lt;/tbody&gt; 
&lt;/table&gt; 
&lt;h3&gt;String conditions&lt;/h3&gt; 
&lt;table&gt; 
 &lt;thead&gt; 
  &lt;tr&gt;
   &lt;th&gt; Condition &lt;/th&gt;
   &lt;th&gt; Description &lt;/th&gt;
  &lt;/tr&gt; 
 &lt;/thead&gt; 
 &lt;tbody&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;[[ -z STR ]]&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Empty string &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;[[ -n STR ]]&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; &lt;yel&gt;
     N
    &lt;/yel&gt;ot empty string &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;[[ STR == STR ]]&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Equal &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;[[ STR = STR ]]&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Equal (Same above) &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;[[ STR &amp;lt; STR ]]&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Less than &lt;em&gt;(ASCII)&lt;/em&gt; &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;[[ STR &amp;gt; STR ]]&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Greater than &lt;em&gt;(ASCII)&lt;/em&gt; &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;[[ STR != STR ]]&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Not Equal &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;[[ STR =~ STR ]]&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Regexp &lt;/td&gt;
  &lt;/tr&gt; 
 &lt;/tbody&gt; 
&lt;/table&gt; 
&lt;h3&gt;Example {.row-span-3}&lt;/h3&gt; 
&lt;h4&gt;String&lt;/h4&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;if [[ -z &quot;$string&quot; ]]; then
    echo &quot;String is empty&quot;
elif [[ -n &quot;$string&quot; ]]; then
    echo &quot;String is not empty&quot;
else
    echo &quot;This never happens&quot;
fi
&lt;/code&gt;&lt;/pre&gt; 
&lt;h4&gt;Combinations&lt;/h4&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;if [[ X &amp;amp;&amp;amp; Y ]]; then
    ...
fi
&lt;/code&gt;&lt;/pre&gt; 
&lt;h4&gt;Equal&lt;/h4&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;if [[ &quot;$A&quot; == &quot;$B&quot; ]]; then
    ...
fi
&lt;/code&gt;&lt;/pre&gt; 
&lt;h4&gt;Regex&lt;/h4&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;if [[ &apos;1. abc&apos; =~ ([a-z]+) ]]; then
    echo ${BASH_REMATCH[1]}
fi
&lt;/code&gt;&lt;/pre&gt; 
&lt;h4&gt;Smaller&lt;/h4&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;if (( $a &amp;lt; $b )); then
   echo &quot;$a is smaller than $b&quot;
fi
&lt;/code&gt;&lt;/pre&gt; 
&lt;h4&gt;Exists&lt;/h4&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;if [[ -e &quot;file.txt&quot; ]]; then
    echo &quot;file exists&quot;
fi
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;File conditions {.row-span-2}&lt;/h3&gt; 
&lt;table&gt; 
 &lt;thead&gt; 
  &lt;tr&gt;
   &lt;th&gt; Condition &lt;/th&gt;
   &lt;th&gt; Description &lt;/th&gt;
  &lt;/tr&gt; 
 &lt;/thead&gt; 
 &lt;tbody&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;[[ -e FILE ]]&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; &lt;yel&gt;
     E
    &lt;/yel&gt;xists &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;[[ -d FILE ]]&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; &lt;yel&gt;
     D
    &lt;/yel&gt;irectory &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;[[ -f FILE ]]&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; &lt;yel&gt;
     F
    &lt;/yel&gt;ile &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;[[ -h FILE ]]&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Symlink &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;[[ -s FILE ]]&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Size is &amp;gt; 0 bytes &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;[[ -r FILE ]]&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; &lt;yel&gt;
     R
    &lt;/yel&gt;eadable &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;[[ -w FILE ]]&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; &lt;yel&gt;
     W
    &lt;/yel&gt;ritable &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;[[ -x FILE ]]&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Executable &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;[[ f1 -nt f2 ]]&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; f1 &lt;yel&gt;
     n
    &lt;/yel&gt;ewer &lt;yel&gt;
     t
    &lt;/yel&gt;han f2 &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;[[ f1 -ot f2 ]]&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; f2 &lt;yel&gt;
     o
    &lt;/yel&gt;lder &lt;yel&gt;
     t
    &lt;/yel&gt;han f1 &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;[[ f1 -ef f2 ]]&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Same files &lt;/td&gt;
  &lt;/tr&gt; 
 &lt;/tbody&gt; 
&lt;/table&gt; 
&lt;h3&gt;More conditions&lt;/h3&gt; 
&lt;table&gt; 
 &lt;thead&gt; 
  &lt;tr&gt;
   &lt;th&gt; Condition &lt;/th&gt;
   &lt;th&gt; Description &lt;/th&gt;
  &lt;/tr&gt; 
 &lt;/thead&gt; 
 &lt;tbody&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;[[ -o noclobber ]]&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; If OPTION is enabled &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;[[ ! EXPR ]]&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Not &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;[[ X &amp;amp;&amp;amp; Y ]]&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; And &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;[[ X || Y ]]&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Or &lt;/td&gt;
  &lt;/tr&gt; 
 &lt;/tbody&gt; 
&lt;/table&gt; 
&lt;h3&gt;logical and, or&lt;/h3&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;if [ &quot;$1&quot; = &apos;y&apos; -a $2 -gt 0 ]; then
    echo &quot;yes&quot;
fi

if [ &quot;$1&quot; = &apos;n&apos; -o $2 -lt 0 ]; then
    echo &quot;no&quot;
fi
&lt;/code&gt;&lt;/pre&gt; 
&lt;h2&gt;Loops {.cols-3}&lt;/h2&gt; 
&lt;h3&gt;Basic for loop&lt;/h3&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;for i in /etc/rc.*; do
    echo $i
done
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;C-like for loop&lt;/h3&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;for ((i = 0 ; i &amp;lt; 100 ; i++)); do
    echo $i
done
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;Ranges {.row-span-2}&lt;/h3&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;for i in {1..5}; do
    echo &quot;Welcome $i&quot;
done
&lt;/code&gt;&lt;/pre&gt; 
&lt;h4&gt;With step size&lt;/h4&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;for i in {5..50..5}; do
    echo &quot;Welcome $i&quot;
done
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;Auto increment&lt;/h3&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;i=1
while [[ $i -lt 4 ]]; do
    echo &quot;Number: $i&quot;
    ((i++))
done
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;Auto decrement&lt;/h3&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;i=3
while [[ $i -gt 0 ]]; do
    echo &quot;Number: $i&quot;
    ((i--))
done
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;Continue&lt;/h3&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;for number in $(seq 1 3); do
    if [[ $number == 2 ]]; then
        continue;
    fi
    echo &quot;$number&quot;
done
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;Break&lt;/h3&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;for number in $(seq 1 3); do
    if [[ $number == 2 ]]; then
        # Skip entire rest of loop.
        break;
    fi
    # This will only print 1
    echo &quot;$number&quot;
done
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;Until&lt;/h3&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;count=0
until [ $count -gt 10 ]; do
    echo &quot;$count&quot;
    ((count++))
done
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;Forever&lt;/h3&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;while true; do
    # here is some code.
done
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;Forever (shorthand)&lt;/h3&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;while :; do
    # here is some code.
done
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;Reading lines&lt;/h3&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;cat file.txt | while read line; do
    echo $line
done
&lt;/code&gt;&lt;/pre&gt; 
&lt;h2&gt;Functions {.cols-3}&lt;/h2&gt; 
&lt;h3&gt;Defining functions&lt;/h3&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;myfunc() {
    echo &quot;hello $1&quot;
}
&lt;/code&gt;&lt;/pre&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;# Same as above (alternate syntax)
function myfunc() {
    echo &quot;hello $1&quot;
}
&lt;/code&gt;&lt;/pre&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;myfunc &quot;John&quot;
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;Returning values&lt;/h3&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;myfunc() {
    local myresult=&apos;some value&apos;
    echo $myresult
}
&lt;/code&gt;&lt;/pre&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;result=&quot;$(myfunc)&quot;
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;Raising errors&lt;/h3&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;myfunc() {
    return 1
}
&lt;/code&gt;&lt;/pre&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;if myfunc; then
    echo &quot;success&quot;
else
    echo &quot;failure&quot;
fi
&lt;/code&gt;&lt;/pre&gt; 
&lt;h2&gt;Options {.cols-2}&lt;/h2&gt; 
&lt;h3&gt;Options&lt;/h3&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;# Avoid overlay files
# (echo &quot;hi&quot; &amp;gt; foo)
set -o noclobber

# Used to exit upon error
# avoiding cascading errors
set -o errexit   

# Unveils hidden failures
set -o pipefail  

# Exposes unset variables
set -o nounset
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;Glob options&lt;/h3&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;# Non-matching globs are removed  
# (&apos;*.foo&apos; =&amp;gt; &apos;&apos;)
shopt -s nullglob   

# Non-matching globs throw errors
shopt -s failglob  

# Case insensitive globs
shopt -s nocaseglob 

# Wildcards match dotfiles 
# (&quot;*.sh&quot; =&amp;gt; &quot;.foo.sh&quot;)
shopt -s dotglob    

# Allow ** for recursive matches 
# (&apos;lib/**/*.rb&apos; =&amp;gt; &apos;lib/a/b/c.rb&apos;)
shopt -s globstar   
&lt;/code&gt;&lt;/pre&gt; 
&lt;h2&gt;History {.cols-2}&lt;/h2&gt; 
&lt;h3&gt;Commands&lt;/h3&gt; 
&lt;table&gt; 
 &lt;thead&gt; 
  &lt;tr&gt;
   &lt;th&gt; Command &lt;/th&gt;
   &lt;th&gt; Description &lt;/th&gt;
  &lt;/tr&gt; 
 &lt;/thead&gt; 
 &lt;tbody&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;history&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Show history &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;shopt -s histverify&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Don&apos;t execute expanded result immediately &lt;/td&gt;
  &lt;/tr&gt; 
 &lt;/tbody&gt; 
&lt;/table&gt; 
&lt;h3&gt;Expansions&lt;/h3&gt; 
&lt;table&gt; 
 &lt;thead&gt; 
  &lt;tr&gt;
   &lt;th&gt; Expression &lt;/th&gt;
   &lt;th&gt; Description &lt;/th&gt;
  &lt;/tr&gt; 
 &lt;/thead&gt; 
 &lt;tbody&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;!$&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Expand last parameter of most recent command &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;!*&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Expand all parameters of most recent command &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;!-n&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Expand &lt;code&gt;n&lt;/code&gt;th most recent command &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;!n&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Expand &lt;code&gt;n&lt;/code&gt;th command in history &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;!&amp;lt;command&amp;gt;&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Expand most recent invocation of command &lt;code&gt;&amp;lt;command&amp;gt;&lt;/code&gt; &lt;/td&gt;
  &lt;/tr&gt; 
 &lt;/tbody&gt; 
&lt;/table&gt; 
&lt;h3&gt;Operations&lt;/h3&gt; 
&lt;table&gt; 
 &lt;thead&gt; 
  &lt;tr&gt;
   &lt;th&gt; Code &lt;/th&gt;
   &lt;th&gt; Description &lt;/th&gt;
  &lt;/tr&gt; 
 &lt;/thead&gt; 
 &lt;tbody&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;!!&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Execute last command again &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;!!:s/&amp;lt;FROM&amp;gt;/&amp;lt;TO&amp;gt;/&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Replace first occurrence of &lt;code&gt;&amp;lt;FROM&amp;gt;&lt;/code&gt; to &lt;code&gt;&amp;lt;TO&amp;gt;&lt;/code&gt; in most recent command &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;!!:gs/&amp;lt;FROM&amp;gt;/&amp;lt;TO&amp;gt;/&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Replace all occurrences of &lt;code&gt;&amp;lt;FROM&amp;gt;&lt;/code&gt; to &lt;code&gt;&amp;lt;TO&amp;gt;&lt;/code&gt; in most recent command &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;!$:t&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Expand only basename from last parameter of most recent command &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;!$:h&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Expand only directory from last parameter of most recent command &lt;/td&gt;
  &lt;/tr&gt; 
 &lt;/tbody&gt; 
&lt;/table&gt; 
&lt;p&gt;&lt;code&gt;!!&lt;/code&gt; and &lt;code&gt;!$&lt;/code&gt; can be replaced with any valid expansion.&lt;/p&gt; 
&lt;h3&gt;Slices&lt;/h3&gt; 
&lt;table&gt; 
 &lt;thead&gt; 
  &lt;tr&gt;
   &lt;th&gt; Code &lt;/th&gt;
   &lt;th&gt; Description &lt;/th&gt;
  &lt;/tr&gt; 
 &lt;/thead&gt; 
 &lt;tbody&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;!!:n&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Expand only &lt;code&gt;n&lt;/code&gt;th token from most recent command (command is &lt;code&gt;0&lt;/code&gt;; first argument is &lt;code&gt;1&lt;/code&gt;) &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;!^&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Expand first argument from most recent command &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;!$&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Expand last token from most recent command &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;!!:n-m&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Expand range of tokens from most recent command &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;!!:n-$&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Expand &lt;code&gt;n&lt;/code&gt;th token to last from most recent command &lt;/td&gt;
  &lt;/tr&gt; 
 &lt;/tbody&gt; 
&lt;/table&gt; 
&lt;p&gt;&lt;code&gt;!!&lt;/code&gt; can be replaced with any valid expansion i.e. &lt;code&gt;!cat&lt;/code&gt;, &lt;code&gt;!-2&lt;/code&gt;, &lt;code&gt;!42&lt;/code&gt;, etc.&lt;/p&gt; 
&lt;h2&gt;Miscellaneous {.cols-3}&lt;/h2&gt; 
&lt;h3&gt;Numeric calculations&lt;/h3&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;$((a + 200))      # Add 200 to $a
&lt;/code&gt;&lt;/pre&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;$(($RANDOM%200))  # Random number 0..199
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;Subshells&lt;/h3&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;(cd somedir; echo &quot;I&apos;m now in $PWD&quot;)
pwd # still in first directory
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;Inspecting commands&lt;/h3&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;command -V cd
#=&amp;gt; &quot;cd is a function/alias/whatever&quot;
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;Redirection {.row-span-2 .col-span-2}&lt;/h3&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;python hello.py &amp;gt; output.txt   # stdout to (file)
python hello.py &amp;gt;&amp;gt; output.txt  # stdout to (file), append
python hello.py 2&amp;gt; error.log   # stderr to (file)
python hello.py 2&amp;gt;&amp;amp;1           # stderr to stdout
python hello.py 2&amp;gt;/dev/null    # stderr to (null)
python hello.py &amp;amp;&amp;gt;/dev/null    # stdout and stderr to (null)
&lt;/code&gt;&lt;/pre&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;python hello.py &amp;lt; foo.txt      # feed foo.txt to stdin for python
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;Source relative&lt;/h3&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;source &quot;${0%/*}/../share/foo.sh&quot;
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;Directory of script&lt;/h3&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;DIR=&quot;${0%/*}&quot;
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;Case/switch&lt;/h3&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;case &quot;$1&quot; in
    start | up)
    vagrant up
    ;;

    *)
    echo &quot;Usage: $0 {start|stop|ssh}&quot;
    ;;
esac
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;Trap errors {.col-span-2}&lt;/h3&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;trap &apos;echo Error at about $LINENO&apos; ERR
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;or&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;traperr() {
    echo &quot;ERROR: ${BASH_SOURCE[1]} at about ${BASH_LINENO[0]}&quot;
}

set -o errtrace
trap traperr ERR
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;printf&lt;/h3&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;printf &quot;Hello %s, I&apos;m %s&quot; Sven Olga
#=&amp;gt; &quot;Hello Sven, I&apos;m Olga

printf &quot;1 + 1 = %d&quot; 2
#=&amp;gt; &quot;1 + 1 = 2&quot;

printf &quot;Print a float: %f&quot; 2
#=&amp;gt; &quot;Print a float: 2.000000&quot;
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;Getting options {.col-span-2}&lt;/h3&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;while [[ &quot;$1&quot; =~ ^- &amp;amp;&amp;amp; ! &quot;$1&quot; == &quot;--&quot; ]]; do case $1 in
    -V | --version )
    echo $version
    exit
    ;;
    -s | --string )
    shift; string=$1
    ;;
    -f | --flag )
    flag=1
    ;;
esac; shift; done
if [[ &quot;$1&quot; == &apos;--&apos; ]]; then shift; fi
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;Check for command&apos;s result {.col-span-2}&lt;/h3&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;if ping -c 1 google.com; then
    echo &quot;It appears you have a working internet connection&quot;
fi
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;Special variables {.row-span-2}&lt;/h3&gt; 
&lt;table&gt; 
 &lt;thead&gt; 
  &lt;tr&gt;
   &lt;th&gt; Expression &lt;/th&gt;
   &lt;th&gt; Description &lt;/th&gt;
  &lt;/tr&gt; 
 &lt;/thead&gt; 
 &lt;tbody&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;$?&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Exit status of last task &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;$!&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; PID of last background task &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;$$&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; PID of shell &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;$0&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Filename of the shell script &lt;/td&gt;
  &lt;/tr&gt; 
 &lt;/tbody&gt; 
&lt;/table&gt; 
&lt;p&gt;See &lt;a href=&quot;http://wiki.bash-hackers.org/syntax/shellvars#special_parameters_and_shell_variables&quot;&gt;Special parameters&lt;/a&gt;.&lt;/p&gt; 
&lt;h3&gt;Grep check {.col-span-2}&lt;/h3&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;if grep -q &apos;foo&apos; ~/.bash_history; then
    echo &quot;You appear to have typed &apos;foo&apos; in the past&quot;
fi
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;Backslash escapes {.row-span-2}&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&amp;nbsp;&lt;/li&gt; 
 &lt;li&gt;!&lt;/li&gt; 
 &lt;li&gt;&quot;&lt;/li&gt; 
 &lt;li&gt;#&lt;/li&gt; 
 &lt;li&gt;&amp;amp;&lt;/li&gt; 
 &lt;li&gt;&apos;&lt;/li&gt; 
 &lt;li&gt;(&lt;/li&gt; 
 &lt;li&gt;)&lt;/li&gt; 
 &lt;li&gt;,&lt;/li&gt; 
 &lt;li&gt;;&lt;/li&gt; 
 &lt;li&gt;&amp;lt;&lt;/li&gt; 
 &lt;li&gt;&amp;gt;&lt;/li&gt; 
 &lt;li&gt;[&lt;/li&gt; 
 &lt;li&gt;|&lt;/li&gt; 
 &lt;li&gt;\&lt;/li&gt; 
 &lt;li&gt;]&lt;/li&gt; 
 &lt;li&gt;^&lt;/li&gt; 
 &lt;li&gt;{&lt;/li&gt; 
 &lt;li&gt;}&lt;/li&gt; 
 &lt;li&gt;`&lt;/li&gt; 
 &lt;li&gt;$&lt;/li&gt; 
 &lt;li&gt;*&lt;/li&gt; 
 &lt;li&gt;?&lt;br&gt; {.cols-4 .style-none}&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;Escape these special characters with &lt;code&gt;\&lt;/code&gt;&lt;/p&gt; 
&lt;h3&gt;Heredoc&lt;/h3&gt; 
&lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;cat &amp;lt;&amp;lt;END
hello world
END
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;Go to previous directory&lt;/h3&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;pwd # /home/user/foo
cd bar/
pwd # /home/user/foo/bar
cd -
pwd # /home/user/foo
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;Reading input&lt;/h3&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;echo -n &quot;Proceed? [y/n]: &quot;
read ans
echo $ans
&lt;/code&gt;&lt;/pre&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;read -n 1 ans    # Just one character
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;Conditional execution&lt;/h3&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;git commit &amp;amp;&amp;amp; git push
git commit || echo &quot;Commit failed&quot;
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;Strict mode&lt;/h3&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;set -euo pipefail
IFS=$&apos;\n\t&apos;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;See: &lt;a href=&quot;http://redsymbol.net/articles/unofficial-bash-strict-mode/&quot;&gt;Unofficial bash strict mode&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Goblin.tools</title>
      <link>https://tedneward.github.io/Research/tools/goblintools/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/goblintools/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://goblin.tools/&quot;&gt;Website&lt;/a&gt; | Android and iOS versions available | Closed source?&lt;/p&gt; 
&lt;p&gt;Tools: &lt;a href=&quot;https://goblin.tools/&quot;&gt;Magic ToDo&lt;/a&gt; | &lt;a href=&quot;https://goblin.tools/Formalizer&quot;&gt;Formalizer&lt;/a&gt; - Turn the spicy thoughts into classy ones, or vice versa | &lt;a href=&quot;https://goblin.tools/Judge&quot;&gt;Judge&lt;/a&gt; - am I misreading the tone of this? | &lt;a href=&quot;https://goblin.tools/Estimator&quot;&gt;Estimator&lt;/a&gt; - Just tell me how long this is probably gonna take | &lt;a href=&quot;https://goblin.tools/Compiler&quot;&gt;Compiler&lt;/a&gt; - Compile my braindump into a list of tasks | &lt;a href=&quot;https://goblin.tools/Chef&quot;&gt;Chef&lt;/a&gt; - What do I want for lunch today?&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Graphviz</title>
      <link>https://tedneward.github.io/Research/tools/graphviz/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/graphviz/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.graphviz.org/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://gitlab.com/graphviz/graphviz&quot;&gt;Source&lt;/a&gt; | &lt;a href=&quot;https://www.graphviz.org/documentation/&quot;&gt;Docs&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Hammerspoon</title>
      <link>https://tedneward.github.io/Research/tools/hammerspoon/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/hammerspoon/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.hammerspoon.org/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/Hammerspoon/hammerspoon&quot;&gt;Source&lt;/a&gt; | &lt;a href=&quot;https://www.hammerspoon.org/docs/index.html&quot;&gt;API Documentation&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Basically wires up a &lt;a href=&quot;/languages/lua&quot;&gt;Lua&lt;/a&gt; engine with the various APIs exposed by macOS applications.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Example: Hello World&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;In your init.lua place the following:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;hs.hotkey.bind({&quot;cmd&quot;, &quot;alt&quot;, &quot;ctrl&quot;}, &quot;W&quot;, function()
  hs.alert.show(&quot;Hello World!&quot;)
end)
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Then save the file, click on the Hammerspoon menubar icon and choose Reload Config. You should now find that pressing Cmd+Option+Ctrl+W will display a Hello World notification on your screen.&lt;/p&gt; 
&lt;p&gt;What is happening here is that we’re telling Hammerspoon to bind an anonymous function to a particular hotkey. The hotkey is specified by a table of modifier keys (Cmd, Option, and Ctrl in this case) and a normal key (W). An anonymous function is simply one that doesn’t have a name. We could have defined the alert function separately with a name and passed that name to &lt;code&gt;hs.hotkey.bind()&lt;/code&gt;, but Lua makes it easy to define the functions inline.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Hexo</title>
      <link>https://tedneward.github.io/Research/tools/hexo/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/hexo/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://hexo.io/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/hexojs/hexo&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Hopper (Disassembler)</title>
      <link>https://tedneward.github.io/Research/tools/hopper/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/hopper/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.hopperapp.com/&quot;&gt;Website&lt;/a&gt; | Commercial (free limited trial)&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>iced</title>
      <link>https://tedneward.github.io/Research/tools/iced/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/iced/index.html</guid>
      	<description>
	&lt;p&gt;It can be used for static analysis of x86/x64 binaries, to rewrite code (eg. remove garbage instructions), to relocate code or as a disassembler.&lt;/p&gt; 
&lt;p&gt;✔️Supports all Intel and AMD instructions&lt;br&gt; ✔️Supports .NET, Rust, JavaScript (WebAssembly)&lt;br&gt; ✔️The formatter supports masm, nasm, gas (AT&amp;amp;T), Intel (XED) and there are many options to customize the output&lt;br&gt; ✔️The decoder is 4x+ faster than other similar libraries and doesn&apos;t allocate any memory&lt;br&gt; ✔️Small decoded instructions, only 32 bytes&lt;br&gt; ✔️High level Assembler (.NET) providing a simple and lean syntax (e.g asm.mov(eax, edx)))&lt;br&gt; ✔️The encoder can be used to re-encode decoded instructions at any address&lt;br&gt; ✔️API to get instruction info, eg. read/written registers, memory and rflags bits; CPUID feature flag, flow control info, etc&lt;br&gt; ✔️All instructions are tested (decode, encode, format, instruction info)&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://github.com/0xd4d/iced&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>ILSpy</title>
      <link>https://tedneward.github.io/Research/tools/ilspy/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/ilspy/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;http://www.ilspy.net/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/icsharpcode/ILSpy&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>injectdso</title>
      <link>https://tedneward.github.io/Research/tools/injectdso/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/injectdso/index.html</guid>
      	<description>
	&lt;p&gt;It currently consists of injectdll (for Microsoft Windows), injectdylib (for MacOS X) and injectoid (for Android). Support for Linux (injectso) is planned for the near future as well.&lt;/p&gt; 
&lt;p&gt;injectdso may be useful for tasks like:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt; &lt;p&gt;Discovering and testing sandbox escape exploits&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Testing properties of heap allocators on closed source applications&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Hooking higher-level programming language runtimes&lt;/p&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;...and probably many more.&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://github.com/huku-/injectdso&quot;&gt;Github&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Jandex</title>
      <link>https://tedneward.github.io/Research/tools/jandex/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/jandex/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://smallrye.io/jandex/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/smallrye/jandex/&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>JBake</title>
      <link>https://tedneward.github.io/Research/tools/jbake/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/jbake/index.html</guid>
      	<description>
	&lt;p&gt;JBake is a Java based open source static site/blog generator for developers.&lt;br&gt; * Supports AsciiDoc, Markdown and good old HTML formatted content.&lt;br&gt; * Structure your content any way you see fit.&lt;br&gt; * RSS feed, archive and tag support.&lt;br&gt; * View draft content before publishing it and making it available to the world.&lt;br&gt; * Freemarker, Groovy, Thymeleaf &amp;amp; Jade based templates &amp;amp; scripting support.&lt;br&gt; * Easily integrate CSS frameworks such as Bootstrap and Foundation.&lt;br&gt; * Add as much metadata to content as you like, also exposed to templates.&lt;br&gt; * Store your site content in Dropbox, CVS, SVN, Git or whatever you want.&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;http://jbake.org/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/jbake-org/jbake&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>JDepend</title>
      <link>https://tedneward.github.io/Research/tools/jdepend/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/jdepend/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/clarkware/jdepend&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>JLex</title>
      <link>https://tedneward.github.io/Research/tools/jlex/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/jlex/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.cs.princeton.edu/~appel/modern/java/JLex/&quot;&gt;Website&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Last updated 2003.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>JXRay</title>
      <link>https://tedneward.github.io/Research/tools/jxray/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/jxray/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://jxray.com/&quot;&gt;Website&lt;/a&gt; Commercial&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Kitty</title>
      <link>https://tedneward.github.io/Research/tools/kitty/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/kitty/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://sw.kovidgoyal.net/kitty/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/kovidgoyal/kitty&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;h2&gt;Reading&lt;/h2&gt; 
&lt;h3&gt;Articles/Blogs/Essays&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.howtogeek.com/kitty-is-the-open-source-mac-terminal-that-iterm-wishes-it-could-be/&quot;&gt;Kitty is the open-source Mac terminal that iTerm wishes it could be&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Lazarus IDE</title>
      <link>https://tedneward.github.io/Research/tools/lazarus/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/lazarus/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.lazarus-ide.org/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://wiki.lazarus.freepascal.org/index.php/Getting_Lazarus&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Light Table (IDE)</title>
      <link>https://tedneward.github.io/Research/tools/lighttable/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/lighttable/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;http://lighttable.com/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/LightTable/LightTable&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>LiveRestore</title>
      <link>https://tedneward.github.io/Research/tools/liverestore/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/liverestore/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.system-rescue.org/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://www.system-rescue.org/Download/&quot;&gt;Download&lt;/a&gt; | &lt;a href=&quot;https://www.system-rescue.org/Installing-SystemRescue-on-a-USB-memory-stick/&quot;&gt;Bootable USB&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;A live bootable Linux environment packed with more than 300 utilities for unbootable Windows machines. It&apos;s under 1GB, so it&apos;s relatively lightweight on system resources and USB storage, allowing you to store more tools on the USB drive.&lt;/p&gt; 
&lt;p&gt;It shines where Windows tools struggle—like reading locked files or running raw disk diagnostics before attempting repairs. Unlike vendor recovery disks, which often wipe your system, SystemRescue preserves everything, allowing you to copy important files to external drives first.&lt;/p&gt; 
&lt;p&gt;It supports native access to Windows NTFS drives with the NTFS-3g driver and includes powerful utilities such as GParted for partition management, TestDisk for recovering deleted partitions, and ddrescue for cloning failing drives sector-by-sector right out of the box.&lt;/p&gt; 
&lt;p&gt;You can even launch Firefox to check for system and driver updates, or mount your PC to a network for backups. When your PC won&apos;t boot, is affected by ransomware, or is crashing randomly, SystemRescue is your go-to tool for data recovery and diagnosis. It’s versatile, fast, and doesn’t rely on the health of your Windows install, making it invaluable for serious recovery jobs via external storage.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Lombok (Project Lombok)</title>
      <link>https://tedneward.github.io/Research/tools/lombok/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/lombok/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://projectlombok.org/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/projectlombok/lombok&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>gdb (GNU debugger)</title>
      <link>https://tedneward.github.io/Research/tools/gdb/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/gdb/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.sourceware.org/gdb/current/onlinedocs/gdb.html&quot;&gt;Docs&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Ghostly</title>
      <link>https://tedneward.github.io/Research/tools/ghostly/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/ghostly/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://ghostlyapp.net/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/patriksvensson/ghostly&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;To get the most out of Ghostly, you can use the Ghostly Query Language (shortened GQL) to search among your pull request, issues, releases, vulnerabilities and commits. All queries made with GQL are local and does not require an internet connection.&lt;/p&gt; 
&lt;h3&gt;Examples&lt;/h3&gt; 
&lt;table&gt; 
 &lt;thead&gt; 
  &lt;tr&gt;
   &lt;th&gt;Query &lt;/th&gt;
   &lt;th&gt; Explanation&lt;/th&gt;
  &lt;/tr&gt; 
 &lt;/thead&gt; 
 &lt;tbody&gt; 
  &lt;tr&gt;
   &lt;td&gt;&lt;code&gt;(org:microsoft OR org:cake-build) AND is:pullrequest AND is:open&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Return all open pull requests that originiated in a repository belonging to either the microsoft or cake-build organisation.&lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt;&lt;code&gt;is:pullrequest AND is:open AND !muted AND mentions:patriksvensson&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Return all open pullrequests that you haven&apos;t muted that mentions the user patriksvensson in the comment.&lt;/td&gt;
  &lt;/tr&gt; 
 &lt;/tbody&gt; 
&lt;/table&gt;
	</description>
    </item>
    <item>
      <title>gitmal</title>
      <link>https://tedneward.github.io/Research/tools/gitmal/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/gitmal/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/antonmedv/gitmal&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Docker: &lt;code&gt;docker run --rm -v $(pwd):/repo antonmedv/gitmal /repo&lt;/code&gt;&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;code&gt;gitmal&lt;/code&gt; generates pages in &lt;code&gt;./output&lt;/code&gt; based on repo in the cwd&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;gitmal help&lt;/code&gt; to get list of available options&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;Here are a few examples of repos:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://git.medv.io/zx/&quot;&gt;git.medv.io/zx/&lt;/a&gt; — github.com/google/zx&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://git.medv.io/zig/&quot;&gt;git.medv.io/zig/&lt;/a&gt; — codeberg.org/ziglang/zig (light theme)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://git.medv.io/my-badges/&quot;&gt;git.medv.io/my-badges/&lt;/a&gt; — github.com/my-badges/my-badges&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Reading&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/antonmedv/gitmal/blob/master/docs/how-to-self-host-a-git-repository.md&quot;&gt;How to Self-Host a Git Repository?&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Gluon</title>
      <link>https://tedneward.github.io/Research/tools/gluonjs/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/gluonjs/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://gluonjs.org/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/gluon-framework/gluon&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>GENTLE Compiler Construction System</title>
      <link>https://tedneward.github.io/Research/tools/gentle/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/gentle/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;http://gentle.compilertools.net/&quot;&gt;Website&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Git</title>
      <link>https://tedneward.github.io/Research/tools/git/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/git/index.html</guid>
      	<description>
	&lt;p&gt;Just the tool itself; considered separate from &lt;a href=&quot;/clouds/github&quot;&gt;Github&lt;/a&gt; since it is used by a variety of other source-control providers like Bitbucket.&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://www.git-scm.com&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;http://git-scm.com/docs&quot;&gt;Docs&lt;/a&gt;&lt;/p&gt; 
&lt;h3&gt;Graphical cheat sheet&lt;/h3&gt; 
&lt;p&gt;&lt;img src=&quot;https://media.licdn.com/dms/image/D5622AQF8ksdiwWBvyw/feedshare-shrink_800/0/1684905537126?e=1689811200&amp;amp;v=beta&amp;amp;t=P5Pt5DenPxOmgJ_kUJ1-9fq8LykPNB6hrtbJO1_7AW4&quot; alt=&quot;&quot;&gt;&lt;/p&gt; 
&lt;h3&gt;Cheat sheet&lt;/h3&gt; 
&lt;p&gt;&lt;code&gt;git init&lt;/code&gt;: Create repository in directory&lt;/p&gt; 
&lt;p&gt;&lt;code&gt;git clone {url}&lt;/code&gt;: copy git repo at {url} to local machine&lt;/p&gt; 
&lt;p&gt;&lt;code&gt;git status&lt;/code&gt;: show modified files in repo&lt;/p&gt; 
&lt;p&gt;&lt;code&gt;git log&lt;/code&gt;: show commit history&lt;/p&gt; 
&lt;p&gt;&lt;code&gt;git add -A&lt;/code&gt;: add (stage) changed files for commit&lt;/p&gt; 
&lt;p&gt;&lt;code&gt;git commit -m &apos;message&apos;&lt;/code&gt;: commit changes using &apos;message&apos; as the commit message&lt;/p&gt; 
&lt;p&gt;&lt;code&gt;git pull origin main&lt;/code&gt;: get up to date changes from branch &quot;main&quot;&lt;/p&gt; 
&lt;p&gt;&lt;code&gt;git push origin main&lt;/code&gt;: push local changes to remote &quot;origin&quot; on branch &quot;main&quot;&lt;/p&gt; 
&lt;p&gt;&lt;code&gt;git branch&lt;/code&gt;: list all local branches&lt;/p&gt; 
&lt;p&gt;&lt;code&gt;git branch {branchname}&lt;/code&gt;: create a new branch&lt;/p&gt; 
&lt;p&gt;&lt;code&gt;git checkout {branchname}&lt;/code&gt;: switch from current branch to named branch&lt;/p&gt; 
&lt;p&gt;&lt;code&gt;git branch -m {newbranchname}&lt;/code&gt;: rename current branch&lt;/p&gt; 
&lt;p&gt;&lt;code&gt;git branch -d {branchname}&lt;/code&gt;: delete named branch&lt;/p&gt; 
&lt;p&gt;&lt;code&gt;git merge develop&lt;/code&gt;: merge branch &quot;develop&quot; into current branch&lt;/p&gt; 
&lt;p&gt;&lt;code&gt;git rm {filename}&lt;/code&gt;: delete (and stage) file&lt;/p&gt; 
&lt;p&gt;&lt;code&gt;git stash&lt;/code&gt;: save modified files and staged changes&lt;/p&gt; 
&lt;p&gt;&lt;code&gt;git diff {branch1} {branch2}&lt;/code&gt;: diff between named branches&lt;/p&gt; 
&lt;p&gt;&lt;code&gt;git rebase {branch}&lt;/code&gt;: put commits of current branch ahead of named branch&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;http://res.cloudinary.com/hy4kyit2a/image/upload/SF_git_cheatsheet.pdf&quot;&gt;SalesForce Cheat Sheet&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Reading&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.atlassian.com/git/&quot;&gt;Atlassian Git - Tutorials &amp;amp; Workflows&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://danielmiessler.com/study/git/&quot;&gt;A git Primer&lt;/a&gt; - Daniel Miessler&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://marklodato.github.io/visual-git-guide/index-en.html&quot;&gt;A Visual Git Reference&lt;/a&gt; - Mark Lodato&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://blog.anvard.org/conversational-git/&quot;&gt;Conversational Git&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://rogerdudler.github.io/git-guide/&quot;&gt;git - the simple guide&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://eagain.net/articles/git-for-computer-scientists/&quot;&gt;Git for Computer Scientists&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://hoth.entp.com/output/git_for_designers.html&quot;&gt;Git For Designers&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://jwiegley.github.io/git-from-the-bottom-up/&quot;&gt;Git From The Bottom Up&lt;/a&gt; - J. Wiegley&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://gitimmersion.com&quot;&gt;Git Immersion&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://cbx33.github.io/gitt/index.html&quot;&gt;Git In The Trenches&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/pluralsight/git-internals-pdf/raw/master/drafts/peepcode-git.pdf&quot;&gt;Git internals&lt;/a&gt; - Scott Chacon (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www-cs-students.stanford.edu/~blynn/gitmagic/&quot;&gt;Git Magic&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://goalkicker.com/GitBook&quot;&gt;Git Notes for Professionals&lt;/a&gt; - Compiled from StackOverflow Documentation (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.oreilly.com/library/view/git-pocket-guide/9781449327507&quot;&gt;Git Pocket Guide&lt;/a&gt; - Richard E. Silverman&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://web.archive.org/web/20170602211147/http://gitref.org/&quot;&gt;Git Reference&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.syncfusion.com/resources/techportal/ebooks/git&quot;&gt;Git Succinctly, Syncfusion&lt;/a&gt; (PDF, Kindle) (email address &lt;em&gt;requested&lt;/em&gt;, not required)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.tutorialspoint.com/git/&quot;&gt;Git Tutorial&lt;/a&gt; - Tutorials Point Ltd. (HTML)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://product.hubspot.com/blog/git-and-github-tutorial-for-beginners&quot;&gt;Git-Tutorial For-Beginners&lt;/a&gt; - HubSpot Product Team&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://web.archive.org/web/20210910133251/http://documentup.com/skwp/git-workflows-book&quot;&gt;Git Workflows&lt;/a&gt; - Yan Pritzker &lt;em&gt;(:card_file_box: archived)&lt;/em&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://happygitwithr.com&quot;&gt;Happy Git and GitHub for the useR&lt;/a&gt; - Jenny Bryan&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/eonist/How-to-collaborate-on-github&quot;&gt;How to Collaborate on Github&lt;/a&gt; - André J&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.freecodecamp.org/news/how-to-write-better-git-commit-messages/&quot;&gt;How to Write Better Git Commit Messages&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://launchschool.com/books/git&quot;&gt;Introduction to Git and Github&lt;/a&gt; - Launch School&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://cse.unl.edu/~cbourke/gitTutorial.pdf&quot;&gt;Introduction to Git and Github - Tutorial&lt;/a&gt; - Dr. Chris Bourke (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/bobbyiliev/introduction-to-git-and-github-ebook&quot;&gt;Introduction to Git and GitHub eBook&lt;/a&gt; - Bobby Iliev (Markdown, PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.git-tower.com/learn/git/ebook/command-line/introduction&quot;&gt;Learn Git - Learn Version Control with Git&lt;/a&gt; - Tobias Günther&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://ohmygit.org/&quot;&gt;Oh My Git!&lt;/a&gt; (&lt;a href=&quot;https://blinry.itch.io/oh-my-git&quot;&gt;Docs&lt;/a&gt;, &lt;a href=&quot;https://github.com/git-learning-game/oh-my-git&quot;&gt;Source&lt;/a&gt;): an open source Git learning game&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://git-scm.com/book/en/v2&quot;&gt;Pro Git&lt;/a&gt; - Scott Chacon&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://leanpub.com/progitreedited/read&quot;&gt;Pro Git Reedited&lt;/a&gt; - Jon Forrest&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://web.archive.org/web/20161121145226/http://rypress.com:80/tutorials/git/index&quot;&gt;Ry&apos;s Git Tutorial&lt;/a&gt; - Ryan Hodson&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://think-like-a-git.net&quot;&gt;Think Like (a) Git: A Guide for the Perplexed&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://blog.stackademic.com/git-rebase-explained-like-youre-new-to-git-263c19fa86ec&quot;&gt;https://blog.stackademic.com/git-rebase-explained-like-youre-new-to-git-263c19fa86ec&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://andrewlock.net/working-with-stacked-branches-in-git-part-1/&quot;&gt;Working with Stacked Branches in Git&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Articles, Blogs, Essays&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.howtogeek.com/i-turned-git-into-a-private-github-free-sync-system-between-my-own-machines-and-it-completely-changed-how-i-work/&quot;&gt;How to sync files between two local machines using Git&lt;/a&gt; - Basic git hosting over SSH&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Websites&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.gitguys.com/&quot;&gt;GitGuys&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://learngitbranching.js.org/&quot;&gt;Learn Git Branching - the most visual and interactive way to learn Git on the web&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://try.github.io/levels/1/challenges/1&quot;&gt;tryGit - A fun interactive way to learn Git.&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://gitjin.com/t&quot;&gt;GitJin&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Videos&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;http://git-scm.com/videos&quot;&gt;git-scm - Video Tutorials&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/playlist?list=PL6gx4Cwl9DGAKWClAD_iKpNC0bGHxGhcx&quot;&gt;The New Boston tutorial to Git covering basic commands and workflow&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Libraries&lt;/h3&gt; 
&lt;h3&gt;C/Native&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://libgit2.org/&quot;&gt;libgit2&lt;/a&gt;: a portable, pure C implementation of the Git core methods&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;JVM&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.gitblit.com/&quot;&gt;Gitblit&lt;/a&gt;: an &lt;a href=&quot;https://github.com/gitblit-org/gitblit&quot;&gt;open-source&lt;/a&gt;, pure Java stack for managing, viewing, and serving Git repositories&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/eclipse-jgit/jgit&quot;&gt;jgit&lt;/a&gt;: the Java implementation of git&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Python&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/gitpython-developers/GitPython&quot;&gt;Git-Python&lt;/a&gt;: Python library used to interact with Git repositories&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;CLR&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/libgit2/libgit2sharp&quot;&gt;libgit2sharp&lt;/a&gt;: Git + .NET&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;ECMAscript&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://isomorphic-git.org/&quot;&gt;isomorphic-git&lt;/a&gt; (&lt;a href=&quot;https://github.com/isomorphic-git/isomorphic-git&quot;&gt;Source&lt;/a&gt;): A pure JavaScript implementation of git for node and browsers&lt;/li&gt; 
&lt;/ul&gt; 
&lt;hr&gt; 
&lt;h1&gt;&lt;a href=&quot;https://learnxinyminutes.com/docs/git/&quot;&gt;Learn X in Y Minutes&lt;/a&gt;&lt;/h1&gt; 
&lt;p&gt;Git is a distributed version control and source code management system.&lt;/p&gt; 
&lt;p&gt;It does this through a series of snapshots of your project, and it works with those snapshots to provide you with functionality to version and manage your source code.&lt;/p&gt; 
&lt;h2&gt;Git Architecture&lt;/h2&gt; 
&lt;h3&gt;Repository&lt;/h3&gt; 
&lt;p&gt;A set of files, directories, historical records, commits, and heads. Imagine it as a source code data structure, with the attribute that each source code &quot;element&quot; gives you access to its revision history, among other things.&lt;/p&gt; 
&lt;p&gt;A git repository is comprised of the .git directory &amp;amp; working tree.&lt;/p&gt; 
&lt;h4&gt;.git Directory (component of repository)&lt;/h4&gt; 
&lt;p&gt;The .git directory contains all the configurations, logs, branches, HEAD, and more. &lt;a href=&quot;http://gitready.com/advanced/2009/03/23/whats-inside-your-git-directory.html&quot;&gt;Detailed List.&lt;/a&gt;&lt;/p&gt; 
&lt;h4&gt;Working Tree (component of repository)&lt;/h4&gt; 
&lt;p&gt;This is basically the directories and files in your repository. It is often referred to as your working directory.&lt;/p&gt; 
&lt;h3&gt;Index (component of .git dir)&lt;/h3&gt; 
&lt;p&gt;The Index is the staging area in git. It&apos;s basically a layer that separates your working tree from the Git repository. This gives developers more power over what gets sent to the Git repository.&lt;/p&gt; 
&lt;h3&gt;Commit&lt;/h3&gt; 
&lt;p&gt;A git commit is a snapshot of a set of changes, or manipulations to your Working Tree. For example, if you added 5 files, and removed 2 others, these changes will be contained in a commit (or snapshot). This commit can then be pushed to other repositories, or not!&lt;/p&gt; 
&lt;h3&gt;Branch&lt;/h3&gt; 
&lt;p&gt;A branch is essentially a pointer to the last commit you made. As you go on committing, this pointer will automatically update to point to the latest commit.&lt;/p&gt; 
&lt;h3&gt;Tag&lt;/h3&gt; 
&lt;p&gt;A tag is a mark on specific point in history. Typically people use this functionality to mark release points (v1.0, and so on).&lt;/p&gt; 
&lt;h3&gt;HEAD and head (component of .git dir)&lt;/h3&gt; 
&lt;p&gt;HEAD is a pointer that points to the current branch. A repository only has 1 &lt;em&gt;active&lt;/em&gt; HEAD. head is a pointer that points to any commit. A repository can have any number of heads.&lt;/p&gt; 
&lt;h3&gt;Stages of Git&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;Modified - Changes have been made to a file but file has not been committed to Git Database yet&lt;/li&gt; 
 &lt;li&gt;Staged - Marks a modified file to go into your next commit snapshot&lt;/li&gt; 
 &lt;li&gt;Committed - Files have been committed to the Git Database&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Commands&lt;/h2&gt; 
&lt;h3&gt;init&lt;/h3&gt; 
&lt;p&gt;Create an empty Git repository. The Git repository&apos;s settings, stored&lt;br&gt; information, and more is stored in a directory (a folder) named &quot;.git&quot;.&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;$ git init
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;config&lt;/h3&gt; 
&lt;p&gt;To configure settings. Whether it be for the repository, the system itself,&lt;br&gt; or global configurations ( global config file is &lt;code&gt;~/.gitconfig&lt;/code&gt; ).&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;# Print &amp;amp; Set Some Basic Config Variables (Global)
$ git config --global user.email &quot;MyEmail@Zoho.com&quot;
$ git config --global user.name &quot;My Name&quot;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;&lt;a href=&quot;http://git-scm.com/docs/git-config&quot;&gt;Learn More About git config.&lt;/a&gt;&lt;/p&gt; 
&lt;h3&gt;help&lt;/h3&gt; 
&lt;p&gt;To give you quick access to an extremely detailed guide of each command. Or to&lt;br&gt; just give you a quick reminder of some semantics.&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;# Quickly check available commands
$ git help

# Check all available commands
$ git help -a

# Command specific help - user manual
# git help &amp;lt;command_here&amp;gt;
$ git help add
$ git help commit
$ git help init
# or git &amp;lt;command_here&amp;gt; --help
$ git add --help
$ git commit --help
$ git init --help
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;ignore files&lt;/h3&gt; 
&lt;p&gt;To intentionally untrack file(s) &amp;amp; folder(s) from git. Typically meant for&lt;br&gt; private &amp;amp; temp files which would otherwise be shared in the repository.&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;$ echo &quot;temp/&quot; &amp;gt;&amp;gt; .gitignore
$ echo &quot;private_key&quot; &amp;gt;&amp;gt; .gitignore
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;status&lt;/h3&gt; 
&lt;p&gt;To show differences between the index file (basically your working copy/repo)&lt;br&gt; and the current HEAD commit.&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;# Will display the branch, untracked files, changes and other differences
$ git status

# To learn other &quot;tid bits&quot; about git status
$ git help status
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;add&lt;/h3&gt; 
&lt;p&gt;To add files to the staging area/index. If you do not &lt;code&gt;git add&lt;/code&gt; new files to&lt;br&gt; the staging area/index, they will not be included in commits!&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;# add a file in your current working directory
$ git add HelloWorld.java

# add a file in a nested dir
$ git add /path/to/file/HelloWorld.c

# Regular Expression support!
$ git add ./*.java

# You can also add everything in your working directory to the staging area.
$ git add -A
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;This only adds a file to the staging area/index, it doesn&apos;t commit it to the&lt;br&gt; working directory/repo.&lt;/p&gt; 
&lt;h3&gt;branch&lt;/h3&gt; 
&lt;p&gt;Manage your branches. You can view, edit, create, delete branches using this&lt;br&gt; command.&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;# list existing branches &amp;amp; remotes
$ git branch -a

# create a new branch
$ git branch myNewBranch

# delete a branch
$ git branch -d myBranch

# rename a branch
# git branch -m &amp;lt;oldname&amp;gt; &amp;lt;newname&amp;gt;
$ git branch -m myBranchName myNewBranchName

# edit a branch&apos;s description
$ git branch myBranchName --edit-description
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;tag&lt;/h3&gt; 
&lt;p&gt;Manage your tags&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;# List tags
$ git tag

# Create a annotated tag
# The -m specifies a tagging message, which is stored with the tag.
# If you don’t specify a message for an annotated tag,
# Git launches your editor so you can type it in.
$ git tag -a v2.0 -m &apos;my version 2.0&apos;

# Show info about tag
# That shows the tagger information, the date the commit was tagged,
# and the annotation message before showing the commit information.
$ git show v2.0

# Push a single tag to remote
$ git push origin v2.0

# Push a lot of tags to remote
$ git push origin --tags
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;checkout&lt;/h3&gt; 
&lt;p&gt;Updates all files in the working tree to match the version in the index, or&lt;br&gt; specified tree.&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;# Checkout a repo - defaults to master branch
$ git checkout

# Checkout a specified branch
$ git checkout branchName

# Create a new branch &amp;amp; switch to it
# equivalent to &quot;git branch &amp;lt;name&amp;gt;; git checkout &amp;lt;name&amp;gt;&quot;

$ git checkout -b newBranch
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;clone&lt;/h3&gt; 
&lt;p&gt;Clones, or copies, an existing repository into a new directory. It also adds&lt;br&gt; remote-tracking branches for each branch in the cloned repo, which allows you&lt;br&gt; to push to a remote branch.&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;# Clone learnxinyminutes-docs
$ git clone https://github.com/adambard/learnxinyminutes-docs.git

# shallow clone - faster cloning that pulls only latest snapshot
$ git clone --depth 1 https://github.com/adambard/learnxinyminutes-docs.git

# clone only a specific branch
$ git clone -b master-cn https://github.com/adambard/learnxinyminutes-docs.git --single-branch
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;commit&lt;/h3&gt; 
&lt;p&gt;Stores the current contents of the index in a new &quot;commit.&quot; This commit&lt;br&gt; contains the changes made and a message created by the user.&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;# commit with a message
$ git commit -m &quot;Added multiplyNumbers() function to HelloWorld.c&quot;

# signed commit with a message (user.signingkey must have been set
# with your GPG key e.g. git config --global user.signingkey 5173AAD5)
$ git commit -S -m &quot;signed commit message&quot;

# automatically stage modified or deleted files, except new files, and then commit
$ git commit -a -m &quot;Modified foo.php and removed bar.php&quot;

# change last commit (this deletes previous commit with a fresh commit)
$ git commit --amend -m &quot;Correct message&quot;
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;diff&lt;/h3&gt; 
&lt;p&gt;Shows differences between a file in the working directory, index and commits.&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;# Show difference between your working dir and the index
$ git diff

# Show differences between the index and the most recent commit.
$ git diff --cached

# Show differences between your working dir and the most recent commit
$ git diff HEAD
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;grep&lt;/h3&gt; 
&lt;p&gt;Allows you to quickly search a repository.&lt;/p&gt; 
&lt;p&gt;Optional Configurations:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;# Thanks to Travis Jeffery for these
# Set line numbers to be shown in grep search results
$ git config --global grep.lineNumber true

# Make search results more readable, including grouping
$ git config --global alias.g &quot;grep --break --heading --line-number&quot;
&lt;/code&gt;&lt;/pre&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;# Search for &quot;variableName&quot; in all java files
$ git grep &apos;variableName&apos; -- &apos;*.java&apos;

# Search for a line that contains &quot;arrayListName&quot; and, &quot;add&quot; or &quot;remove&quot;
$ git grep -e &apos;arrayListName&apos; --and \( -e add -e remove \)
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Google is your friend; for more examples&lt;br&gt; &lt;a href=&quot;http://travisjeffery.com/b/2012/02/search-a-git-repo-like-a-ninja&quot;&gt;Git Grep Ninja&lt;/a&gt;&lt;/p&gt; 
&lt;h3&gt;log&lt;/h3&gt; 
&lt;p&gt;Display commits to the repository.&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;# Show all commits
$ git log

# Show only commit message &amp;amp; ref
$ git log --oneline

# Show merge commits only
$ git log --merges

# Show all commits represented by an ASCII graph
$ git log --graph
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;merge&lt;/h3&gt; 
&lt;p&gt;&quot;Merge&quot; in changes from external commits into the current branch.&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;# Merge the specified branch into the current.
$ git merge branchName

# Always generate a merge commit when merging
$ git merge --no-ff branchName
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;mv&lt;/h3&gt; 
&lt;p&gt;Rename or move a file&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;# Renaming a file
$ git mv HelloWorld.c HelloNewWorld.c

# Moving a file
$ git mv HelloWorld.c ./new/path/HelloWorld.c

# Force rename or move
# &quot;existingFile&quot; already exists in the directory, will be overwritten
$ git mv -f myFile existingFile
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;pull&lt;/h3&gt; 
&lt;p&gt;Pulls from a repository and merges it with another branch.&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;# Update your local repo, by merging in new changes
# from the remote &quot;origin&quot; and &quot;master&quot; branch.
# git pull &amp;lt;remote&amp;gt; &amp;lt;branch&amp;gt;
$ git pull origin master

# By default, git pull will update your current branch
# by merging in new changes from its remote-tracking branch
$ git pull

# Merge in changes from remote branch and rebase
# branch commits onto your local repo, like: &quot;git fetch &amp;lt;remote&amp;gt; &amp;lt;branch&amp;gt;, git
# rebase &amp;lt;remote&amp;gt;/&amp;lt;branch&amp;gt;&quot;
$ git pull origin master --rebase
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;push&lt;/h3&gt; 
&lt;p&gt;Push and merge changes from a branch to a remote &amp;amp; branch.&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;# Push and merge changes from a local repo to a
# remote named &quot;origin&quot; and &quot;master&quot; branch.
# git push &amp;lt;remote&amp;gt; &amp;lt;branch&amp;gt;
$ git push origin master

# By default, git push will push and merge changes from
# the current branch to its remote-tracking branch
$ git push

# To link up current local branch with a remote branch, add -u flag:
$ git push -u origin master
# Now, anytime you want to push from that same local branch, use shortcut:
$ git push
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;stash&lt;/h3&gt; 
&lt;p&gt;Stashing takes the dirty state of your working directory and saves it on a&lt;br&gt; stack of unfinished changes that you can reapply at any time.&lt;/p&gt; 
&lt;p&gt;Let&apos;s say you&apos;ve been doing some work in your git repo, but you want to pull&lt;br&gt; from the remote. Since you have dirty (uncommitted) changes to some files, you&lt;br&gt; are not able to run &lt;code&gt;git pull&lt;/code&gt;. Instead, you can run &lt;code&gt;git stash&lt;/code&gt; to save your&lt;br&gt; changes onto a stack!&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;$ git stash
Saved working directory and index state \
  &quot;WIP on master: 049d078 added the index file&quot;
  HEAD is now at 049d078 added the index file
  (To restore them type &quot;git stash apply&quot;)
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Now you can pull!&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;git pull
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;&lt;code&gt;...changes apply...&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;Now check that everything is OK&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;$ git status
# On branch master
nothing to commit, working directory clean
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;You can see what &quot;hunks&quot; you&apos;ve stashed so far using &lt;code&gt;git stash list&lt;/code&gt;. Since the &quot;hunks&quot; are stored in a Last-In-First-Out stack, our most recent change will be at top.&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;$ git stash list
stash@{0}: WIP on master: 049d078 added the index file
stash@{1}: WIP on master: c264051 Revert &quot;added file_size&quot;
stash@{2}: WIP on master: 21d80a5 added number to log
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Now let&apos;s apply our dirty changes back by popping them off the stack.&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;$ git stash pop
# On branch master
# Changes not staged for commit:
#   (use &quot;git add &amp;lt;file&amp;gt;...&quot; to update what will be committed)
#
#      modified:   index.html
#      modified:   lib/simplegit.rb
#
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;&lt;code&gt;git stash apply&lt;/code&gt; does the same thing. Now you&apos;re ready to get back to work on your stuff! &lt;a href=&quot;http://git-scm.com/book/en/v2/Git-Tools-Stashing&quot;&gt;Additional Reading.&lt;/a&gt;&lt;/p&gt; 
&lt;h3&gt;rebase (caution)&lt;/h3&gt; 
&lt;p&gt;Take all changes that were committed on one branch, and replay them onto another branch. &lt;em&gt;Do not rebase commits that you have pushed to a public repo&lt;/em&gt;.&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;# Rebase experimentBranch onto master
# git rebase &amp;lt;basebranch&amp;gt; &amp;lt;topicbranch&amp;gt;
$ git rebase master experimentBranch
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;&lt;a href=&quot;http://git-scm.com/book/en/Git-Branching-Rebasing&quot;&gt;Additional Reading.&lt;/a&gt;&lt;/p&gt; 
&lt;h3&gt;reset (caution)&lt;/h3&gt; 
&lt;p&gt;Reset the current HEAD to the specified state. This allows you to undo merges, pulls, commits, adds, and more. It&apos;s a great command but also dangerous if you don&apos;t know what you are doing.&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;# Reset the staging area, to match the latest commit (leaves dir unchanged)
$ git reset

# Reset the staging area, to match the latest commit, and overwrite working dir
$ git reset --hard

# Moves the current branch tip to the specified commit (leaves dir unchanged)
# all changes still exist in the directory.
$ git reset 31f2bb1

# Moves the current branch tip backward to the specified commit
# and makes the working dir match (deletes uncommitted changes and all commits
# after the specified commit).
$ git reset --hard 31f2bb1
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;reflog (caution)&lt;/h3&gt; 
&lt;p&gt;Reflog will list most of the git commands you have done for a given time period, default 90 days.&lt;/p&gt; 
&lt;p&gt;This give you the chance to reverse any git commands that have gone wrong (for instance, if a rebase has broken your application).&lt;/p&gt; 
&lt;p&gt;You can do this:&lt;/p&gt; 
&lt;ol&gt; 
 &lt;li&gt;&lt;code&gt;git reflog&lt;/code&gt; to list all of the git commands for the rebase&lt;/li&gt; 
&lt;/ol&gt; 
&lt;pre&gt;&lt;code&gt;38b323f HEAD@{0}: rebase -i (finish): returning to refs/heads/feature/add_git_reflog
38b323f HEAD@{1}: rebase -i (pick): Clarify inc/dec operators
4fff859 HEAD@{2}: rebase -i (pick): Update java.html.markdown
34ed963 HEAD@{3}: rebase -i (pick): [yaml/en] Add more resources (#1666)
ed8ddf2 HEAD@{4}: rebase -i (pick): pythonstatcomp spanish translation (#1748)
2e6c386 HEAD@{5}: rebase -i (start): checkout 02fb96d
&lt;/code&gt;&lt;/pre&gt; 
&lt;ol&gt; 
 &lt;li&gt;Select where to reset to, in our case its &lt;code&gt;2e6c386&lt;/code&gt;, or &lt;code&gt;HEAD@{5}&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;&apos;git reset --hard HEAD@{5}&apos; this will reset your repo to that head&lt;/li&gt; 
 &lt;li&gt;You can start the rebase again or leave it alone.&lt;/li&gt; 
&lt;/ol&gt; 
&lt;p&gt;&lt;a href=&quot;https://git-scm.com/docs/git-reflog&quot;&gt;Additional Reading.&lt;/a&gt;&lt;/p&gt; 
&lt;h3&gt;revert&lt;/h3&gt; 
&lt;p&gt;Revert can be used to undo a commit. It should not be confused with reset which restores the state of a project to a previous point. Revert will add a new commit which is the inverse of the specified commit, thus reverting it.&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;# Revert a specified commit
$ git revert &amp;lt;commit&amp;gt;
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;rm&lt;/h3&gt; 
&lt;p&gt;The opposite of git add, git rm removes files from the current working tree.&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;# remove HelloWorld.c
$ git rm HelloWorld.c

# Remove a file from a nested dir
$ git rm /pather/to/the/file/HelloWorld.c
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;Useful tidbits&lt;/h3&gt; 
&lt;p&gt;&lt;a href=&quot;https://twitter.com/cecilphillip/status/1493958954434584580&quot;&gt;&quot;Changing your default branch name from master in Git is easy. Do it now&quot;&lt;/a&gt;: &lt;code&gt;git config --global init.defaultBranch main&lt;/code&gt;&lt;/p&gt; 
&lt;h1&gt;Notes from the Git website&lt;/h1&gt; 
&lt;h2&gt;Branching and Merging&lt;/h2&gt; 
&lt;p&gt;&quot;The Git feature that really makes it stand apart from nearly every other SCM out there is its branching model. Git allows and encourages you to have multiple local branches that can be entirely independent of each other. The creation, merging, and deletion of those lines of development takes seconds.&lt;/p&gt; 
&lt;p&gt;This means that you can do things like:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt; &lt;p&gt;Frictionless Context Switching. Create a branch to try out an idea, commit a few times, switch back to where you branched from, apply a patch, switch back to where you are experimenting, and merge it in.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Role-Based Codelines. Have a branch that always contains only what goes to production, another that you merge work into for testing, and several smaller ones for day to day work.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Feature Based Workflow. Create new branches for each new feature you&apos;re working on so you can seamlessly switch back and forth between them, then delete each branch when that feature gets merged into your main line.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Disposable Experimentation. Create a branch to experiment in, realize it&apos;s not going to work, and just delete it - abandoning the work—with nobody else ever seeing it (even if you&apos;ve pushed other branches in the meantime).&lt;br&gt; Branches&lt;/p&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;Notably, when you push to a remote repository, you do not have to push all of your branches. You can choose to share just one of your branches, a few of them, or all of them. This tends to free people to try new ideas without worrying about having to plan how and when they are going to merge it in or share it with others.&lt;/p&gt; 
&lt;p&gt;There are ways to accomplish some of this with other systems, but the work involved is much more difficult and error-prone. Git makes this process incredibly easy and it changes the way most developers work when they learn it.&lt;/p&gt; 
&lt;h2&gt;Distributed&lt;/h2&gt; 
&lt;p&gt;One of the nicest features of any Distributed SCM, Git included, is that it&apos;s distributed. This means that instead of doing a &quot;checkout&quot; of the current tip of the source code, you do a &quot;clone&quot; of the entire repository.&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt; &lt;p&gt;&lt;em&gt;Multiple Backups&lt;/em&gt;: This means that even if you&apos;re using a centralized workflow, every user essentially has a full backup of the main server. Each of these copies could be pushed up to replace the main server in the event of a crash or corruption. In effect, there is no single point of failure with Git unless there is only a single copy of the repository.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;em&gt;Any Workflow&lt;/em&gt;: Because of Git&apos;s distributed nature and superb branching system, an almost endless number of workflows can be implemented with relative ease.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;em&gt;Subversion-Style Workflow&lt;/em&gt;: A centralized workflow is very common, especially from people transitioning from a centralized system. Git will not allow you to push if someone has pushed since the last time you fetched, so a centralized model where all developers push to the same server works just fine.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;em&gt;Integration Manager Workflow&lt;/em&gt;: Another common Git workflow involves an integration manager — a single person who commits to the &apos;blessed&apos; repository. A number of developers then clone from that repository, push to their own independent repositories, and ask the integrator to pull in their changes. This is the type of development model often seen with open source or GitHub repositories.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;em&gt;Dictator and Lieutenants Workflow&lt;/em&gt;: For more massive projects, a development workflow like that of the Linux kernel is often effective. In this model, some people (&apos;lieutenants&apos;) are in charge of a specific subsystem of the project and they merge in all changes related to that subsystem. Another integrator (the &apos;dictator&apos;) can pull changes from only his/her lieutenants and then push to the &apos;blessed&apos; repository that everyone then clones from again.&lt;/p&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Staging Area&lt;/h2&gt; 
&lt;p&gt;Unlike the other systems, Git has something called the &quot;staging area&quot; or &quot;index&quot;. This is an intermediate area where commits can be formatted and reviewed before completing the commit.&lt;/p&gt; 
&lt;p&gt;One thing that sets Git apart from other tools is that it&apos;s possible to quickly stage some of your files and commit them without committing all of the other modified files in your working directory or having to list them on the command line during the commit.&lt;/p&gt; 
&lt;p&gt;This allows you to stage only portions of a modified file. Gone are the days of making two logically unrelated modifications to a file before you realized that you forgot to commit one of them. Now you can just stage the change you need for the current commit and stage the other change for the next commit. This feature scales up to as many different changes to your file as needed.&lt;/p&gt; 
&lt;p&gt;Of course, Git also makes it easy to ignore this feature if you don&apos;t want that kind of control — just add a &apos;-a&apos; to your commit command in order to add all changes to all files to the staging area.&lt;/p&gt; 
&lt;hr&gt; 
&lt;h3&gt;Using Git to do keyword-expansion within source files&lt;/h3&gt; 
&lt;p&gt;In general, this appears to be best handled with &lt;a href=&quot;https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks&quot;&gt;Git Hooks&lt;/a&gt;. &lt;a href=&quot;https://www.git-scm.com/docs/githooks&quot;&gt;Official githook doc page&lt;/a&gt;.&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://stackoverflow.com/questions/44948352/git-add-author-date-create-modified-to-a-file?noredirect=1&amp;amp;lq=1&quot;&gt;StackOverflow: Add author, date, create/modified to a file&lt;/a&gt; answer directed to &lt;a href=&quot;https://git-scm.com/book/en/v2/Customizing-Git-Git-Attributes#_keyword_expansion&quot;&gt;keyword expansion&lt;/a&gt;:&lt;/p&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;It turns out that you can write your own filters for doing substitutions in files on commit/checkout. These are called “clean” and “smudge” filters. In the .gitattributes file, you can set a filter for particular paths and then set up scripts that will process files just before they’re checked out (“smudge”, see &lt;a href=&quot;https://git-scm.com/book/en/v2/ch00/filters_a&quot;&gt;The “smudge” filter is run on checkout&lt;/a&gt;.) and just before they’re staged (“clean”, see &lt;a href=&quot;https://git-scm.com/book/en/v2/ch00/filters_b&quot;&gt;The “clean” filter is run when files are staged&lt;/a&gt;.). These filters can be set to do all sorts of fun things.&lt;/p&gt; 
 &lt;p&gt;The original commit message for this feature gives a simple example of running all your C source code through the indent program before committing. You can set it up by setting the filter attribute in your .gitattributes file to filter *.c files with the “indent” filter:&lt;/p&gt; 
 &lt;pre&gt;&lt;code&gt;*.c filter=indent
&lt;/code&gt;&lt;/pre&gt; 
 &lt;p&gt;Then, tell Git what the “indent” filter does on smudge and clean:&lt;/p&gt; 
 &lt;pre&gt;&lt;code&gt;$ git config --global filter.indent.clean indent
$ git config --global filter.indent.smudge cat
&lt;/code&gt;&lt;/pre&gt; 
 &lt;p&gt;In this case, when you commit files that match *.c, Git will run them through the indent program before it stages them and then run them through the cat program before it checks them back out onto disk. The cat program does essentially nothing: it spits out the same data that it comes in. This combination effectively filters all C source code files through indent before committing.&lt;/p&gt; 
 &lt;p&gt;Another interesting example gets $Date$ keyword expansion, RCS style. To do this properly, you need a small script that takes a filename, figures out the last commit date for this project, and inserts the date into the file. Here is a small Ruby script that does that:&lt;/p&gt; 
 &lt;pre&gt;&lt;code&gt;#! /usr/bin/env ruby
data = STDIN.read
last_date = `git log --pretty=format:&quot;%ad&quot; -1`
puts data.gsub(&apos;$Date$&apos;, &apos;$Date: &apos; + last_date.to_s + &apos;$&apos;)
&lt;/code&gt;&lt;/pre&gt; 
 &lt;p&gt;All the script does is get the latest commit date from the git log command, stick that into any $Date$ strings it sees in stdin, and print the results – it should be simple to do in whatever language you’re most comfortable in. You can name this file expand_date and put it in your path. Now, you need to set up a filter in Git (call it dater) and tell it to use your expand_date filter to smudge the files on checkout. You’ll use a Perl expression to clean that up on commit:&lt;/p&gt; 
&lt;/blockquote&gt; 
&lt;pre&gt;&lt;code&gt;$ git config filter.dater.smudge expand_date
$ git config filter.dater.clean &apos;perl -pe &quot;s/\\\$Date[^\\\$]*\\\$/\\\$Date\\\$/&quot;&apos;
&lt;/code&gt;&lt;/pre&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;This Perl snippet strips out anything it sees in a $Date$ string, to get back to where you started. Now that your filter is ready, you can test it by setting up a Git attribute for that file that engages the new filter and creating a file with your $Date$ keyword:&lt;/p&gt; 
&lt;/blockquote&gt; 
&lt;pre&gt;&lt;code&gt;date*.txt filter=dater
$ echo &apos;# $Date$&apos; &amp;gt; date_test.txt
&lt;/code&gt;&lt;/pre&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;If you commit those changes and check out the file again, you see the keyword properly substituted:&lt;/p&gt; 
&lt;/blockquote&gt; 
&lt;pre&gt;&lt;code&gt;$ git add date_test.txt .gitattributes
$ git commit -m &quot;Test date expansion in Git&quot;
$ rm date_test.txt
$ git checkout date_test.txt
$ cat date_test.txt
# $Date: Tue Apr 21 07:26:52 2009 -0700$
&lt;/code&gt;&lt;/pre&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;You can see how powerful this technique can be for customized applications. You have to be careful, though, because the .gitattributes file is committed and passed around with the project, but the driver (in this case, dater) isn’t, so it won’t work everywhere. When you design these filters, they should be able to fail gracefully and have the project still work properly.&lt;/p&gt; 
&lt;/blockquote&gt;
	</description>
    </item>
    <item>
      <title>GitNexus</title>
      <link>https://tedneward.github.io/Research/tools/gitnexus/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/gitnexus/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://gitnexus.vercel.app/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/abhigyanpatwari/GitNexus&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Building nervous system for agent context.&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;Indexes any codebase into a knowledge graph — every dependency, call chain, cluster, and execution flow — then exposes it through smart tools so AI agents never miss code.&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://github.com/user-attachments/assets/172685ba-8e54-4ea7-9ad1-e31a3398da72&quot;&gt;https://github.com/user-attachments/assets/172685ba-8e54-4ea7-9ad1-e31a3398da72&lt;/a&gt;&lt;/p&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;&lt;em&gt;Like DeepWiki, but deeper.&lt;/em&gt; DeepWiki helps you &lt;em&gt;understand&lt;/em&gt; code. GitNexus lets you &lt;em&gt;analyze&lt;/em&gt; it — because a knowledge graph tracks every relationship, not just descriptions.&lt;/p&gt; 
&lt;/blockquote&gt; 
&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; The &lt;strong&gt;Web UI&lt;/strong&gt; is a quick way to chat with any repo. The &lt;strong&gt;CLI + MCP&lt;/strong&gt; is how you make your AI agent actually reliable — it gives Cursor, Claude Code, and friends a deep architectural view of your codebase so they stop missing dependencies, breaking call chains, and shipping blind edits. Even smaller models get full architectural clarity, making it compete with goliath models.&lt;/p&gt; 
&lt;hr&gt; 
&lt;h2&gt;Star History&lt;/h2&gt; 
&lt;p&gt;&lt;a href=&quot;https://www.star-history.com/#abhigyanpatwari/GitNexus&amp;amp;type=date&amp;amp;legend=top-left&quot;&gt;&lt;img src=&quot;https://api.star-history.com/svg?repos=abhigyanpatwari/GitNexus&amp;amp;type=date&amp;amp;legend=top-left&quot; alt=&quot;Star History Chart&quot;&gt;&lt;/a&gt;&lt;/p&gt; 
&lt;h2&gt;Two Ways to Use GitNexus&lt;/h2&gt; 
&lt;table&gt; 
 &lt;thead&gt; 
  &lt;tr&gt;
   &lt;th&gt; &lt;/th&gt;
   &lt;th&gt; &lt;strong&gt;CLI + MCP&lt;/strong&gt; &lt;/th&gt;
   &lt;th&gt; &lt;strong&gt;Web UI&lt;/strong&gt; &lt;/th&gt;
  &lt;/tr&gt; 
 &lt;/thead&gt; 
 &lt;tbody&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;strong&gt;What&lt;/strong&gt; &lt;/td&gt;
   &lt;td&gt; Index repos locally, connect AI agents via MCP &lt;/td&gt;
   &lt;td&gt; Visual graph explorer + AI chat in browser &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;strong&gt;For&lt;/strong&gt; &lt;/td&gt;
   &lt;td&gt; Daily development with Cursor, Claude Code, Windsurf, OpenCode &lt;/td&gt;
   &lt;td&gt; Quick exploration, demos, one-off analysis &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;strong&gt;Scale&lt;/strong&gt; &lt;/td&gt;
   &lt;td&gt; Full repos, any size &lt;/td&gt;
   &lt;td&gt; Limited by browser memory (~5k files), or unlimited via backend mode &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;strong&gt;Install&lt;/strong&gt; &lt;/td&gt;
   &lt;td&gt; &lt;code&gt;npm install -g gitnexus&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; No install —&lt;a href=&quot;https://gitnexus.vercel.app&quot;&gt;gitnexus.vercel.app&lt;/a&gt; &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;strong&gt;Storage&lt;/strong&gt; &lt;/td&gt;
   &lt;td&gt; KuzuDB native (fast, persistent) &lt;/td&gt;
   &lt;td&gt; KuzuDB WASM (in-memory, per session) &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;strong&gt;Parsing&lt;/strong&gt; &lt;/td&gt;
   &lt;td&gt; Tree-sitter native bindings &lt;/td&gt;
   &lt;td&gt; Tree-sitter WASM &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;strong&gt;Privacy&lt;/strong&gt; &lt;/td&gt;
   &lt;td&gt; Everything local, no network &lt;/td&gt;
   &lt;td&gt; Everything in-browser, no server &lt;/td&gt;
  &lt;/tr&gt; 
 &lt;/tbody&gt; 
&lt;/table&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;&lt;strong&gt;Bridge mode:&lt;/strong&gt; &lt;code&gt;gitnexus serve&lt;/code&gt; connects the two — the web UI auto-detects the local server and can browse all your CLI-indexed repos without re-uploading or re-indexing.&lt;/p&gt; 
&lt;/blockquote&gt; 
&lt;hr&gt; 
&lt;h2&gt;CLI + MCP (recommended)&lt;/h2&gt; 
&lt;p&gt;The CLI indexes your repository and runs an MCP server that gives AI agents deep codebase awareness.&lt;/p&gt; 
&lt;h3&gt;Quick Start&lt;/h3&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;# Index your repo (run from repo root)
npx gitnexus analyze
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;That&apos;s it. This indexes the codebase, installs agent skills, registers Claude Code hooks, and creates &lt;code&gt;AGENTS.md&lt;/code&gt; / &lt;code&gt;CLAUDE.md&lt;/code&gt; context files — all in one command.&lt;/p&gt; 
&lt;p&gt;To configure MCP for your editor, run &lt;code&gt;npx gitnexus setup&lt;/code&gt; once — or set it up manually below.&lt;/p&gt; 
&lt;h3&gt;MCP Setup&lt;/h3&gt; 
&lt;p&gt;&lt;code&gt;gitnexus setup&lt;/code&gt; auto-detects your editors and writes the correct global MCP config. You only need to run it once.&lt;/p&gt; 
&lt;h3&gt;Editor Support&lt;/h3&gt; 
&lt;table&gt; 
 &lt;thead&gt; 
  &lt;tr&gt;
   &lt;th&gt; Editor &lt;/th&gt;
   &lt;th&gt; MCP &lt;/th&gt;
   &lt;th&gt; Skills &lt;/th&gt;
   &lt;th&gt; Hooks (auto-augment) &lt;/th&gt;
   &lt;th&gt; Support &lt;/th&gt;
  &lt;/tr&gt; 
 &lt;/thead&gt; 
 &lt;tbody&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;strong&gt;Claude Code&lt;/strong&gt; &lt;/td&gt;
   &lt;td&gt; Yes &lt;/td&gt;
   &lt;td&gt; Yes &lt;/td&gt;
   &lt;td&gt; Yes (PreToolUse + PostToolUse) &lt;/td&gt;
   &lt;td&gt; &lt;strong&gt;Full&lt;/strong&gt; &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;strong&gt;Cursor&lt;/strong&gt; &lt;/td&gt;
   &lt;td&gt; Yes &lt;/td&gt;
   &lt;td&gt; Yes &lt;/td&gt;
   &lt;td&gt; — &lt;/td&gt;
   &lt;td&gt; MCP + Skills &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;strong&gt;Windsurf&lt;/strong&gt; &lt;/td&gt;
   &lt;td&gt; Yes &lt;/td&gt;
   &lt;td&gt; — &lt;/td&gt;
   &lt;td&gt; — &lt;/td&gt;
   &lt;td&gt; MCP &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;strong&gt;OpenCode&lt;/strong&gt; &lt;/td&gt;
   &lt;td&gt; Yes &lt;/td&gt;
   &lt;td&gt; Yes &lt;/td&gt;
   &lt;td&gt; — &lt;/td&gt;
   &lt;td&gt; MCP + Skills &lt;/td&gt;
  &lt;/tr&gt; 
 &lt;/tbody&gt; 
&lt;/table&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;&lt;strong&gt;Claude Code&lt;/strong&gt; gets the deepest integration: MCP tools + agent skills + PreToolUse hooks that enrich searches with graph context + PostToolUse hooks that auto-reindex after commits.&lt;/p&gt; 
&lt;/blockquote&gt; 
&lt;h3&gt;Community Integrations&lt;/h3&gt; 
&lt;table&gt; 
 &lt;thead&gt; 
  &lt;tr&gt;
   &lt;th&gt; Agent &lt;/th&gt;
   &lt;th&gt; Install &lt;/th&gt;
   &lt;th&gt; Source &lt;/th&gt;
  &lt;/tr&gt; 
 &lt;/thead&gt; 
 &lt;tbody&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;a href=&quot;https://pi.dev&quot;&gt;pi&lt;/a&gt; &lt;/td&gt;
   &lt;td&gt; &lt;code&gt;pi install npm:pi-gitnexus&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; &lt;a href=&quot;https://github.com/tintinweb/pi-gitnexus&quot;&gt;pi-gitnexus&lt;/a&gt; &lt;/td&gt;
  &lt;/tr&gt; 
 &lt;/tbody&gt; 
&lt;/table&gt; 
&lt;p&gt;If you prefer manual configuration:&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Claude Code&lt;/strong&gt; (full support — MCP + skills + hooks):&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;claude mcp add gitnexus -- npx -y gitnexus@latest mcp
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;&lt;strong&gt;Cursor&lt;/strong&gt; (&lt;code&gt;~/.cursor/mcp.json&lt;/code&gt; — global, works for all projects):&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-json&quot;&gt;{
  &quot;mcpServers&quot;: {
    &quot;gitnexus&quot;: {
      &quot;command&quot;: &quot;npx&quot;,
      &quot;args&quot;: [&quot;-y&quot;, &quot;gitnexus@latest&quot;, &quot;mcp&quot;]
    }
  }
}
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;&lt;strong&gt;OpenCode&lt;/strong&gt; (&lt;code&gt;~/.config/opencode/config.json&lt;/code&gt;):&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-json&quot;&gt;{
  &quot;mcp&quot;: {
    &quot;gitnexus&quot;: {
      &quot;command&quot;: &quot;npx&quot;,
      &quot;args&quot;: [&quot;-y&quot;, &quot;gitnexus@latest&quot;, &quot;mcp&quot;]
    }
  }
}
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;CLI Commands&lt;/h3&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;gitnexus setup                    # Configure MCP for your editors (one-time)
gitnexus analyze [path]           # Index a repository (or update stale index)
gitnexus analyze --force          # Force full re-index
gitnexus analyze --skip-embeddings  # Skip embedding generation (faster)
gitnexus mcp                     # Start MCP server (stdio) — serves all indexed repos
gitnexus serve                   # Start local HTTP server (multi-repo) for web UI connection
gitnexus list                    # List all indexed repositories
gitnexus status                  # Show index status for current repo
gitnexus clean                   # Delete index for current repo
gitnexus clean --all --force     # Delete all indexes
gitnexus wiki [path]             # Generate repository wiki from knowledge graph
gitnexus wiki --model &amp;lt;model&amp;gt;    # Wiki with custom LLM model (default: gpt-4o-mini)
gitnexus wiki --base-url &amp;lt;url&amp;gt;   # Wiki with custom LLM API base URL
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;What Your AI Agent Gets&lt;/h3&gt; 
&lt;p&gt;&lt;strong&gt;7 tools&lt;/strong&gt; exposed via MCP:&lt;/p&gt; 
&lt;table&gt; 
 &lt;thead&gt; 
  &lt;tr&gt;
   &lt;th&gt; Tool &lt;/th&gt;
   &lt;th&gt; What It Does &lt;/th&gt;
   &lt;th&gt; &lt;code&gt;repo&lt;/code&gt; Param &lt;/th&gt;
  &lt;/tr&gt; 
 &lt;/thead&gt; 
 &lt;tbody&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;list_repos&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Discover all indexed repositories &lt;/td&gt;
   &lt;td&gt; — &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;query&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Process-grouped hybrid search (BM25 + semantic + RRF) &lt;/td&gt;
   &lt;td&gt; Optional &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;context&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; 360-degree symbol view — categorized refs, process participation &lt;/td&gt;
   &lt;td&gt; Optional &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;impact&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Blast radius analysis with depth grouping and confidence &lt;/td&gt;
   &lt;td&gt; Optional &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;detect_changes&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Git-diff impact — maps changed lines to affected processes &lt;/td&gt;
   &lt;td&gt; Optional &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;rename&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Multi-file coordinated rename with graph + text search &lt;/td&gt;
   &lt;td&gt; Optional &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;cypher&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Raw Cypher graph queries &lt;/td&gt;
   &lt;td&gt; Optional &lt;/td&gt;
  &lt;/tr&gt; 
 &lt;/tbody&gt; 
&lt;/table&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;When only one repo is indexed, the &lt;code&gt;repo&lt;/code&gt; parameter is optional. With multiple repos, specify which one: &lt;code&gt;query({query: &quot;auth&quot;, repo: &quot;my-app&quot;})&lt;/code&gt;.&lt;/p&gt; 
&lt;/blockquote&gt; 
&lt;p&gt;&lt;strong&gt;Resources&lt;/strong&gt; for instant context:&lt;/p&gt; 
&lt;table&gt; 
 &lt;thead&gt; 
  &lt;tr&gt;
   &lt;th&gt; Resource &lt;/th&gt;
   &lt;th&gt; Purpose &lt;/th&gt;
  &lt;/tr&gt; 
 &lt;/thead&gt; 
 &lt;tbody&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;gitnexus://repos&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; List all indexed repositories (read this first) &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;gitnexus://repo/{name}/context&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Codebase stats, staleness check, and available tools &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;gitnexus://repo/{name}/clusters&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; All functional clusters with cohesion scores &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;gitnexus://repo/{name}/cluster/{name}&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Cluster members and details &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;gitnexus://repo/{name}/processes&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; All execution flows &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;gitnexus://repo/{name}/process/{name}&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Full process trace with steps &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;gitnexus://repo/{name}/schema&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Graph schema for Cypher queries &lt;/td&gt;
  &lt;/tr&gt; 
 &lt;/tbody&gt; 
&lt;/table&gt; 
&lt;p&gt;&lt;strong&gt;2 MCP prompts&lt;/strong&gt; for guided workflows:&lt;/p&gt; 
&lt;table&gt; 
 &lt;thead&gt; 
  &lt;tr&gt;
   &lt;th&gt; Prompt &lt;/th&gt;
   &lt;th&gt; What It Does &lt;/th&gt;
  &lt;/tr&gt; 
 &lt;/thead&gt; 
 &lt;tbody&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;detect_impact&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Pre-commit change analysis — scope, affected processes, risk level &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;generate_map&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Architecture documentation from the knowledge graph with mermaid diagrams &lt;/td&gt;
  &lt;/tr&gt; 
 &lt;/tbody&gt; 
&lt;/table&gt; 
&lt;p&gt;&lt;strong&gt;4 agent skills&lt;/strong&gt; installed to &lt;code&gt;.claude/skills/&lt;/code&gt; automatically:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;strong&gt;Exploring&lt;/strong&gt; — Navigate unfamiliar code using the knowledge graph&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Debugging&lt;/strong&gt; — Trace bugs through call chains&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Impact Analysis&lt;/strong&gt; — Analyze blast radius before changes&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Refactoring&lt;/strong&gt; — Plan safe refactors using dependency mapping&lt;/li&gt; 
&lt;/ul&gt; 
&lt;hr&gt; 
&lt;h2&gt;Multi-Repo MCP Architecture&lt;/h2&gt; 
&lt;p&gt;GitNexus uses a &lt;strong&gt;global registry&lt;/strong&gt; so one MCP server can serve multiple indexed repos. No per-project MCP config needed — set it up once and it works everywhere.&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-mermaid&quot;&gt;flowchart TD
    subgraph CLI [CLI Commands]
        Setup[&quot;gitnexus setup&quot;]
        Analyze[&quot;gitnexus analyze&quot;]
        Clean[&quot;gitnexus clean&quot;]
        List[&quot;gitnexus list&quot;]
    end

    subgraph Registry [&quot;~/.gitnexus/&quot;]
        RegFile[&quot;registry.json&quot;]
    end

    subgraph Repos [Project Repos]
        RepoA[&quot;.gitnexus/ in repo A&quot;]
        RepoB[&quot;.gitnexus/ in repo B&quot;]
    end

    subgraph MCP [MCP Server]
        Server[&quot;server.ts&quot;]
        Backend[&quot;LocalBackend&quot;]
        Pool[&quot;Connection Pool&quot;]
        ConnA[&quot;KuzuDB conn A&quot;]
        ConnB[&quot;KuzuDB conn B&quot;]
    end

    Setup --&amp;gt;|&quot;writes global MCP config&quot;| CursorConfig[&quot;~/.cursor/mcp.json&quot;]
    Analyze --&amp;gt;|&quot;registers repo&quot;| RegFile
    Analyze --&amp;gt;|&quot;stores index&quot;| RepoA
    Clean --&amp;gt;|&quot;unregisters repo&quot;| RegFile
    List --&amp;gt;|&quot;reads&quot;| RegFile
    Server --&amp;gt;|&quot;reads registry&quot;| RegFile
    Server --&amp;gt; Backend
    Backend --&amp;gt; Pool
    Pool --&amp;gt;|&quot;lazy open&quot;| ConnA
    Pool --&amp;gt;|&quot;lazy open&quot;| ConnB
    ConnA --&amp;gt;|&quot;queries&quot;| RepoA
    ConnB --&amp;gt;|&quot;queries&quot;| RepoB
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;&lt;strong&gt;How it works:&lt;/strong&gt; Each &lt;code&gt;gitnexus analyze&lt;/code&gt; stores the index in &lt;code&gt;.gitnexus/&lt;/code&gt; inside the repo (portable, gitignored) and registers a pointer in &lt;code&gt;~/.gitnexus/registry.json&lt;/code&gt;. When an AI agent starts, the MCP server reads the registry and can serve any indexed repo. KuzuDB connections are opened lazily on first query and evicted after 5 minutes of inactivity (max 5 concurrent). If only one repo is indexed, the &lt;code&gt;repo&lt;/code&gt; parameter is optional on all tools — agents don&apos;t need to change anything.&lt;/p&gt; 
&lt;hr&gt; 
&lt;h2&gt;Web UI (browser-based)&lt;/h2&gt; 
&lt;p&gt;A fully client-side graph explorer and AI chat. No server, no install — your code never leaves the browser.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Try it now:&lt;/strong&gt; &lt;a href=&quot;https://gitnexus.vercel.app&quot;&gt;gitnexus.vercel.app&lt;/a&gt; — drag &amp;amp; drop a ZIP and start exploring.&lt;/p&gt; 
&lt;p&gt;&lt;img width=&quot;2550&quot; height=&quot;1343&quot; alt=&quot;gitnexus_img&quot; src=&quot;https://github.com/user-attachments/assets/cc5d637d-e0e5-48e6-93ff-5bcfdb929285&quot;&gt;&lt;/p&gt; 
&lt;p&gt;Or run locally:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;git clone https://github.com/abhigyanpatwari/gitnexus.git
cd gitnexus/gitnexus-web
npm install
npm run dev
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;The web UI uses the same indexing pipeline as the CLI but runs entirely in WebAssembly (Tree-sitter WASM, KuzuDB WASM, in-browser embeddings). It&apos;s great for quick exploration but limited by browser memory for larger repos.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Local Backend Mode:&lt;/strong&gt; Run &lt;code&gt;gitnexus serve&lt;/code&gt; and open the web UI locally — it auto-detects the server and shows all your indexed repos, with full AI chat support. No need to re-upload or re-index. The agent&apos;s tools (Cypher queries, search, code navigation) route through the backend HTTP API automatically.&lt;/p&gt; 
&lt;hr&gt; 
&lt;h2&gt;The Problem GitNexus Solves&lt;/h2&gt; 
&lt;p&gt;Tools like &lt;strong&gt;Cursor&lt;/strong&gt;, &lt;strong&gt;Claude Code&lt;/strong&gt;, &lt;strong&gt;Cline&lt;/strong&gt;, &lt;strong&gt;Roo Code&lt;/strong&gt;, and &lt;strong&gt;Windsurf&lt;/strong&gt; are powerful — but they don&apos;t truly know your codebase structure.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;What happens:&lt;/strong&gt;&lt;/p&gt; 
&lt;ol&gt; 
 &lt;li&gt;AI edits &lt;code&gt;UserService.validate()&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;Doesn&apos;t know 47 functions depend on its return type&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Breaking changes ship&lt;/strong&gt;&lt;/li&gt; 
&lt;/ol&gt; 
&lt;h3&gt;Traditional Graph RAG vs GitNexus&lt;/h3&gt; 
&lt;p&gt;Traditional approaches give the LLM raw graph edges and hope it explores enough. GitNexus &lt;strong&gt;precomputes structure at index time&lt;/strong&gt; — clustering, tracing, scoring — so tools return complete context in one call:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-mermaid&quot;&gt;flowchart TB
    subgraph Traditional[&quot;Traditional Graph RAG&quot;]
        direction TB
        U1[&quot;User: What depends on UserService?&quot;]
        U1 --&amp;gt; LLM1[&quot;LLM receives raw graph&quot;]
        LLM1 --&amp;gt; Q1[&quot;Query 1: Find callers&quot;]
        Q1 --&amp;gt; Q2[&quot;Query 2: What files?&quot;]
        Q2 --&amp;gt; Q3[&quot;Query 3: Filter tests?&quot;]
        Q3 --&amp;gt; Q4[&quot;Query 4: High-risk?&quot;]
        Q4 --&amp;gt; OUT1[&quot;Answer after 4+ queries&quot;]
    end

    subgraph GN[&quot;GitNexus Smart Tools&quot;]
        direction TB
        U2[&quot;User: What depends on UserService?&quot;]
        U2 --&amp;gt; TOOL[&quot;impact UserService upstream&quot;]
        TOOL --&amp;gt; PRECOMP[&quot;Pre-structured response:
        8 callers, 3 clusters, all 90%+ confidence&quot;]
        PRECOMP --&amp;gt; OUT2[&quot;Complete answer, 1 query&quot;]
    end
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;&lt;strong&gt;Core innovation: Precomputed Relational Intelligence&lt;/strong&gt;&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;strong&gt;Reliability&lt;/strong&gt; — LLM can&apos;t miss context, it&apos;s already in the tool response&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Token efficiency&lt;/strong&gt; — No 10-query chains to understand one function&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Model democratization&lt;/strong&gt; — Smaller LLMs work because tools do the heavy lifting&lt;/li&gt; 
&lt;/ul&gt; 
&lt;hr&gt; 
&lt;h2&gt;How It Works&lt;/h2&gt; 
&lt;p&gt;GitNexus builds a complete knowledge graph of your codebase through a multi-phase indexing pipeline:&lt;/p&gt; 
&lt;ol&gt; 
 &lt;li&gt;&lt;strong&gt;Structure&lt;/strong&gt; — Walks the file tree and maps folder/file relationships&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Parsing&lt;/strong&gt; — Extracts functions, classes, methods, and interfaces using Tree-sitter ASTs&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Resolution&lt;/strong&gt; — Resolves imports and function calls across files with language-aware logic&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Clustering&lt;/strong&gt; — Groups related symbols into functional communities&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Processes&lt;/strong&gt; — Traces execution flows from entry points through call chains&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Search&lt;/strong&gt; — Builds hybrid search indexes for fast retrieval&lt;/li&gt; 
&lt;/ol&gt; 
&lt;h3&gt;Supported Languages&lt;/h3&gt; 
&lt;p&gt;TypeScript, JavaScript, Python, Java, Kotlin, C, C++, C#, Go, Rust, PHP, Swift&lt;/p&gt; 
&lt;hr&gt; 
&lt;h2&gt;Tool Examples&lt;/h2&gt; 
&lt;h3&gt;Impact Analysis&lt;/h3&gt; 
&lt;pre&gt;&lt;code&gt;impact({target: &quot;UserService&quot;, direction: &quot;upstream&quot;, minConfidence: 0.8})

TARGET: Class UserService (src/services/user.ts)

UPSTREAM (what depends on this):
  Depth 1 (WILL BREAK):
    handleLogin [CALLS 90%] -&amp;gt; src/api/auth.ts:45
    handleRegister [CALLS 90%] -&amp;gt; src/api/auth.ts:78
    UserController [CALLS 85%] -&amp;gt; src/controllers/user.ts:12
  Depth 2 (LIKELY AFFECTED):
    authRouter [IMPORTS] -&amp;gt; src/routes/auth.ts
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Options: &lt;code&gt;maxDepth&lt;/code&gt;, &lt;code&gt;minConfidence&lt;/code&gt;, &lt;code&gt;relationTypes&lt;/code&gt; (&lt;code&gt;CALLS&lt;/code&gt;, &lt;code&gt;IMPORTS&lt;/code&gt;, &lt;code&gt;EXTENDS&lt;/code&gt;, &lt;code&gt;IMPLEMENTS&lt;/code&gt;), &lt;code&gt;includeTests&lt;/code&gt;&lt;/p&gt; 
&lt;h3&gt;Process-Grouped Search&lt;/h3&gt; 
&lt;pre&gt;&lt;code&gt;query({query: &quot;authentication middleware&quot;})

processes:
  - summary: &quot;LoginFlow&quot;
    priority: 0.042
    symbol_count: 4
    process_type: cross_community
    step_count: 7

process_symbols:
  - name: validateUser
    type: Function
    filePath: src/auth/validate.ts
    process_id: proc_login
    step_index: 2

definitions:
  - name: AuthConfig
    type: Interface
    filePath: src/types/auth.ts
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;Context (360-degree Symbol View)&lt;/h3&gt; 
&lt;pre&gt;&lt;code&gt;context({name: &quot;validateUser&quot;})

symbol:
  uid: &quot;Function:validateUser&quot;
  kind: Function
  filePath: src/auth/validate.ts
  startLine: 15

incoming:
  calls: [handleLogin, handleRegister, UserController]
  imports: [authRouter]

outgoing:
  calls: [checkPassword, createSession]

processes:
  - name: LoginFlow (step 2/7)
  - name: RegistrationFlow (step 3/5)
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;Detect Changes (Pre-Commit)&lt;/h3&gt; 
&lt;pre&gt;&lt;code&gt;detect_changes({scope: &quot;all&quot;})

summary:
  changed_count: 12
  affected_count: 3
  changed_files: 4
  risk_level: medium

changed_symbols: [validateUser, AuthService, ...]
affected_processes: [LoginFlow, RegistrationFlow, ...]
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;Rename (Multi-File)&lt;/h3&gt; 
&lt;pre&gt;&lt;code&gt;rename({symbol_name: &quot;validateUser&quot;, new_name: &quot;verifyUser&quot;, dry_run: true})

status: success
files_affected: 5
total_edits: 8
graph_edits: 6     (high confidence)
text_search_edits: 2  (review carefully)
changes: [...]
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;Cypher Queries&lt;/h3&gt; 
&lt;pre&gt;&lt;code class=&quot;language-cypher&quot;&gt;-- Find what calls auth functions with high confidence
MATCH (c:Community {heuristicLabel: &apos;Authentication&apos;})&amp;lt;-[:CodeRelation {type: &apos;MEMBER_OF&apos;}]-(fn)
MATCH (caller)-[r:CodeRelation {type: &apos;CALLS&apos;}]-&amp;gt;(fn)
WHERE r.confidence &amp;gt; 0.8
RETURN caller.name, fn.name, r.confidence
ORDER BY r.confidence DESC
&lt;/code&gt;&lt;/pre&gt; 
&lt;hr&gt; 
&lt;h2&gt;Wiki Generation&lt;/h2&gt; 
&lt;p&gt;Generate LLM-powered documentation from your knowledge graph:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;# Requires an LLM API key (OPENAI_API_KEY, etc.)
gitnexus wiki

# Use a custom model or provider
gitnexus wiki --model gpt-4o
gitnexus wiki --base-url https://api.anthropic.com/v1

# Force full regeneration
gitnexus wiki --force
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;The wiki generator reads the indexed graph structure, groups files into modules via LLM, generates per-module documentation pages, and creates an overview page — all with cross-references to the knowledge graph.&lt;/p&gt; 
&lt;hr&gt; 
&lt;h2&gt;Tech Stack&lt;/h2&gt; 
&lt;table&gt; 
 &lt;thead&gt; 
  &lt;tr&gt;
   &lt;th&gt; Layer &lt;/th&gt;
   &lt;th&gt; CLI &lt;/th&gt;
   &lt;th&gt; Web &lt;/th&gt;
  &lt;/tr&gt; 
 &lt;/thead&gt; 
 &lt;tbody&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;strong&gt;Runtime&lt;/strong&gt; &lt;/td&gt;
   &lt;td&gt; Node.js (native) &lt;/td&gt;
   &lt;td&gt; Browser (WASM) &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;strong&gt;Parsing&lt;/strong&gt; &lt;/td&gt;
   &lt;td&gt; Tree-sitter native bindings &lt;/td&gt;
   &lt;td&gt; Tree-sitter WASM &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;strong&gt;Database&lt;/strong&gt; &lt;/td&gt;
   &lt;td&gt; KuzuDB native &lt;/td&gt;
   &lt;td&gt; KuzuDB WASM &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;strong&gt;Embeddings&lt;/strong&gt; &lt;/td&gt;
   &lt;td&gt; HuggingFace transformers.js (GPU/CPU) &lt;/td&gt;
   &lt;td&gt; transformers.js (WebGPU/WASM) &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;strong&gt;Search&lt;/strong&gt; &lt;/td&gt;
   &lt;td&gt; BM25 + semantic + RRF &lt;/td&gt;
   &lt;td&gt; BM25 + semantic + RRF &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;strong&gt;Agent Interface&lt;/strong&gt; &lt;/td&gt;
   &lt;td&gt; MCP (stdio) &lt;/td&gt;
   &lt;td&gt; LangChain ReAct agent &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;strong&gt;Visualization&lt;/strong&gt; &lt;/td&gt;
   &lt;td&gt; — &lt;/td&gt;
   &lt;td&gt; Sigma.js + Graphology (WebGL) &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;strong&gt;Frontend&lt;/strong&gt; &lt;/td&gt;
   &lt;td&gt; — &lt;/td&gt;
   &lt;td&gt; React 18, TypeScript, Vite, Tailwind v4 &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;strong&gt;Clustering&lt;/strong&gt; &lt;/td&gt;
   &lt;td&gt; Graphology &lt;/td&gt;
   &lt;td&gt; Graphology &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;strong&gt;Concurrency&lt;/strong&gt; &lt;/td&gt;
   &lt;td&gt; Worker threads + async &lt;/td&gt;
   &lt;td&gt; Web Workers + Comlink &lt;/td&gt;
  &lt;/tr&gt; 
 &lt;/tbody&gt; 
&lt;/table&gt; 
&lt;hr&gt; 
&lt;h2&gt;Security &amp;amp; Privacy&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;strong&gt;CLI&lt;/strong&gt;: Everything runs locally on your machine. No network calls. Index stored in &lt;code&gt;.gitnexus/&lt;/code&gt; (gitignored). Global registry at &lt;code&gt;~/.gitnexus/&lt;/code&gt; stores only paths and metadata.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Web&lt;/strong&gt;: Everything runs in your browser. No code uploaded to any server. API keys stored in localStorage only.&lt;/li&gt; 
 &lt;li&gt;Open source — audit the code yourself.&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Glush</title>
      <link>https://tedneward.github.io/Research/tools/glush/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/glush/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/judofyr/glush&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;h2&gt;Reading&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.sanity.io/blog/why-we-wrote-yet-another-parser-compiler&quot;&gt;&quot;Introducing Glush: a robust, human readable, top-down parser compiler&quot;&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Get-Shit-Done</title>
      <link>https://tedneward.github.io/Research/tools/get-shit-done/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/get-shit-done/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/gsd-build/get-shit-done&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;A light-weight and powerful meta-prompting, context engineering and spec-driven development system for Claude Code, OpenCode, Gemini CLI, Kilo, Codex, Copilot, Cursor, Windsurf, Antigravity, Augment, Trae, Qwen Code, Cline, and CodeBuddy.&lt;/p&gt; 
&lt;p&gt;Solves context rot — the quality degradation that happens as Claude fills its context window.&lt;/p&gt; 
&lt;p&gt;&lt;code&gt;npx get-shit-done-cc@latest&lt;/code&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Gitbook</title>
      <link>https://tedneward.github.io/Research/tools/gitbook/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/gitbook/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.gitbook.com/&quot;&gt;Website&lt;/a&gt; | Commercial | &lt;a href=&quot;https://github.com/GitBookIO&quot;&gt;Source?&lt;/a&gt; | &lt;a href=&quot;https://gitbook.com/docs&quot;&gt;Docs&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Glim</title>
      <link>https://tedneward.github.io/Research/tools/glim/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/glim/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/thias/glim&quot;&gt;Source&lt;/a&gt; | &lt;a href=&quot;https://glee.thias.es/GLIM&quot;&gt;Docs&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Advantages over extracting files or using special Live USB creation tools :&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;A single USB memory can hold all Live environments (the limit is its size)&lt;/li&gt; 
 &lt;li&gt;ISO images stay available to burn real CDs or DVDs&lt;/li&gt; 
 &lt;li&gt;ISO images are quick to manipulate (vs. hundreds+ files)&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;Disadvantages :&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;There is no persistence overlay for distributions which normally support it&lt;/li&gt; 
 &lt;li&gt;Setting up isn&apos;t as easy as a simple cat from the ISO image to a block device&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;My experience has been that the safest filesystem to use is FAT32 (surprisingly!), though it will mean that ISO images greater than 4GB won&apos;t be supported. Other filesystems supported by GRUB2 also work, such as ext3/ext4, NTFS and exFAT, but the boot of the distributions must also support it, which isn&apos;t the case for many with NTFS (Ubuntu does, Fedora doesn&apos;t) and exFAT (Ubuntu doesn&apos;t, Fedora does). So FAT32 stays the safe bet; make sure your device is partitioned with MBR (not GPT) for legacy BIOS and EFI hybrid support for peak compatibility.&lt;/p&gt; 
&lt;h2&gt;Reading&lt;/h2&gt; 
&lt;h3&gt;Articles&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.xda-developers.com/glim-ventoy-alternative-linux-enthusiasts-should-use-instead/&quot;&gt;Glim is the Ventoy alternative Linux enthusiasts should use instead&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Awk</title>
      <link>https://tedneward.github.io/Research/tools/gnu/awk/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/gnu/awk/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.gnu.org/software/gawk/manual/gawk.html&quot;&gt;Website: GNU awk&lt;/a&gt; | &lt;a href=&quot;&quot;&gt;Source&lt;/a&gt; | &lt;a href=&quot;https://www-zeuthen.desy.de/dv/documentation/unixguide/infohtml/gawk/gawk.html&quot;&gt;GNU Awk User&apos;s Guide&lt;/a&gt;&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://gist.github.com/Rafe/3102414&quot;&gt;AWK cheatsheet&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://en.wikibooks.org/wiki/An_Awk_Primer&quot;&gt;An Awk Primer&lt;/a&gt; - Wikibooks&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.grymoire.com/Unix/Awk.html&quot;&gt;Awk&lt;/a&gt; - Bruce Barnett&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://learnbyexample.github.io/learn_gnuawk/&quot;&gt;GNU awk&lt;/a&gt; - Sundeep Agarwal&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://awka.sourceforge.net/index.html&quot;&gt;AWKA&lt;/a&gt; - Awka is an open-source implementation. Awka is not an interpreter like Gawk, Mawk or Nawk, but instead it converts the program to ANSI-C, then compiles this using gcc or a native C compiler to create a binary executable. This means you must have an ANSI C compiler present on your system for Awka to work.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;&lt;a href=&quot;https://github.com/adambard/learnxinyminutes-docs/blob/master/awk.html.markdown&quot;&gt;Learn X in Y Minutes&lt;/a&gt; short intro&lt;/h3&gt; 
&lt;pre&gt;&lt;code class=&quot;language-awk&quot;&gt;#!/usr/bin/awk -f

# Comments are like this


# AWK programs consist of a collection of patterns and actions.
pattern1 { action; } # just like lex
pattern2 { action; }

# There is an implied loop and AWK automatically reads and parses each
# record of each file supplied. Each record is split by the FS delimiter,
# which defaults to white-space (multiple spaces,tabs count as one)
# You can assign FS either on the command line (-F C) or in your BEGIN
# pattern

# One of the special patterns is BEGIN. The BEGIN pattern is true
# BEFORE any of the files are read. The END pattern is true after
# an End-of-file from the last file (or standard-in if no files specified)
# There is also an output field separator (OFS) that you can assign, which
# defaults to a single space

BEGIN {

    # BEGIN will run at the beginning of the program. It&apos;s where you put all
    # the preliminary set-up code, before you process any text files. If you
    # have no text files, then think of BEGIN as the main entry point.

    # Variables are global. Just set them or use them, no need to declare..
    count = 0;

    # Operators just like in C and friends
    a = count + 1;
    b = count - 1;
    c = count * 1;
    d = count / 1; # integer division
    e = count % 1; # modulus
    f = count ^ 1; # exponentiation

    a += 1;
    b -= 1;
    c *= 1;
    d /= 1;
    e %= 1;
    f ^= 1;

    # Incrementing and decrementing by one
    a++;
    b--;

    # As a prefix operator, it returns the incremented value
    ++a;
    --b;

    # Notice, also, no punctuation such as semicolons to terminate statements

    # Control statements
    if (count == 0)
        print &quot;Starting with count of 0&quot;;
    else
        print &quot;Huh?&quot;;

    # Or you could use the ternary operator
    print (count == 0) ? &quot;Starting with count of 0&quot; : &quot;Huh?&quot;;

    # Blocks consisting of multiple lines use braces
    while (a &amp;lt; 10) {
        print &quot;String concatenation is done&quot; &quot; with a series&quot; &quot; of&quot;
            &quot; space-separated strings&quot;;
        print a;

        a++;
    }

    for (i = 0; i &amp;lt; 10; i++)
        print &quot;Good ol&apos; for loop&quot;;

    # As for comparisons, they&apos;re the standards:
    # a &amp;lt; b   # Less than
    # a &amp;lt;= b  # Less than or equal
    # a != b  # Not equal
    # a == b  # Equal
    # a &amp;gt; b   # Greater than
    # a &amp;gt;= b  # Greater than or equal

    # Logical operators as well
    # a &amp;amp;&amp;amp; b  # AND
    # a || b  # OR

    # In addition, there&apos;s the super useful regular expression match
    if (&quot;foo&quot; ~ &quot;^fo+$&quot;)
        print &quot;Fooey!&quot;;
    if (&quot;boo&quot; !~ &quot;^fo+$&quot;)
        print &quot;Boo!&quot;;

    # Arrays
    arr[0] = &quot;foo&quot;;
    arr[1] = &quot;bar&quot;;
    
    # You can also initialize an array with the built-in function split()
    
    n = split(&quot;foo:bar:baz&quot;, arr, &quot;:&quot;);
   
    # You also have associative arrays (actually, they&apos;re all associative arrays)
    assoc[&quot;foo&quot;] = &quot;bar&quot;;
    assoc[&quot;bar&quot;] = &quot;baz&quot;;

    # And multi-dimensional arrays, with some limitations I won&apos;t mention here
    multidim[0,0] = &quot;foo&quot;;
    multidim[0,1] = &quot;bar&quot;;
    multidim[1,0] = &quot;baz&quot;;
    multidim[1,1] = &quot;boo&quot;;

    # You can test for array membership
    if (&quot;foo&quot; in assoc)
        print &quot;Fooey!&quot;;

    # You can also use the &apos;in&apos; operator to traverse the keys of an array
    for (key in assoc)
        print assoc[key];

    # The command line is in a special array called ARGV
    for (argnum in ARGV)
        print ARGV[argnum];

    # You can remove elements of an array
    # This is particularly useful to prevent AWK from assuming the arguments
    # are files for it to process
    delete ARGV[1];

    # The number of command line arguments is in a variable called ARGC
    print ARGC;

    # AWK has several built-in functions. They fall into three categories. I&apos;ll
    # demonstrate each of them in their own functions, defined later.

    return_value = arithmetic_functions(a, b, c);
    string_functions();
    io_functions();
}

# Here&apos;s how you define a function
function arithmetic_functions(a, b, c,     d) {

    # Probably the most annoying part of AWK is that there are no local
    # variables. Everything is global. For short scripts, this is fine, even
    # useful, but for longer scripts, this can be a problem.

    # There is a work-around (ahem, hack). Function arguments are local to the
    # function, and AWK allows you to define more function arguments than it
    # needs. So just stick local variable in the function declaration, like I
    # did above. As a convention, stick in some extra whitespace to distinguish
    # between actual function parameters and local variables. In this example,
    # a, b, and c are actual parameters, while d is merely a local variable.

    # Now, to demonstrate the arithmetic functions

    # Most AWK implementations have some standard trig functions
    localvar = sin(a);
    localvar = cos(a);
    localvar = atan2(b, a); # arc tangent of b / a

    # And logarithmic stuff
    localvar = exp(a);
    localvar = log(a);

    # Square root
    localvar = sqrt(a);

    # Truncate floating point to integer
    localvar = int(5.34); # localvar =&amp;gt; 5

    # Random numbers
    srand(); # Supply a seed as an argument. By default, it uses the time of day
    localvar = rand(); # Random number between 0 and 1.

    # Here&apos;s how to return a value
    return localvar;
}

function string_functions(    localvar, arr) {

    # AWK, being a string-processing language, has several string-related
    # functions, many of which rely heavily on regular expressions.

    # Search and replace, first instance (sub) or all instances (gsub)
    # Both return number of matches replaced
    localvar = &quot;fooooobar&quot;;
    sub(&quot;fo+&quot;, &quot;Meet me at the &quot;, localvar); # localvar =&amp;gt; &quot;Meet me at the bar&quot;
    gsub(&quot;e+&quot;, &quot;.&quot;, localvar); # localvar =&amp;gt; &quot;m..t m. at th. bar&quot;

    # Search for a string that matches a regular expression
    # index() does the same thing, but doesn&apos;t allow a regular expression
    match(localvar, &quot;t&quot;); # =&amp;gt; 4, since the &apos;t&apos; is the fourth character

    # Split on a delimiter
    n = split(&quot;foo-bar-baz&quot;, arr, &quot;-&quot;); # a[1] = &quot;foo&quot;; a[2] = &quot;bar&quot;; a[3] = &quot;baz&quot;; n = 3

    # Other useful stuff
    sprintf(&quot;%s %d %d %d&quot;, &quot;Testing&quot;, 1, 2, 3); # =&amp;gt; &quot;Testing 1 2 3&quot;
    substr(&quot;foobar&quot;, 2, 3); # =&amp;gt; &quot;oob&quot;
    substr(&quot;foobar&quot;, 4); # =&amp;gt; &quot;bar&quot;
    length(&quot;foo&quot;); # =&amp;gt; 3
    tolower(&quot;FOO&quot;); # =&amp;gt; &quot;foo&quot;
    toupper(&quot;foo&quot;); # =&amp;gt; &quot;FOO&quot;
}

function io_functions(    localvar) {

    # You&apos;ve already seen print
    print &quot;Hello world&quot;;

    # There&apos;s also printf
    printf(&quot;%s %d %d %d\n&quot;, &quot;Testing&quot;, 1, 2, 3);

    # AWK doesn&apos;t have file handles, per se. It will automatically open a file
    # handle for you when you use something that needs one. The string you used
    # for this can be treated as a file handle, for purposes of I/O. This makes
    # it feel sort of like shell scripting, but to get the same output, the string
    # must match exactly, so use a variable:
    
    outfile = &quot;/tmp/foobar.txt&quot;;

    print &quot;foobar&quot; &amp;gt; outfile;

    # Now the string outfile is a file handle. You can close it:
    close(outfile);

    # Here&apos;s how you run something in the shell
    system(&quot;echo foobar&quot;); # =&amp;gt; prints foobar

    # Reads a line from standard input and stores in localvar
    getline localvar;

    # Reads a line from a pipe (again, use a string so you close it properly)
    cmd = &quot;echo foobar&quot;;
    cmd | getline localvar; # localvar =&amp;gt; &quot;foobar&quot;
    close(cmd);

    # Reads a line from a file and stores in localvar
    infile = &quot;/tmp/foobar.txt&quot;;
    getline localvar &amp;lt; infile; 
    close(infile);
}

# As I said at the beginning, AWK programs consist of a collection of patterns
# and actions. You&apos;ve already seen the BEGIN pattern. Other
# patterns are used only if you&apos;re processing lines from files or standard
# input.
#
# When you pass arguments to AWK, they are treated as file names to process.
# It will process them all, in order. Think of it like an implicit for loop,
# iterating over the lines in these files. these patterns and actions are like
# switch statements inside the loop. 

/^fo+bar$/ {
    
    # This action will execute for every line that matches the regular
    # expression, /^fo+bar$/, and will be skipped for any line that fails to
    # match it. Let&apos;s just print the line:

    print;

    # Whoa, no argument! That&apos;s because print has a default argument: $0.
    # $0 is the name of the current line being processed. It is created
    # automatically for you.

    # You can probably guess there are other $ variables. Every line is
    # implicitly split before every action is called, much like the shell
    # does. And, like the shell, each field can be access with a dollar sign

    # This will print the second and fourth fields in the line
    print $2, $4;

    # AWK automatically defines many other variables to help you inspect and
    # process each line. The most important one is NF

    # Prints the number of fields on this line
    print NF;

    # Print the last field on this line
    print $NF;
}

# Every pattern is actually a true/false test. The regular expression in the
# last pattern is also a true/false test, but part of it was hidden. If you
# don&apos;t give it a string to test, it will assume $0, the line that it&apos;s
# currently processing. Thus, the complete version of it is this:

$0 ~ /^fo+bar$/ {
    print &quot;Equivalent to the last pattern&quot;;
}

a &amp;gt; 0 {
    # This will execute once for each line, as long as a is positive
}

# You get the idea. Processing text files, reading in a line at a time, and
# doing something with it, particularly splitting on a delimiter, is so common
# in UNIX that AWK is a scripting language that does all of it for you, without
# you needing to ask. All you have to do is write the patterns and actions
# based on what you expect of the input, and what you want to do with it.

# Here&apos;s a quick example of a simple script, the sort of thing AWK is perfect
# for. It will read a name from standard input and then will print the average
# age of everyone with that first name. Let&apos;s say you supply as an argument the
# name of a this data file:
#
# Bob Jones 32
# Jane Doe 22
# Steve Stevens 83
# Bob Smith 29
# Bob Barker 72
#
# Here&apos;s the script:

BEGIN {

    # First, ask the user for the name
    print &quot;What name would you like the average age for?&quot;;

    # Get a line from standard input, not from files on the command line
    getline name &amp;lt; &quot;/dev/stdin&quot;;
}

# Now, match every line whose first field is the given name
$1 == name {

    # Inside here, we have access to a number of useful variables, already
    # pre-loaded for us:
    # $0 is the entire line
    # $3 is the third field, the age, which is what we&apos;re interested in here
    # NF is the number of fields, which should be 3
    # NR is the number of records (lines) seen so far
    # FILENAME is the name of the file being processed
    # FS is the field separator being used, which is &quot; &quot; here
    # ...etc. There are plenty more, documented in the man page.

    # Keep track of a running total and how many lines matched
    sum += $3;
    nlines++;
}

# Another special pattern is called END. It will run after processing all the
# text files. Unlike BEGIN, it will only run if you&apos;ve given it input to
# process. It will run after all the files have been read and processed
# according to the rules and actions you&apos;ve provided. The purpose of it is
# usually to output some kind of final report, or do something with the
# aggregate of the data you&apos;ve accumulated over the course of the script.

END {
    if (nlines)
        print &quot;The average age for &quot; name &quot; is &quot; sum / nlines;
}
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;&lt;a href=&quot;https://github.com/Randy8080/reference/blob/main/awk.md&quot;&gt;Cheat Sheet&lt;/a&gt;&lt;/h3&gt; 
&lt;p&gt;&lt;strong&gt;Have a try&lt;/strong&gt;&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-shell&quot;&gt;$ awk -F: &apos;{print $1, $NF}&apos; /etc/passwd
&lt;/code&gt;&lt;/pre&gt; 
&lt;table&gt; 
 &lt;thead&gt; 
  &lt;tr&gt;
   &lt;th&gt;- &lt;/th&gt;
   &lt;th&gt; - &lt;/th&gt;
   &lt;th&gt; - &lt;/th&gt;
  &lt;/tr&gt; 
 &lt;/thead&gt; 
 &lt;tbody&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;/td&gt;
   &lt;td&gt; &lt;code&gt;-F:&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Colon as a separator &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;/td&gt;
   &lt;td&gt; &lt;code&gt;{...}&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Awk program &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;/td&gt;
   &lt;td&gt; &lt;code&gt;print&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Prints the current record &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;/td&gt;
   &lt;td&gt; &lt;code&gt;$1&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; First field &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;/td&gt;
   &lt;td&gt; &lt;code&gt;$NF&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Last field &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;/td&gt;
   &lt;td&gt; &lt;code&gt;/etc/passwd&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Input data file &lt;/td&gt;
  &lt;/tr&gt; 
 &lt;/tbody&gt; 
&lt;/table&gt; 
&lt;h4&gt;Awk program&lt;/h4&gt; 
&lt;pre&gt;&lt;code&gt;BEGIN          {&amp;lt;initializations&amp;gt;} 
   &amp;lt;pattern 1&amp;gt; {&amp;lt;program actions&amp;gt;} 
   &amp;lt;pattern 2&amp;gt; {&amp;lt;program actions&amp;gt;} 
   ...
END            {&amp;lt; final actions &amp;gt;}
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;&lt;strong&gt;Example&lt;/strong&gt;&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;awk &apos;
    BEGIN { print &quot;\n&amp;gt;&amp;gt;&amp;gt;Start&quot; }
    !/(login|shutdown)/ { print NR, $0 }
    END { print &quot;&amp;lt;&amp;lt;&amp;lt;END\n&quot; }
&apos; /etc/passwd
&lt;/code&gt;&lt;/pre&gt; 
&lt;h4&gt;Variables&lt;/h4&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;          $1      $2/$(NF-1)    $3/$NF
           ▼          ▼           ▼ 
        ┌──────┬──────────────┬───────┐
$0/NR ▶ │  ID  │  WEBSITE     │  URI  │
        ├──────┼──────────────┼───────┤
$0/NR ▶ │  1   │  quickref.me │  awk  │
        ├──────┼──────────────┼───────┤
$0/NR ▶ │  2   │  google.com  │  25   │
        └──────┴──────────────┴───────┘
&lt;/code&gt;&lt;/pre&gt; 
&lt;pre&gt;&lt;code&gt;# First and last field
awk -F: &apos;{print $1,$NF}&apos; /etc/passwd

# With line number
awk -F: &apos;{print NR, $0}&apos; /etc/passwd

# Second last field
awk -F: &apos;{print $(NF-1)}&apos; /etc/passwd

# Custom string 
awk -F: &apos;{print $1 &quot;=&quot; $6}&apos; /etc/passwd
&lt;/code&gt;&lt;/pre&gt; 
&lt;h4&gt;Awk program examples&lt;/h4&gt; 
&lt;pre&gt;&lt;code&gt;awk &apos;BEGIN {print &quot;hello world&quot;}&apos;        # Prints &quot;hello world&quot;
awk -F: &apos;{print $1}&apos; /etc/passwd         # -F: Specify field separator

# /pattern/ Execute actions only for matched pattern
awk -F: &apos;/root/ {print $1}&apos; /etc/passwd                     

# BEGIN block is executed once at the start
awk -F: &apos;BEGIN { print &quot;uid&quot;} { print $1 }&apos; /etc/passwd     

# END block is executed once at the end
awk -F: &apos;{print $1} END { print &quot;-done-&quot;}&apos; /etc/passwd
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;&lt;strong&gt;Conditions&lt;/strong&gt;&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;awk &apos;{if ($3&amp;gt;30) print $1}&apos; /etc/passwd
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;&lt;strong&gt;Generate 1000 spaces&lt;/strong&gt;&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;awk &apos;BEGIN{
    while (a++ &amp;lt; 1000)
        s=s &quot; &quot;;
    print s
}&apos;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;&lt;strong&gt;Arrays&lt;/strong&gt;&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;awk &apos;BEGIN {
   fruits[&quot;mango&quot;] = &quot;yellow&quot;;
   fruits[&quot;orange&quot;] = &quot;orange&quot;
   print fruits[&quot;orange&quot;] 
   print fruits[&quot;mango&quot;]
}&apos;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;&lt;strong&gt;Functions&lt;/strong&gt;&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;# =&amp;gt; 5
awk &apos;BEGIN{print length(&quot;hello&quot;)}&apos;
# =&amp;gt; HELLO
awk &apos;BEGIN{print toupper(&quot;hello&quot;)}&apos;
# =&amp;gt; hel
awk &apos;BEGIN{print substr(&quot;hello&quot;, 1, 3)}&apos;
&lt;/code&gt;&lt;/pre&gt; 
&lt;h4&gt;Variables&lt;/h4&gt; 
&lt;p&gt;&lt;strong&gt;Build-in variables&lt;/strong&gt;&lt;/p&gt; 
&lt;table&gt; 
 &lt;thead&gt;&lt;/thead&gt; 
 &lt;tbody&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;$0&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Whole line &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;$1, $2...$NF&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; First, second… last field &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;NR&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Total &lt;code&gt;N&lt;/code&gt;umber of &lt;code&gt;R&lt;/code&gt;ecords &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;NF&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; &lt;code&gt;N&lt;/code&gt;number of &lt;code&gt;F&lt;/code&gt;ields &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;OFS&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; &lt;code&gt;O&lt;/code&gt;utput &lt;code&gt;F&lt;/code&gt;ield &lt;code&gt;S&lt;/code&gt;eparator &lt;br&gt; &lt;em&gt;(default &quot; &quot;)&lt;/em&gt; &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;FS&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; input &lt;code&gt;F&lt;/code&gt;ield &lt;code&gt;S&lt;/code&gt;eparator &lt;br&gt; &lt;em&gt;(default &quot; &quot;)&lt;/em&gt; &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;ORS&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; &lt;code&gt;O&lt;/code&gt;utput &lt;code&gt;R&lt;/code&gt;ecord &lt;code&gt;S&lt;/code&gt;eparator &lt;br&gt; &lt;em&gt;(default &quot;\n&quot;)&lt;/em&gt; &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;RS&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; input &lt;code&gt;R&lt;/code&gt;ecord &lt;code&gt;S&lt;/code&gt;eparator &lt;br&gt; &lt;em&gt;(default &quot;\n&quot;)&lt;/em&gt; &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;FILENAME&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Name of the file &lt;/td&gt;
  &lt;/tr&gt; 
 &lt;/tbody&gt; 
&lt;/table&gt; 
&lt;p&gt;&lt;strong&gt;Expressions&lt;/strong&gt;&lt;/p&gt; 
&lt;table&gt; 
 &lt;thead&gt;&lt;/thead&gt; 
 &lt;tbody&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;$1 == &quot;root&quot;&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; First field equals root &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;{print $(NF-1)}&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Second last field &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;NR!=1{print $0}&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; From 2th record &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;NR &amp;gt; 3&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; From 4th record &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;NR == 1&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; First record &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;END{print NR}&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Total records &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;BEGIN{print OFMT}&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Output format &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;{print NR, $0}&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Line number &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;{print NR &quot; &quot; $0}&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Line number (tab) &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;{$1 = NR; print}&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Replace 1th field with line number &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;$NF &amp;gt; 4&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Last field &amp;gt; 4 &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;NR % 2 == 0&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Even records &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;NR==10, NR==20&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Records 10 to 20 &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;BEGIN{print ARGC}&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Total arguments &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;ORS=NR%5?&quot;,&quot;:&quot;\n&quot;&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Concatenate records &lt;/td&gt;
  &lt;/tr&gt; 
 &lt;/tbody&gt; 
&lt;/table&gt; 
&lt;p&gt;&lt;strong&gt;Examples&lt;/strong&gt;&lt;br&gt; Print sum and average&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;awk -F: &apos;{sum += $3}
     END { print sum, sum/NR }
&apos; /etc/passwd
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Printing parameters&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;awk &apos;BEGIN {
    for (i = 1; i &amp;lt; ARGC; i++)
        print ARGV[i] }&apos; a b c
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Output field separator as a comma&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;awk &apos;BEGIN { FS=&quot;:&quot;;OFS=&quot;,&quot;}
    {print $1,$2,$3,$4}&apos; /etc/passwd
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Position of match&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;awk &apos;BEGIN {
    if (match(&quot;One Two Three&quot;, &quot;Tw&quot;))
        print RSTART }&apos;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Length of match&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;awk &apos;BEGIN {
    if (match(&quot;One Two Three&quot;, &quot;re&quot;))
        print RLENGTH }&apos;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;&lt;strong&gt;Environment Variables&lt;/strong&gt;&lt;/p&gt; 
&lt;table&gt; 
 &lt;thead&gt; 
  &lt;tr&gt;
   &lt;th&gt; - &lt;/th&gt;
   &lt;th&gt; - &lt;/th&gt;
  &lt;/tr&gt; 
 &lt;/thead&gt; 
 &lt;tbody&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;ARGC&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Number or arguments &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;ARGV&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Array of arguments &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;FNR&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; &lt;code&gt;F&lt;/code&gt;ile &lt;code&gt;N&lt;/code&gt;umber of &lt;code&gt;R&lt;/code&gt;ecords &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;OFMT&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Format for numbers &lt;br&gt; &lt;em&gt;(default &quot;%.6g&quot;)&lt;/em&gt; &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;RSTART&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Location in the string &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;RLENGTH&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Length of match &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;SUBSEP&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Multi-dimensional array separator &lt;br&gt; &lt;em&gt;(default &quot;\034&quot;)&lt;/em&gt; &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;ARGIND&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Argument Index &lt;/td&gt;
  &lt;/tr&gt; 
 &lt;/tbody&gt; 
&lt;/table&gt; 
&lt;h4&gt;GNU awk only&lt;/h4&gt; 
&lt;table&gt; 
 &lt;thead&gt; 
  &lt;tr&gt;
   &lt;th&gt; - &lt;/th&gt;
   &lt;th&gt; - &lt;/th&gt;
  &lt;/tr&gt; 
 &lt;/thead&gt; 
 &lt;tbody&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;ENVIRON&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Environment variables &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;IGNORECASE&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Ignore case &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;CONVFMT&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Conversion format &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;ERRNO&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; System errors &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;FIELDWIDTHS&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Fixed width fields &lt;/td&gt;
  &lt;/tr&gt; 
 &lt;/tbody&gt; 
&lt;/table&gt; 
&lt;p&gt;&lt;strong&gt;Defining variable&lt;/strong&gt;&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;awk -v var1=&quot;Hello&quot; -v var2=&quot;Wold&quot; &apos;
    END {print var1, var2}
&apos; &amp;lt;/dev/null
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;&lt;strong&gt;Use shell variables&lt;/strong&gt;&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;awk -v varName=&quot;$PWD&quot; &apos;
    END {print varName}&apos; &amp;lt;/dev/null
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;Operators&lt;/h3&gt; 
&lt;table&gt; 
 &lt;thead&gt; 
  &lt;tr&gt;
   &lt;th&gt; - &lt;/th&gt;
   &lt;th&gt; - &lt;/th&gt;
  &lt;/tr&gt; 
 &lt;/thead&gt; 
 &lt;tbody&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;{print $1}&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; First field &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;$2 == &quot;foo&quot;&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Equals &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;$2 != &quot;foo&quot;&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Not equals &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;&quot;foo&quot; in array&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; In array &lt;/td&gt;
  &lt;/tr&gt; 
 &lt;/tbody&gt; 
&lt;/table&gt; 
&lt;p&gt;&lt;strong&gt;Regular expression&lt;/strong&gt;&lt;/p&gt; 
&lt;table&gt; 
 &lt;thead&gt; 
  &lt;tr&gt;
   &lt;th&gt; - &lt;/th&gt;
   &lt;th&gt; - &lt;/th&gt;
  &lt;/tr&gt; 
 &lt;/thead&gt; 
 &lt;tbody&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;/regex/&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Line matches &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;!/regex/&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Line not matches &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;$1 ~ /regex/&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Field matches &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;$1 !~ /regex/&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Field not matches &lt;/td&gt;
  &lt;/tr&gt; 
 &lt;/tbody&gt; 
&lt;/table&gt; 
&lt;p&gt;&lt;strong&gt;More conditions&lt;/strong&gt;&lt;/p&gt; 
&lt;table&gt; 
 &lt;thead&gt; 
  &lt;tr&gt;
   &lt;th&gt; - &lt;/th&gt;
   &lt;th&gt; - &lt;/th&gt;
  &lt;/tr&gt; 
 &lt;/thead&gt; 
 &lt;tbody&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;($2 &amp;lt;= 4 || $3 &amp;lt; 20)&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Or &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;($1 == 4 &amp;amp;&amp;amp; $3 &amp;lt; 20)&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; And &lt;/td&gt;
  &lt;/tr&gt; 
 &lt;/tbody&gt; 
&lt;/table&gt; 
&lt;p&gt;&lt;strong&gt;Arithmetic operations&lt;/strong&gt;&lt;br&gt; - &lt;code&gt;+&lt;/code&gt;&lt;br&gt; - &lt;code&gt;-&lt;/code&gt;&lt;br&gt; - &lt;code&gt;*&lt;/code&gt;&lt;br&gt; - &lt;code&gt;/&lt;/code&gt;&lt;br&gt; - &lt;code&gt;%&lt;/code&gt;&lt;br&gt; - &lt;code&gt;++&lt;/code&gt;&lt;br&gt; - &lt;code&gt;--&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Shorthand assignments&lt;/strong&gt;&lt;br&gt; - &lt;code&gt;+=&lt;/code&gt;&lt;br&gt; - &lt;code&gt;-=&lt;/code&gt;&lt;br&gt; - &lt;code&gt;*=&lt;/code&gt;&lt;br&gt; - &lt;code&gt;/=&lt;/code&gt;&lt;br&gt; - &lt;code&gt;%=&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Comparison operators&lt;/strong&gt;&lt;br&gt; - &lt;code&gt;==&lt;/code&gt;&lt;br&gt; - &lt;code&gt;!=&lt;/code&gt;&lt;br&gt; - &lt;code&gt;&amp;lt;&lt;/code&gt;&lt;br&gt; - &lt;code&gt;&amp;gt;&lt;/code&gt;&lt;br&gt; - &lt;code&gt;&amp;lt;=&lt;/code&gt;&lt;br&gt; - &lt;code&gt;&amp;gt;=&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Examples&lt;/strong&gt;&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;awk &apos;BEGIN {
    if (&quot;foo&quot; ~ &quot;^fo+$&quot;)
        print &quot;Fooey!&quot;;
}&apos;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;&lt;strong&gt;Not match&lt;/strong&gt;&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;awk &apos;BEGIN {
    if (&quot;boo&quot; !~ &quot;^fo+$&quot;)
        print &quot;Boo!&quot;;
}&apos;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;&lt;strong&gt;if in array&lt;/strong&gt;&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;awk &apos;BEGIN {
    assoc[&quot;foo&quot;] = &quot;bar&quot;;
    assoc[&quot;bar&quot;] = &quot;baz&quot;;
    if (&quot;foo&quot; in assoc)
        print &quot;Fooey!&quot;;
}&apos;
&lt;/code&gt;&lt;/pre&gt; 
&lt;h4&gt;Functions&lt;/h4&gt; 
&lt;p&gt;&lt;strong&gt;Common functions&lt;/strong&gt;&lt;/p&gt; 
&lt;table&gt; 
 &lt;thead&gt; 
  &lt;tr&gt;
   &lt;th&gt; Function &lt;/th&gt;
   &lt;th&gt; Description &lt;/th&gt;
  &lt;/tr&gt; 
 &lt;/thead&gt; 
 &lt;tbody&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;index(s,t)&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Position in string s where string t occurs, 0 if not found &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;length(s)&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Length of string s (or $0 if no arg) &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;rand&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Random number between 0 and 1 &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;substr(s,index,len)&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Return len-char substring of s that begins at index (counted from 1) &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;srand&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Set seed for rand and return previous seed &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;int(x)&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Truncate x to integer value &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;split(s,a,fs)&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Split string s into array a split by fs, returning length of a &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;match(s,r)&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Position in string s where regex r occurs, or 0 if not found &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;sub(r,t,s)&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Substitute t for first occurrence of regex r in string s (or $0 if s not given) &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;gsub(r,t,s)&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Substitute t for all occurrences of regex r in string s &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;system(cmd)&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Execute cmd and return exit status &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;tolower(s)&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; String s to lowercase &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;toupper(s)&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; String s to uppercase &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;getline&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Set $0 to next input record from current input file. &lt;/td&gt;
  &lt;/tr&gt; 
 &lt;/tbody&gt; 
&lt;/table&gt; 
&lt;p&gt;&lt;strong&gt;User defined function&lt;/strong&gt;&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;awk &apos;
    # Returns minimum number
    function find_min(num1, num2){
       if (num1 &amp;lt; num2)
       return num1
       return num2
    }
    # Returns maximum number
    function find_max(num1, num2){
       if (num1 &amp;gt; num2)
       return num1
       return num2
    }
    # Main function
    function main(num1, num2){
       result = find_min(num1, num2)
       print &quot;Minimum =&quot;, result
      
       result = find_max(num1, num2)
       print &quot;Maximum =&quot;, result
    }
    # Script execution starts here
    BEGIN {
       main(10, 60)
    }
&apos;
&lt;/code&gt;&lt;/pre&gt; 
&lt;h4&gt;Arrays&lt;/h4&gt; 
&lt;p&gt;&lt;strong&gt;Array with index&lt;/strong&gt;&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;awk &apos;BEGIN {
    arr[0] = &quot;foo&quot;;
    arr[1] = &quot;bar&quot;;
    print(arr[0]); # =&amp;gt; foo
    delete arr[0];
    print(arr[0]); # =&amp;gt; &quot;&quot;
}&apos;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;&lt;strong&gt;Array with key&lt;/strong&gt;&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;awk &apos;BEGIN {
    assoc[&quot;foo&quot;] = &quot;bar&quot;;
    assoc[&quot;bar&quot;] = &quot;baz&quot;;
    print(&quot;baz&quot; in assoc); # =&amp;gt; 0
    print(&quot;foo&quot; in assoc); # =&amp;gt; 1
}&apos;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;&lt;strong&gt;Array with split&lt;/strong&gt;&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;awk &apos;BEGIN {
    split(&quot;foo:bar:baz&quot;, arr, &quot;:&quot;);
    for (key in arr)
        print arr[key];
}&apos;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;&lt;strong&gt;Array with asort&lt;/strong&gt;&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;awk &apos;BEGIN {
    arr[0] = 3
    arr[1] = 2
    arr[2] = 4
    n = asort(arr)
    for (i = 1; i &amp;lt;= n ; i++)
        print(arr[i])
}&apos;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;&lt;strong&gt;Multi-dimensional&lt;/strong&gt;&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;awk &apos;BEGIN {
    multidim[0,0] = &quot;foo&quot;;
    multidim[0,1] = &quot;bar&quot;;
    multidim[1,0] = &quot;baz&quot;;
    multidim[1,1] = &quot;boo&quot;;
}&apos;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;&lt;strong&gt;Multi-dimensional iteration&lt;/strong&gt;&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;awk &apos;BEGIN {
    array[1,2]=3;
    array[2,3]=5;
    for (comb in array) {
        split(comb,sep,SUBSEP);
        print sep[1], sep[2], 
        array[sep[1],sep[2]]
    }
}&apos;
&lt;/code&gt;&lt;/pre&gt; 
&lt;h4&gt;Conditions&lt;/h4&gt; 
&lt;p&gt;&lt;strong&gt;if-else statement&lt;/strong&gt;&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;awk -v count=2 &apos;BEGIN {
    if (count == 1)
        print &quot;Yes&quot;;
    else
        print &quot;Huh?&quot;;
}&apos;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;&lt;strong&gt;Ternary operator&lt;/strong&gt;&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;awk -v count=2 &apos;BEGIN {
    print (count==1) ? &quot;Yes&quot; : &quot;Huh?&quot;;
}&apos;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;&lt;strong&gt;Exists&lt;/strong&gt;&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;awk &apos;BEGIN {
    assoc[&quot;foo&quot;] = &quot;bar&quot;;
    assoc[&quot;bar&quot;] = &quot;baz&quot;;
    if (&quot;foo&quot; in assoc)
        print &quot;Fooey!&quot;;
}&apos;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;&lt;strong&gt;Not exists&lt;/strong&gt;&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;awk &apos;BEGIN {
    assoc[&quot;foo&quot;] = &quot;bar&quot;;
    assoc[&quot;bar&quot;] = &quot;baz&quot;;
    if (&quot;Huh&quot; in assoc == 0 )
        print &quot;Huh!&quot;;
}&apos;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;&lt;strong&gt;switch&lt;/strong&gt;&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;awk -F: &apos;{
    switch (NR * 2 + 1) {
        case 3:
        case &quot;11&quot;:
            print NR - 1
            break
        
        case /2[[:digit:]]+/:
            print NR
        
        default:
            print NR + 1
        
        case -1:
            print NR * -1
    }
}&apos; /etc/passwd
&lt;/code&gt;&lt;/pre&gt; 
&lt;h4&gt;Loops&lt;/h4&gt; 
&lt;p&gt;&lt;strong&gt;&lt;code&gt;for...i&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;awk &apos;BEGIN {
    for (i = 0; i &amp;lt; 10; i++)
        print &quot;i=&quot; i;
}&apos;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;**Powers of two between 1 and 100 **&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;awk &apos;BEGIN {
    for (i = 1; i &amp;lt;= 100; i *= 2)
        print i
}&apos;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;&lt;strong&gt;&lt;code&gt;for...in&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;awk &apos;BEGIN {
    assoc[&quot;key1&quot;] = &quot;val1&quot;
    assoc[&quot;key2&quot;] = &quot;val2&quot;
    for (key in assoc)
        print assoc[key];
}&apos;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;&lt;strong&gt;Arguments&lt;/strong&gt;&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;awk &apos;BEGIN {
    for (argnum in ARGV)
        print ARGV[argnum];
}&apos; a b c
&lt;/code&gt;&lt;/pre&gt; 
&lt;h4&gt;Examples&lt;/h4&gt; 
&lt;p&gt;&lt;strong&gt;Reverse records&lt;/strong&gt;&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;awk -F: &apos;{ x[NR] = $0 }
    END {
        for (i = NR; i &amp;gt; 0; i--)
        print x[i]
    }
&apos; /etc/passwd
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;&lt;strong&gt;Reverse fields&lt;/strong&gt;&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;awk -F: &apos;{
    for (i = NF; i &amp;gt; 0; i--)
        printf(&quot;%s &quot;,$i);
    print &quot;&quot;
}&apos; /etc/passwd
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;&lt;strong&gt;Sum by record&lt;/strong&gt;&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;awk -F: &apos;{
    s=0;
    for (i = 1; i &amp;lt;= NF; i++)
        s += $i;
    print s
}&apos; /etc/passwd
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;&lt;strong&gt;Sum whole file&lt;/strong&gt;&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;awk -F: &apos;
    {for (i = 1; i &amp;lt;= NF; i++)
        s += $i;
    };
    END{print s}
&apos; /etc/passwd
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;&lt;strong&gt;&lt;code&gt;while&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;awk &apos;BEGIN {
    while (a &amp;lt; 10) {
        print &quot;- &quot; &quot; concatenation: &quot; a
        a++;
    }
}&apos;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;&lt;strong&gt;&lt;code&gt;do...while&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;awk &apos;{
    i = 1
    do {
        print $0
        i++
    } while (i &amp;lt;= 5)
}&apos; /etc/passwd
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;&lt;strong&gt;Break&lt;/strong&gt;&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;awk &apos;BEGIN {
    break_num = 5
    for (i = 0; i &amp;lt; 10; i++) {
        print i
        if (i == break_num)
            break
    }
}&apos;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;&lt;strong&gt;Continue&lt;/strong&gt;&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;awk &apos;BEGIN {
    for (x = 0; x &amp;lt;= 10; x++) {
        if (x == 5 || x == 6)
            continue
        printf &quot;%d &quot;, x
    }
    print &quot;&quot;
}&apos;
&lt;/code&gt;&lt;/pre&gt; 
&lt;h4&gt;Formatted Printing&lt;/h4&gt; 
&lt;p&gt;&lt;strong&gt;Right align&lt;/strong&gt;&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;awk &apos;BEGIN{printf &quot;|%10s|\n&quot;, &quot;hello&quot;}&apos;

|     hello|
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;&lt;strong&gt;Left align&lt;/strong&gt;&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;awk &apos;BEGIN{printf &quot;|%-10s|\n&quot;, &quot;hello&quot;}&apos;

|hello     |
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;**Common specifiers **&lt;/p&gt; 
&lt;table&gt; 
 &lt;thead&gt; 
  &lt;tr&gt;
   &lt;th&gt; Character &lt;/th&gt;
   &lt;th&gt; Description &lt;/th&gt;
  &lt;/tr&gt; 
 &lt;/thead&gt; 
 &lt;tbody&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;c&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; ASCII character &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;d&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Decimal integer &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;e&lt;/code&gt;, &lt;code&gt;E&lt;/code&gt;, &lt;code&gt;f&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Floating-point format &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;o&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Unsigned octal value &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;s&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; String &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;%&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Literal % &lt;/td&gt;
  &lt;/tr&gt; 
 &lt;/tbody&gt; 
&lt;/table&gt; 
&lt;p&gt;&lt;strong&gt;Space&lt;/strong&gt;&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;awk -F: &apos;{
    printf &quot;%-10s %s\n&quot;, $1, $(NF-1)
}&apos; /etc/passwd | head -n 3
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Outputs&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-shell&quot;&gt;root       /root
bin        /bin
daemon     /sbin
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;&lt;strong&gt;Header&lt;/strong&gt;&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;awk -F: &apos;BEGIN {
    printf &quot;%-10s %s\n&quot;, &quot;User&quot;, &quot;Home&quot;
    printf &quot;%-10s %s\n&quot;, &quot;----&quot;,&quot;----&quot;}
    { printf &quot;%-10s %s\n&quot;, $1, $(NF-1) }
&apos; /etc/passwd | head -n 5
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Outputs&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;User       Home
----       ----
root       /root
bin        /bin
daemon     /sbin
&lt;/code&gt;&lt;/pre&gt; 
&lt;h4&gt;Miscellaneous&lt;/h4&gt; 
&lt;p&gt;&lt;strong&gt;Regex Metacharacters&lt;/strong&gt;&lt;br&gt; - &lt;code&gt;\&lt;/code&gt;&lt;br&gt; - &lt;code&gt;^&lt;/code&gt;&lt;br&gt; - &lt;code&gt;$&lt;/code&gt;&lt;br&gt; - &lt;code&gt;.&lt;/code&gt;&lt;br&gt; - &lt;code&gt;[&lt;/code&gt;&lt;br&gt; - &lt;code&gt;]&lt;/code&gt;&lt;br&gt; - &lt;code&gt;|&lt;/code&gt;&lt;br&gt; - &lt;code&gt;(&lt;/code&gt;&lt;br&gt; - &lt;code&gt;)&lt;/code&gt;&lt;br&gt; - &lt;code&gt;*&lt;/code&gt;&lt;br&gt; - &lt;code&gt;+&lt;/code&gt;&lt;br&gt; - &lt;code&gt;?&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Escape Sequences&lt;/strong&gt;&lt;/p&gt; 
&lt;table&gt; 
 &lt;thead&gt; 
  &lt;tr&gt;
   &lt;th&gt; - &lt;/th&gt;
   &lt;th&gt; - &lt;/th&gt;
  &lt;/tr&gt; 
 &lt;/thead&gt; 
 &lt;tbody&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;\b&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Backspace &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;\f&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Form feed &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;\n&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Newline (line feed) &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;\r&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Carriage return &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;\t&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Horizontal tab &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;\v&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Vertical tab &lt;/td&gt;
  &lt;/tr&gt; 
 &lt;/tbody&gt; 
&lt;/table&gt; 
&lt;p&gt;&lt;strong&gt;Run script&lt;/strong&gt;&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-shell&quot;&gt;$ cat demo.awk
#!/usr/bin/awk -f
BEGIN { x = 23 }
      { x += 2 }
END   { print x }
$ awk -f demo.awk /etc/passwd
69
&lt;/code&gt;&lt;/pre&gt;
	</description>
    </item>
    <item>
      <title>GCC static analyzer options</title>
      <link>https://tedneward.github.io/Research/tools/gcc/static-analyzer/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/gcc/static-analyzer/index.html</guid>
      	<description>
	&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://gcc.gnu.org/onlinedocs/gcc/Static-Analyzer-Options.html&quot;&gt;https://gcc.gnu.org/onlinedocs/gcc/Static-Analyzer-Options.html&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://gcc.gnu.org/wiki/DavidMalcolm/StaticAnalyzer&quot;&gt;https://gcc.gnu.org/wiki/DavidMalcolm/StaticAnalyzer&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;Static analysis in GCC 10 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://developers.redhat.com/blog/2020/03/26/static-analysis-in-gcc-10/&quot;&gt;https://developers.redhat.com/blog/2020/03/26/static-analysis-in-gcc-10/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Ghidra</title>
      <link>https://tedneward.github.io/Research/tools/ghidra/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/ghidra/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://ghidra-sre.org/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/NationalSecurityAgency/ghidra&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;JDK 21-based, using native plugins&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Gitea</title>
      <link>https://tedneward.github.io/Research/tools/gitea/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/gitea/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://gitea.com/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/go-gitea/gitea&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Gluey</title>
      <link>https://tedneward.github.io/Research/tools/glueysh/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/glueysh/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://gluey.sh/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/rebels-software/gluey&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Eleventy (11ty)</title>
      <link>https://tedneward.github.io/Research/tools/eleventy/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/eleventy/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.11ty.dev/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/11ty/eleventy/&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Excalidraw</title>
      <link>https://tedneward.github.io/Research/tools/excalidraw/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/excalidraw/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://excalidraw.com/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://docs.excalidraw.com/&quot;&gt;Docs&lt;/a&gt; | &lt;a href=&quot;https://github.com/excalidraw/excalidraw&quot;&gt;Source&lt;/a&gt; | &lt;a href=&quot;https://hub.docker.com/r/excalidraw/excalidraw&quot;&gt;DockerHub&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>FindBugs</title>
      <link>https://tedneward.github.io/Research/tools/findbugs/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/findbugs/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.methodsandtools.com/tools/findbugs.php&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;http://findbugs.sourceforge.net/&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Fluid</title>
      <link>https://tedneward.github.io/Research/tools/fluidapp/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/fluidapp/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://fluidapp.com/&quot;&gt;Website&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Free but no source.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Fray</title>
      <link>https://tedneward.github.io/Research/tools/fray/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/fray/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/cmu-pasta/fray&quot;&gt;Source&lt;/a&gt; | &lt;a href=&quot;https://dl.acm.org/doi/10.1145/3764119&quot;&gt;Paper&lt;/a&gt; | &lt;a href=&quot;https://arxiv.org/abs/2501.12618&quot;&gt;Technical Report&lt;/a&gt;&lt;/p&gt; 
&lt;h2&gt;Reading&lt;/h2&gt; 
&lt;h3&gt;Articles&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.infoq.com/news/2025/12/fray-detects-concurrency-issues/&quot;&gt;https://www.infoq.com/news/2025/12/fray-detects-concurrency-issues/&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>FunctionSimSearch</title>
      <link>https://tedneward.github.io/Research/tools/functionsimsearch/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/functionsimsearch/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/googleprojectzero/functionsimsearch&quot;&gt;Github&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://googleprojectzero.blogspot.com/2018/12/searching-statically-linked-vulnerable.html&quot;&gt;Searching statically-linked vulnerable library functions in executable code&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Gaphor</title>
      <link>https://tedneward.github.io/Research/tools/gaphor/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/gaphor/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://gaphor.org/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/gaphor/gaphor&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Elkhound</title>
      <link>https://tedneward.github.io/Research/tools/elkhound/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/elkhound/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;http://scottmcpeak.com/elkhound/sources/elkhound/index.html&quot;&gt;Website&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>FASTBuild</title>
      <link>https://tedneward.github.io/Research/tools/fastbuild/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/fastbuild/index.html</guid>
      	<description>
	&lt;p&gt;A high performance, open-source build system for Windows, Linux, and OS X. Supports highly scalable compilation, caching and network distribution.&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://www.fastbuild.org/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/fastbuild/fastbuild&quot;&gt;Github&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Find-Security-Bugs</title>
      <link>https://tedneward.github.io/Research/tools/findsecuritybugs/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/findsecuritybugs/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://find-sec-bugs.github.io/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/find-sec-bugs/find-sec-bugs&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Programmer fonts</title>
      <link>https://tedneward.github.io/Research/tools/fonts/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/fonts/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/tonsky/FiraCode&quot;&gt;FiraCode&lt;/a&gt;: Free monospaced font with programming ligatures&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Frida</title>
      <link>https://tedneward.github.io/Research/tools/frida/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/frida/index.html</guid>
      	<description>
	&lt;p&gt;Inject JavaScript to explore native apps on Windows, Mac, Linux, iOS, Android, and QNX.&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://www.frida.re/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/frida/frida&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://github.com/dweinstein/awesome-frida&quot;&gt;Awesome Frida&lt;/a&gt;: A curated list of Frida resources&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://github.com/agustingianni/memrepl&quot;&gt;MemREPL&lt;/a&gt;: Memory inspection REPL interface&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>FX</title>
      <link>https://tedneward.github.io/Research/tools/fx/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/fx/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://fx.wtf/&quot;&gt;Website&lt;/a&gt; (Currently redirects to) &lt;a href=&quot;https://github.com/antonmedv/fx&quot;&gt;Source&lt;/a&gt; | &lt;a href=&quot;https://github.com/antonmedv/fx/blob/master/DOCS.md&quot;&gt;Docs&lt;/a&gt;.&lt;/p&gt; 
&lt;p&gt;Install: &lt;code&gt;brew install fx&lt;/code&gt; or &lt;code&gt;npm install -g fx&lt;/code&gt;&lt;/p&gt; 
&lt;h2&gt;Usage&lt;/h2&gt; 
&lt;p&gt;Start &lt;a href=&quot;https://github.com/antonmedv/fx/blob/master/DOCS.md#interactive-mode&quot;&gt;interactive mode&lt;/a&gt; without passing any arguments.&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;$ curl ... | fx
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Or by passing filename as first argument.&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;$ fx data.json
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Pass a few JSON files.&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;cat foo.json bar.json baz.json | fx .message
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Use full power of JavaScript.&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;$ curl ... | fx &apos;.filter(x =&amp;gt; x.startsWith(&quot;a&quot;))&apos;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Access all lodash (or ramda, etc) methods by using &lt;a href=&quot;https://github.com/antonmedv/fx/blob/master/DOCS.md#using-fxrc&quot;&gt;.fxrc&lt;/a&gt; file.&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;$ curl ... | fx &apos;_.groupBy(&quot;commit.committer.name&quot;)&apos; &apos;_.mapValues(_.size)&apos;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Update JSON using spread operator.&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;$ echo &apos;{&quot;count&quot;: 0}&apos; | fx &apos;{...this, count: 1}&apos;
{
  &quot;count&quot;: 1
}
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Extract values from maps.&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;$ fx commits.json | fx .[].author.name
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Print formatted JSON to stdout.&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;$ curl ... | fx .
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Pipe JSON logs stream into fx.&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;$ kubectl logs ... -f | fx .message
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;And try this:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;$ fx --life
&lt;/code&gt;&lt;/pre&gt; 
&lt;h2&gt;Links&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;http://bit.ly/discover-how-to-use-fx-effectively&quot;&gt;Discover how to use fx effectively&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://bit.ly/youtube-fx-tutorial&quot;&gt;Video tutorial&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Related&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/antonmedv/gofx&quot;&gt;gofx&lt;/a&gt; – fx-like JSON tool (&lt;em&gt;go&lt;/em&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/antonmedv/eat&quot;&gt;eat&lt;/a&gt; – converts anything into JSON&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/matthewadams/ymlx&quot;&gt;ymlx&lt;/a&gt; – fx-like YAML cli processor&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/antonmedv/fx-completion&quot;&gt;fx-completion&lt;/a&gt; – bash completion for fx&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/antonmedv/fx-theme-monokai&quot;&gt;fx-theme-monokai&lt;/a&gt; – monokai theme&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/antonmedv/fx-theme-night&quot;&gt;fx-theme-night&lt;/a&gt; – night theme&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Gatsby (GatsbyJS)</title>
      <link>https://tedneward.github.io/Research/tools/gatsbyjs/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/gatsbyjs/index.html</guid>
      	<description>
	&lt;p&gt;title=Gatsby (GatsbyJS)&lt;br&gt; tags=tool, static site generator, nodejs&lt;br&gt; summary=React-based static site generator.&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;&lt;/code&gt;&lt;/pre&gt;
	</description>
    </item>
    <item>
      <title>Entire</title>
      <link>https://tedneward.github.io/Research/tools/entire/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/entire/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://entire.io/&quot;&gt;Website&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>FileBytes</title>
      <link>https://tedneward.github.io/Research/tools/filebytes/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/filebytes/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://scoding.de/filebytes-introduction&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/sashs/filebytes/&quot;&gt;Github&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Fizzy</title>
      <link>https://tedneward.github.io/Research/tools/fizzy/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/fizzy/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/basecamp/fizzy&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Forgejo</title>
      <link>https://tedneward.github.io/Research/tools/forgejo/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/forgejo/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://forgejo.org/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://codeberg.org/forgejo/forgejo&quot;&gt;Source&lt;/a&gt; | &lt;a href=&quot;https://forgejo.org/docs/latest/&quot;&gt;Docs&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Forgejo is a self-hosted lightweight software forge. Easy to install and low maintenance, it just does the job.&lt;/p&gt; 
&lt;p&gt;Built in Go, looks like.&lt;/p&gt; 
&lt;h1&gt;&lt;a href=&quot;https://codeberg.org/teaserbot-labs/delightful&quot;&gt;Delightful Forgejo&lt;/a&gt;&lt;/h1&gt; 
&lt;h2&gt;Official resources&lt;/h2&gt; 
&lt;p&gt;Resources maintained as part of the primary Forgejo project.&lt;br&gt; - &lt;a href=&quot;https://forgejo.org/&quot;&gt;![][forgejo] Forgejo website&lt;/a&gt;&lt;br&gt; - &lt;a href=&quot;https://forgejo.org/docs/latest/&quot;&gt;![][forgejo] Forgejo documentation&lt;/a&gt;&lt;br&gt; - &lt;a href=&quot;https://codeberg.org/forgejo/forgejo&quot;&gt;![][forgejo] Forgejo issue tracker&lt;/a&gt;&lt;br&gt; - &lt;a href=&quot;https://forgejo.org/releases&quot;&gt;![][forgejo] Forgejo releases&lt;/a&gt; (&lt;a href=&quot;https://forgejo.org/releases/rss.xml&quot;&gt;RSS feed&lt;/a&gt;; &lt;a href=&quot;https://codeberg.org/forgejo/forgejo/src/branch/forgejo/RELEASE-NOTES.md&quot;&gt;Release notes&lt;/a&gt;)&lt;br&gt; - &lt;a href=&quot;https://code.forgejo.org/forgejo/runner&quot;&gt;![][forgejo] Forgejo runner&lt;/a&gt;&lt;br&gt; - &lt;a href=&quot;https://codeberg.org/forgejo/-/packages/container/forgejo/versions&quot;&gt;![][forgejo] Forgejo container images&lt;/a&gt;&lt;br&gt; - &lt;a href=&quot;https://floss.social/@forgejo&quot;&gt;![][forgejo] Forgejo Mastodon account&lt;/a&gt;&lt;br&gt; - &lt;a href=&quot;https://keyoxide.org/contact@forgejo.org&quot;&gt;![][forgejo] Forgejo identity proofs (Keyoxide)&lt;/a&gt;&lt;/p&gt; 
&lt;h2&gt;Documentation&lt;/h2&gt; 
&lt;p&gt;In addition to &lt;a href=&quot;https://forgejo.org/docs/latest/&quot;&gt;![][forgejo] Forgejo&apos;s official documentation&lt;/a&gt;, the following resources may be useful.&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://docs.codeberg.org/&quot;&gt;Codeberg documentation&lt;/a&gt; - contains some Codeberg-specific parts but is mostly applicable to every Forgejo instance.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://docs.gitea.io/&quot;&gt;Gitea documentation&lt;/a&gt; - mostly applicable to Forgejo as well as Gitea.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Tutorials&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://devforum.roblox.com/t/forgejo-in-a-nutshell/2505867&quot;&gt;Forgejo in a nutshell&lt;/a&gt; - guide to setup Forgejo.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://blog.gibson.sh/2023/05/28/server-with-wireguard-and-forgejo/&quot;&gt;Forgejo with LFS behind a VPN&lt;/a&gt; - guide to set up a Linux web server running Forgejo, Git-LFS, and a Wireguard VPN.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://lab.uberspace.de/guide_forgejo/&quot;&gt;UberLab installation guide&lt;/a&gt; - Forgejo installation guide for &lt;a href=&quot;https://uberspace.de/&quot;&gt;Uberspace&lt;/a&gt;.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://linus.dev/posts/setting-up-a-self-hosted-forgejo-actions-runner-with-docker-compose/&quot;&gt;Setting up a Self-Hosted Forgejo Actions Runner with Docker Compose&lt;/a&gt;.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://jan.wildeboer.net/2024/08/Running-a-runner-codeberg/&quot;&gt;Running a runner for codeberg/forgejo on RHEL9 (Red Hat Enterprise Linux) with podman as user systemd service&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Public instances&lt;/h2&gt; 
&lt;p&gt;Forgejo instances with open registration.&lt;br&gt; - &lt;a href=&quot;https://codeberg.org&quot;&gt;Codeberg&lt;/a&gt; - free and open &lt;em&gt;for FOSS projects only&lt;/em&gt;, run by a German non-profit organization. Also provides hosted Woodpecker (CI) and Weblate (localisation).&lt;br&gt; - &lt;a href=&quot;https://codefloe.com&quot;&gt;CodeFloe&lt;/a&gt; - free and open. Legally operated by &lt;a href=&quot;https://devxy.io&quot;&gt;devXY&lt;/a&gt;, a Swiss DevOps company. Open to community engagement and management.&lt;br&gt; Provides Crow CI and Forgejo Actions for CI/CD and a &lt;a href=&quot;https://forum.codefloe.com&quot;&gt;Forum&lt;/a&gt; for public user discussions.&lt;br&gt; - &lt;a href=&quot;https://disroot.org/en/services/git&quot;&gt;Disroot&lt;/a&gt; - a platform providing online services based on principles of freedom, privacy, federation and decentralization. Also provides many other free hosted services.&lt;br&gt; - &lt;a href=&quot;https://git.pub.solar&quot;&gt;pub.solar&lt;/a&gt; - Register/Login via &lt;a href=&quot;https://auth.pub.solar&quot;&gt;pub.solar ID&lt;/a&gt;, run by a German tech collective with the goal to enable more people to use free software, have secure digital communications, and to take control over their private data.&lt;br&gt; - &lt;a href=&quot;https://git.kaki87.net&quot;&gt;KaKi&apos;s git&lt;/a&gt; - free and open, run by a French web developer.&lt;br&gt; - &lt;a href=&quot;https://sij.ai&quot;&gt;sij.ai&lt;/a&gt; - Free and open platform run by a public interest environmental lawyer that is open for anyone but especially intended for AI-ML hobbyists &amp;amp; enthusiasts.&lt;br&gt; - &lt;a href=&quot;https://git.gay/&quot;&gt;git.gay&lt;/a&gt; - instance run by &lt;a href=&quot;https://besties.house/&quot;&gt;Besties&lt;/a&gt;, a queer collective. Uses modified version of Forgejo.&lt;br&gt; - &lt;a href=&quot;https://bolha.dev/&quot;&gt;bolha.dev&lt;/a&gt; - instance run by &lt;a href=&quot;https://bolha.us/&quot;&gt;bolha.us&lt;/a&gt;, and &lt;a href=&quot;https://bolha.io/&quot;&gt;bolha.io&lt;/a&gt; a Brazilian IT collective. Running the vanilla version.&lt;/p&gt; 
&lt;h2&gt;Packaging&lt;/h2&gt; 
&lt;p&gt;Platform-specific packages to easily install and update Forgejo on your system. These are generally maintained either by distro packagers or by community volunteers.&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://repology.org/project/forgejo/versions&quot;&gt;&lt;br&gt; &lt;img src=&quot;https://repology.org/badge/vertical-allrepos/forgejo.svg&quot; alt=&quot;Packaging status&quot; align=&quot;right&quot;&gt;&lt;br&gt; &lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Also see &lt;a href=&quot;https://repology.org/project/forgejo/versions&quot;&gt;forgejo package versions on Repology&lt;/a&gt;.&lt;br&gt; - &lt;strong&gt;Alpine&lt;/strong&gt;&lt;br&gt; - &lt;a href=&quot;https://pkgs.alpinelinux.org/packages?name=forgejo&quot;&gt;Alpine community &lt;code&gt;forgejo&lt;/code&gt; package&lt;/a&gt;&lt;br&gt; - &lt;a href=&quot;https://pkgs.alpinelinux.org/packages?name=forgejo-lts&quot;&gt;Alpine community &lt;code&gt;forgejo-lts&lt;/code&gt; package&lt;/a&gt;&lt;br&gt; - &lt;strong&gt;Arch Linux&lt;/strong&gt;&lt;br&gt; - &lt;a href=&quot;https://archlinux.org/packages/extra/x86_64/forgejo&quot;&gt;Arch extra &lt;code&gt;forgejo&lt;/code&gt; package&lt;/a&gt;&lt;/p&gt; &lt;!-- - **AOSC OS**
	- 👻 [AOSC OS stable `forgejo` package](https://packages.aosc.io/packages/forgejo)--&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;strong&gt;Debian/Ubuntu&lt;/strong&gt; 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://codeberg.org/forgejo-contrib/forgejo-deb&quot;&gt;Unofficial &lt;code&gt;forgejo-deb&lt;/code&gt; packages + repo&lt;/a&gt; &lt;img src=&quot;https://codeberg.org/forgejo-contrib/forgejo-deb/badges/release.svg&quot; alt=&quot;package version&quot;&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Fedora&lt;/strong&gt; 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://packages.fedoraproject.org/pkgs/forgejo/&quot;&gt;Fedora &lt;code&gt;forgejo&lt;/code&gt; package&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://copr.fedorainfracloud.org/coprs/mdwalters/forgejo/&quot;&gt;RPM copr repo&lt;/a&gt; &lt;img src=&quot;https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fcopr.fedorainfracloud.org%2Fapi_3%2Fpackage%2F%3Fownername%3Dmdwalters%26projectname%3Dforgejo%26packagename%3Dforgejo%26with_latest_build%3Dfalse%26with_latest_succeeded_build%3Dfalse&amp;amp;query=%24.builds.latest_succeeded.source_package.version&amp;amp;label=version&quot; alt=&quot;package version&quot;&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;FreeBSD&lt;/strong&gt; 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.freshports.org/www/forgejo&quot;&gt;Port &lt;code&gt;www/forgejo&lt;/code&gt; / package &lt;code&gt;forgejo&lt;/code&gt;&lt;/a&gt; - binary packages available in latest and quarterly 2024Q2 or newer.&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Gentoo&lt;/strong&gt; 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://gitweb.gentoo.org/repo/proj/guru.git/tree/www-apps/forgejo&quot;&gt;Gentoo GURU &lt;code&gt;www-apps/forgejo&lt;/code&gt; package&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Kubernetes&lt;/strong&gt; 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://codeberg.org/forgejo-contrib/forgejo-helm&quot;&gt;Helm chart&lt;/a&gt; - Helm chart for Forgejo, forked from the official Gitea helm chart&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://repo.prod.meissa.de/meissa/c4k-forgejo&quot;&gt;c4k-forgejo&lt;/a&gt; - Convention 4 Kubernetes, generates a kubernetes manifest for Forgejo including backup &amp;amp; monitoring.&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;NixOS&lt;/strong&gt; 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://nixos.org/manual/nixos/stable/options#opt-services.forgejo.enable&quot;&gt;NixOS &lt;code&gt;forgejo&lt;/code&gt; service&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Snapcraft&lt;/strong&gt; 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://codeberg.org/forgejo-contrib/snap&quot;&gt;Unofficial &lt;code&gt;forgejo&lt;/code&gt; snap package&lt;/a&gt; - building in &lt;a href=&quot;https://launchpad.net/~popey/forgejo-snap/+snap/forgejo-snap&quot;&gt;launchpad&lt;/a&gt; &lt;img src=&quot;https://snapcraft.io/forgejo/badge.svg&quot; alt=&quot;package version&quot;&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Termux (Android)&lt;/strong&gt; 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/termux/termux-packages/tree/master/packages/forgejo&quot;&gt;Termux &lt;code&gt;forgejo&lt;/code&gt; package&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;YunoHost&lt;/strong&gt; 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/YunoHost-Apps/forgejo_ynh&quot;&gt;YunoHost package&lt;/a&gt; - install Forgejo quickly and simply on a YunoHost server&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; &lt;!-- - **Cloudron**
	- 👻 [Cloudron package](https://codeberg.org/bart/forgejo-app) - Install Forgejo on a Cloudron server--&gt; 
&lt;h2&gt;CI/CD&lt;/h2&gt; 
&lt;p&gt;CI/CD tools that integrate via Forgejo officially or inofficially.&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;#forgejo-actions&quot;&gt;Forgejo Actions&lt;/a&gt; - the integrated CI/CD solution with external runners. See below.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://woodpecker-ci.org/&quot;&gt;Woodpecker CI&lt;/a&gt; - a community-maintained powerful CI/CD based on Docker containers, historically forked from Drone CI. 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://crowci.dev/&quot;&gt;Crow CI&lt;/a&gt; - a soft-fork of Woodpecker CI.&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.jenkins.io/&quot;&gt;Jenkins&lt;/a&gt; - an extensible CI/CD with a large plugin ecosystem. 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://plugins.jenkins.io/gitea/&quot;&gt;Gitea Plugin&lt;/a&gt; - use Jenkins with Forgejo (API-compatible to Gitea).&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://plugins.jenkins.io/gitea-checks/&quot;&gt;Gitea Checks Plugin&lt;/a&gt; - use Forgejo status checks with Jenkins.&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://codeberg.org/emersion/yojo&quot;&gt;yoyo Sourcehut CI bridge&lt;/a&gt; - develop on Forgejo and run builds within the Sourcehut CI.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://agola.io/&quot;&gt;agola&lt;/a&gt; - containerized and flexible CI/CD platform.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.buildbot.net/&quot;&gt;Buildbot&lt;/a&gt; - a flexible CI/CD framework. Can be used &lt;a href=&quot;https://github.com/lab132/buildbot-gitea&quot;&gt;with a plugin&lt;/a&gt;.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://codeberg.org/snaums/mvoCI&quot;&gt;mvoCI&lt;/a&gt; - a simple and personal CI/CD solution.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Forgejo Actions&lt;/h2&gt; 
&lt;p&gt;Learn about Forgejo actions in the &lt;a href=&quot;https://forgejo.org/docs/latest/admin/actions/&quot;&gt;![][forgejo] Actions admin guide&lt;/a&gt; and &lt;a href=&quot;https://forgejo.org/docs/latest/user/actions/&quot;&gt;![][forgejo] Actions user guide&lt;/a&gt;.&lt;/p&gt; 
&lt;h3&gt;Actions runners&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://code.forgejo.org/forgejo/runner&quot;&gt;![][forgejo] Forgejo runner&lt;/a&gt; - supports LXC &amp;amp; Docker &amp;amp; shell with binaries for GNU/Linux (amd64, arm64)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://gitea.com/gitea/act_runner&quot;&gt;act runner&lt;/a&gt; - supports Docker &amp;amp; shell with binaries for GNU/Linux (amd64, arm64, arm[567]), FreeBSD, Windows, MacOS&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Actions runner deployment tools&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://codeberg.org/pierreprinetti/forgejo-hetzner-runner&quot;&gt;forgejo-hetzner-runner&lt;/a&gt; - Deploy Forgejo Actions runners on Hetzner infrastructure&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://codeberg.org/wrenix/helm-charts/src/branch/main/forgejo-runner&quot;&gt;helm-chart&lt;/a&gt; - Deploy a Forgejo Actions runner on the specified Forgejo instance&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Actions&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://code.forgejo.org/Seltsamsel/trust-self-signed-cert&quot;&gt;trust-self-signed-cert&lt;/a&gt; - Trust a self-signed SSL certificate for future operations (e.g. checkout action).&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://codeberg.org/kemitix/forgejo-todo-checker&quot;&gt;forgejo-todo-checker&lt;/a&gt; - Checks your source files for TODO and FIXME comments, where they don&apos;t have an open issue number.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://codeberg.org/kemitix/forgejo-commit-path-rules&quot;&gt;forgejo-commit-path-rules&lt;/a&gt; - Enforce consistency between commit messages and file changes in your repository.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://codeberg.org/Native-CI/&quot;&gt;Native-CI&lt;/a&gt; - A collection of actions for helping maintain native projects (C/C++/...) that may require cross-platform builds.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Clients&lt;/h2&gt; 
&lt;h3&gt;CMS (Content Management System)&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/sveltia/sveltia-cms&quot;&gt;Sveltia CMS&lt;/a&gt; - Configurable admin panel for static site generator authoring.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://decapcms.org/docs/gitea-backend/&quot;&gt;DecapCMS&lt;/a&gt; (&lt;a href=&quot;https://github.com/decaporg/decap-cms&quot;&gt;repo&lt;/a&gt;) - Configurable admin panel for static site generator authoring.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Mobile&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://gitnex.com/&quot;&gt;GitNex&lt;/a&gt; (&lt;a href=&quot;https://codeberg.org/gitnex/GitNex&quot;&gt;repo&lt;/a&gt;) - Android client for Forgejo and Gitea (&lt;code&gt;Android – GPL&lt;/code&gt;)&lt;/li&gt; 
 &lt;li&gt;👻 &lt;a href=&quot;https://github.com/git-touch/git-touch&quot;&gt;GitTouch&lt;/a&gt; - Mobile client for Forgejo, Gitea, GitHub, GitLab, Bitbucket (&lt;code&gt;Android, iOS – Apache&lt;/code&gt;)&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Command-line&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://codeberg.org/Aviac/codeberg-cli&quot;&gt;codeberg-cli&lt;/a&gt; - CLI tool for Forgejo similar to &lt;code&gt;gh&lt;/code&gt;, &lt;code&gt;glab&lt;/code&gt; and &lt;code&gt;tea&lt;/code&gt; (&lt;code&gt;cross-platform - AGPL&lt;/code&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://codeberg.org/forgejo-contrib/forgejo-cli&quot;&gt;forgejo-cli&lt;/a&gt; - CLI tool for interacting with Forgejo (&lt;code&gt;cross-platform - Apache/MIT&lt;/code&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://code.forgejo.org/forgejo/forgejo-curl&quot;&gt;![][forgejo] forgejo-curl&lt;/a&gt; - a thin curl wrapper that helps with Forgejo authentication&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://gitea.com/gitea/tea&quot;&gt;tea&lt;/a&gt; - the official Gitea CLI client, works with Forgejo (&lt;code&gt;cross-platform – MIT&lt;/code&gt;)&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Emacs&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://codeberg.org/martianh/fj.el&quot;&gt;fj.el&lt;/a&gt; - a basic Emacs client for Forgejo.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Tools&lt;/h2&gt; 
&lt;h3&gt;Infrastructure as Code&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://forgejo.dev/forgejo.dev/infrastructure-as-code/&quot;&gt;Terraform &amp;amp; Ansible playbook&lt;/a&gt; - Deploy Forgejo, Minio, Nginx &amp;amp; Woodpecker in the cloud via &lt;a href=&quot;https://docs.docker.com/compose/&quot;&gt;Docker Compose&lt;/a&gt;, depends on related &lt;a href=&quot;https://github.com/geerlingguy&quot;&gt;geerlingguy&lt;/a&gt; playbooks.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://registry.terraform.io/providers/svalabs/forgejo/latest/docs&quot;&gt;Terraform Provider for Forgejo&lt;/a&gt; - Allows managing resources (organizations, repositories, users) within Forgejo.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://galaxy.ansible.com/ui/repo/published/l3d/git/content/role/gitea/&quot;&gt;Ansible Collection l3d.git.gitea&lt;/a&gt; - Ansible collection to install and configure forgejo.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Monitoring&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://gitea.zionetrix.net/bn8/check_forgejo_upgrade&quot;&gt;Monitoring plugin to check Forgejo instance upgrade status&lt;/a&gt; has the sources and is published in the &lt;a href=&quot;https://exchange.icinga.com/brenard/check_forgejo_upgrade&quot;&gt;Icinga exchange repository&lt;/a&gt;.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Bots&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;👻 &lt;a href=&quot;https://codeberg.org/spla/gitcat.git&quot;&gt;gitcat&lt;/a&gt; - Python script that allows sign-up to a Forgejo instance to all local users of a Mastodon server. (&lt;code&gt;Python - GPLv3&lt;/code&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://docs.renovatebot.com/modules/platform/gitea/#gitea-and-forgejo&quot;&gt;Renovate&lt;/a&gt; - Dependency update tool (similar to dependabot) with Forgejo support. (&lt;code&gt;TypeScript - AGPLv3&lt;/code&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://codeberg.org/kita/nayrah&quot;&gt;Nayrah&lt;/a&gt; - A Discord bot that retrieves various information from a Forgejo instance like Codeberg. (&lt;code&gt;Python - AGPLv3&lt;/code&gt;)&lt;/li&gt; 
 &lt;li&gt;👻 &lt;a href=&quot;https://git.4rs.nl/awiteb/forgejo-guardian&quot;&gt;forgejo-guardian&lt;/a&gt; - Simple Forgejo instance guardian, banning users and alerting admins based on certain regular expressions. (&lt;code&gt;Rust - AGPLv3&lt;/code&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://codeberg.org/kemitix/git-next&quot;&gt;git-next&lt;/a&gt; - Trunk-based development manager (with Forgejo &amp;amp; Github support).&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Scripts&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/maxkratz/github2gitea-mirror&quot;&gt;github2gitea/github2forgejo&lt;/a&gt; - Bash script that creates mirrors for various GitHub resources like orgs, users and starred repos (incl. private repos). (&lt;code&gt;Bash - AGPLv3&lt;/code&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://git.kaki87.net/KaKi87/userscripts/src/branch/master/enhancementsForForgejo/README.md&quot;&gt;Enhancements for Forgejo&lt;/a&gt; - Violentmonkey userscript that adds minor UX improvements to the web UI. (&lt;code&gt;JavaScript - MIT&lt;/code&gt;)&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Package deployment&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://codeberg.org/rome-user/lein-forgejo-wagon&quot;&gt;lein-forgejo-wagon&lt;/a&gt; - Leiningen plugin for deployment and downloading of JARs in Maven repositories hosted on Forgejo packages.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;API client libraries&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://codeberg.org/Cyborus/forgejo-api&quot;&gt;Cyborus/forgejo-api&lt;/a&gt; - Rust crate to interact with the Forgejo API (&lt;code&gt;Rust - Apache or MIT&lt;/code&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://codeberg.org/harabat/pyforgejo&quot;&gt;harabat/pyforgejo&lt;/a&gt; - Python client library to interact with the Forgejo API (&lt;code&gt;Python - MIT&lt;/code&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://codeberg.org/mvdkleijn/forgejo-sdk&quot;&gt;mvdkleijn/forgejo-sdk&lt;/a&gt; - Go client library to interact with the Forgejo API (fork of &lt;a href=&quot;https://gitea.com/gitea/go-sdk&quot;&gt;gitea/go-sdk&lt;/a&gt;) (&lt;code&gt;Go - MIT&lt;/code&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://codeberg.org/anbraten/forgejo-js&quot;&gt;forgejo-js&lt;/a&gt; - JavaScript / Typescript&lt;br&gt; library to interact with the Forgejo API (fork of &lt;a href=&quot;https://github.com/anbraten/gitea-js&quot;&gt;gitea-js&lt;/a&gt;) (&lt;code&gt;JavaScript / Typescript - MIT&lt;/code&gt;)&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Forks&lt;/h2&gt; 
&lt;p&gt;Actively maintained Forgejo forks.&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://fordj.org/&quot;&gt;Fordj&lt;/a&gt; - a git-based design-platform for the AEC (Architecture, Engineering and Construction).&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://codeberg.org/forgejo-aneksajo/forgejo-aneksajo/&quot;&gt;Forgejo-aneksajo&lt;/a&gt; - (temporary) fork of Forgejo that adds an integration with git-annex.&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>FSNotesApp</title>
      <link>https://tedneward.github.io/Research/tools/fsnotes/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/fsnotes/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://fsnot.es/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/glushchenko/fsnotes&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;h3&gt;Features&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;Markdown-first. Also supports plaintext and RTF files.&lt;/li&gt; 
 &lt;li&gt;Fast and lightweight. Works smoothly with 10k+ files.&lt;/li&gt; 
 &lt;li&gt;Access anywhere. Sync with iCloud Drive or Dropbox.&lt;/li&gt; 
 &lt;li&gt;Multi-folder storage.&lt;/li&gt; 
 &lt;li&gt;Keyboard-centric. nvalt-inspired controls and shortcuts.&lt;/li&gt; 
 &lt;li&gt;Syntax highlighting within code blocks. Supports over 170 programming languages.&lt;/li&gt; 
 &lt;li&gt;In-line image support.&lt;/li&gt; 
 &lt;li&gt;Organize with tags.&lt;/li&gt; 
 &lt;li&gt;Cross-note links using [[double brackets]].&lt;/li&gt; 
 &lt;li&gt;Elastic two-pane view. Choose a vertical or horizontal layout.&lt;/li&gt; 
 &lt;li&gt;External editor support (changes seamless live sync with UI).&lt;/li&gt; 
 &lt;li&gt;Pin important notes.&lt;/li&gt; 
 &lt;li&gt;Quickly copy notes to the clipboard.&lt;/li&gt; 
 &lt;li&gt;Dark mode.&lt;/li&gt; 
 &lt;li&gt;Lock sensitive notes with AES-256 encryption.&lt;/li&gt; 
 &lt;li&gt;Mermaid and MathJax support.&lt;/li&gt; 
 &lt;li&gt;Optional Git versioning and backups.&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>fzf</title>
      <link>https://tedneward.github.io/Research/tools/fzf/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/fzf/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/junegunn/fzf&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>GCC</title>
      <link>https://tedneward.github.io/Research/tools/gcc/index/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/gcc/index/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://gcc.gnu.org/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://web.archive.org/web/20170326232435/http://www.network-theory.co.uk/docs/gccintro/index.html&quot;&gt;An Introduction to GCC&lt;/a&gt; - Brian Gough&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;GCC online documentation - &lt;a href=&quot;https://gcc.gnu.org/onlinedocs/&quot;&gt;https://gcc.gnu.org/onlinedocs/&lt;/a&gt; 
  &lt;ul&gt; 
   &lt;li&gt;Cynbe&apos;s GCC Debugging Hints - &lt;a href=&quot;http://muq.org/~cynbe/gcc/&quot;&gt;http://muq.org/~cynbe/gcc/&lt;/a&gt; 
    &lt;ul&gt; 
     &lt;li&gt;Debugging Resources - &lt;a href=&quot;http://muq.org/~cynbe/gcc/offsite-resources.html&quot;&gt;http://muq.org/~cynbe/gcc/offsite-resources.html&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;Comments on the Internals Manual - &lt;a href=&quot;http://muq.org/~cynbe/gcc/gccint.html&quot;&gt;http://muq.org/~cynbe/gcc/gccint.html&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;GCC Wiki - &lt;a href=&quot;https://gcc.gnu.org/wiki&quot;&gt;https://gcc.gnu.org/wiki&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;&lt;a href=&quot;https://gcc.gnu.org/projects/cxx-status.html&quot;&gt;C++ Status&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;/tools/gcc/static-analyzer&quot;&gt;Static analyzer options&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://tldp.org/HOWTO/GCC-Frontend-HOWTO.html&quot;&gt;GCC Front-end HOWTO&lt;/a&gt;: How to build a GCC front-end (so GCC can take care of the rest)&lt;/p&gt; 
&lt;h2&gt;Viewing exported symbols from executables&lt;/h2&gt; 
&lt;h3&gt;&lt;code&gt;readelf&lt;/code&gt;&lt;/h3&gt; 
&lt;pre&gt;&lt;code&gt;$ readelf -s lib.so
Symbol table &apos;.dynsym&apos; contains 8 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND 
     1: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND _ITM_deregisterT[...]
     2: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND puts@GLIBC_2.2.5 (2)
     3: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND __gmon_start__
     4: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND _ITM_registerTMC[...]
     5: 0000000000000000     0 FUNC    WEAK   DEFAULT  UND [...]@GLIBC_2.2.5 (2)
     6: 000000000000111f    22 FUNC    GLOBAL DEFAULT   12 lib_exported2
     7: 0000000000001109    22 FUNC    GLOBAL DEFAULT   12 lib_exported1
...
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;&lt;code&gt;objdump&lt;/code&gt;&lt;/h3&gt; 
&lt;pre&gt;&lt;code&gt;$ objdump -T lib.so
lib.so:     file format elf64-x86-64
DYNAMIC SYMBOL TABLE:
0000000000000000  w   D  *UND*	0000000000000000  Base        _ITM_deregisterTMCloneTable
0000000000000000      DF *UND*	0000000000000000  GLIBC_2.2.5 puts
0000000000000000  w   D  *UND*	0000000000000000  Base        __gmon_start__
0000000000000000  w   D  *UND*	0000000000000000  Base        _ITM_registerTMCloneTable
0000000000000000  w   DF *UND*	0000000000000000  GLIBC_2.2.5 __cxa_finalize
000000000000111f g    DF .text	0000000000000016  Base        lib_exported2
0000000000001109 g    DF .text	0000000000000016  Base        lib_exported1
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Does not demangle C++ names unless passed the `--demangle`` flag.&lt;/p&gt; 
&lt;h3&gt;&lt;code&gt;nm&lt;/code&gt;&lt;/h3&gt; 
&lt;pre&gt;&lt;code&gt;$ nm -D --demangle lib.so
                 w __cxa_finalize@GLIBC_2.2.5
                 w __gmon_start__
                 w _ITM_deregisterTMCloneTable
                 w _ITM_registerTMCloneTable
                 U puts@GLIBC_2.2.5
0000000000001109 T lib_exported1()
000000000000111f T lib_exported2()
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Does not demangle C++ names unless passed `--demangle`` flag.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>exa</title>
      <link>https://tedneward.github.io/Research/tools/exa/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/exa/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://the.exa.website/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://the.exa.website/introduction&quot;&gt;Docs&lt;/a&gt; | &lt;a href=&quot;https://the.exa.website/install/source&quot;&gt;Sources&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Fileformat</title>
      <link>https://tedneward.github.io/Research/tools/fileformat/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/fileformat/index.html</guid>
      	<description>
	&lt;p&gt;COFF, ELF, Intel HEX, Mach-O, PE, raw data&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://github.com/avast-tl/fileformat&quot;&gt;Github&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>FlubuCore</title>
      <link>https://tedneward.github.io/Research/tools/flubucore/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/flubucore/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://flubucore.dotnetcore.xyz/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/dotnetcore/FlubuCore/&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Examples:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;[FromArg(&quot;nugetKey&quot;, &quot;Nuget api key for publishing Flubu nuget packages.&quot;)]
public string NugetApiKey { get; set; }

protected override void ConfigureTargets(ITaskContext context)
{
    var pack = context.CreateTarget(&quot;Pack&quot;)
        .SetDescription(&quot;Prepare&apos;s nuget package.&quot;)
        .AddCoreTask(x =&amp;gt; x.Pack()
            .NoBuild()
            .OutputDirectory(OutputDirectory)
            .WithArguments(&quot;--force&quot;); //you can add your own custom arguments on each task

    var branch = context.BuildSystems().Travis().Branch;

    //// Examine travis.yaml to see how to pass api key from travis to FlubuCore build script.
    var nugetPush = context.CreateTarget(&quot;Nuget.publish&quot;)
        .SetDescription(&quot;Publishes nuget package.&quot;)
        .DependsOn(pack)
        .AddCoreTask(x =&amp;gt; x.NugetPush($&quot;{OutputDirectory}/NetCoreOpenSource.nupkg&quot;)
            .ServerUrl(&quot;https://www.nuget.org/api/v2/package&quot;)
             .ApiKey(NugetApiKey)
        )
        .When((c) =&amp;gt; c.BuildSystems().RunningOn == BuildSystemType.TravisCI
                     &amp;amp;&amp;amp; !string.IsNullOrEmpty(branch)
                     &amp;amp;&amp;amp; branch.EndsWith(&quot;stable&quot;, StringComparison.OrdinalIgnoreCase));
}
&lt;/code&gt;&lt;/pre&gt; 
&lt;pre&gt;&lt;code&gt;context.CreateTarget(&quot;build&quot;)
   .AddTask(x =&amp;gt; x.GitVersionTask())
   .AddTask(x =&amp;gt; x.CompileSolutionTask(&quot;MySolution.sln&quot;).BuildConfiguration(&quot;Release&quot;);

context.CreateTarget(&quot;run.tests&quot;)
   .AddTask(x =&amp;gt; x.XunitTaskByProjectName(&quot;MyProject&quot;).StopOnFail())
   .AddTask(x =&amp;gt; x.NUnitTask(NunitCmdOptions.V3, &quot;MyProject2&quot;).ExcludeCategory(&quot;Linux&quot;))
   .AddCoreTask(x =&amp;gt; x.CoverletTask(&quot;MyProject.dll&quot;));
&lt;/code&gt;&lt;/pre&gt; 
&lt;pre&gt;&lt;code&gt;[NugetPackage(&quot;Newtonsoft.json&quot;, &quot;11.0.2&quot;)]
[Assembly(&quot;.\Lib\EntityFramework.dll&quot;)]
public class BuildScript : DefaultBuildScript
{
   public void NuGetPackageReferencingExample(ITaskContext context)
    {
        JsonConvert.SerializeObject(&quot;Example&quot;);
    }
}
&lt;/code&gt;&lt;/pre&gt; 
&lt;pre&gt;&lt;code&gt;public class SimpleScript : DefaultBuildScript
{
    protected override void ConfigureTargets(ITaskContext context)
    {
        context.CreateTarget(&quot;Run.Libz&quot;)
        .AddTask(x =&amp;gt; x.RunProgramTask(@&quot;packages\LibZ.Tool\1.2.0\tools\libz.exe&quot;)
            .WorkingFolder(@&quot;.\src&quot;)
            .WithArguments(&quot;add&quot;)
            .WithArguments(&quot;--libz&quot;, &quot;Assemblies.libz&quot;));
    }
}
&lt;/code&gt;&lt;/pre&gt; 
&lt;pre&gt;&lt;code&gt;public class SimpleScript : DefaultBuildScript
{
    [FromArg(&quot;c&quot;, &quot;The configuration to use for building the project.&quot;)]
    public string Configuration { get; set; } = &quot;Release&quot;

    [FromArg(&quot;sn&quot;, &quot;If true app is deployed on second node. Otherwise not.&quot;)]
    public bool deployOnSecondNode { get; set; }

    protected override void ConfigureTargets(ITaskContext context)
    {
         context.CreateTarget(&quot;build&quot;)
            .AddCoreTask(x =&amp;gt; x.Build()
                .Configuration(Configuration)
                .ForMember(x =&amp;gt;  x.Framework(&quot;net462&quot;), &quot;f&quot;, &quot;The target framework to build for.&quot;)); 
    }
}
&lt;/code&gt;&lt;/pre&gt; 
&lt;pre&gt;&lt;code&gt;dotnet tool install --global FlubuCore.GlobalTool
flubu compile
&lt;/code&gt;&lt;/pre&gt; 
&lt;pre&gt;&lt;code&gt;context.WaitForDebugger();
&lt;/code&gt;&lt;/pre&gt;
	</description>
    </item>
    <item>
      <title>formae</title>
      <link>https://tedneward.github.io/Research/tools/formae/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/formae/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://platform.engineering/formae&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/platform-engineering-labs/formae&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;formae&lt;/strong&gt; doesn&apos;t require its user to maintain any secondary artifacts such as state files, and keeps the infrastructure code automatically in sync with the reality.&lt;/p&gt; 
&lt;h2&gt;&lt;strong&gt;formae&lt;/strong&gt; capabilities&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;strong&gt;The single source of truth is code:&lt;/strong&gt; It unifies every infrastructure resource and change into fully versioned infrastructure code.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Always up-to-data infrastructure code:&lt;/strong&gt; It sees when things change outside the tool. It merges these changes into your infrastructure code instead of just ignoring or undoing them. This way, important outside changes are never lost, and are immediately incorporated into the infrastructure code.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Prevents avoidable mistakes:&lt;/strong&gt; It is built around a very robust, enforced schema.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Made for everyone:&lt;/strong&gt; It welcomes all kinds of engineers, whether they are new or experienced, be they in Ops, DevOps, SRE or Platform Engineering.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Perfect for Platform Engineering:&lt;/strong&gt; It allows platform engineers to work on the low level of detail, and developers consume reusable services by just providing a few predefined, schema-safe properties.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Built for co-existence:&lt;/strong&gt; It is not necessary to migrate or to import anything - &lt;strong&gt;formae&lt;/strong&gt; will automatically discover and update resources and happily co-exist with other IaC and Infrastructure Management tools and even ClickOps.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Perfect for Day 0 and onward:&lt;/strong&gt; It is equally great for setting up new systems and for making small, safe changes with minimal blast radius as you go.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;How to Use &lt;strong&gt;formae&lt;/strong&gt; in Your Organization?&lt;/h2&gt; 
&lt;p&gt;Using &lt;strong&gt;formae&lt;/strong&gt; is straightforward and designed to fit various team roles, needs and daily operation scenarios and situations:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Core Platform Engineers:&lt;/strong&gt; A small group of engineers with broad responsibilities can manage the main infrastructure code. They can make large, system-wide changes. They often use GitOps (managing infrastructure through Git), but &lt;strong&gt;formae&lt;/strong&gt; doesn&apos;t enforce this.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Engineers with Specific Roles &amp;amp; Developers:&lt;/strong&gt; Engineers who are newer, or those who focus on smaller parts of the system, can make small changes. Developers needing to adjust specific resources can also apply these small patches. This keeps the risk of impact (blast radius) very small.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;On-Call Engineers (Emergency Fixes):&lt;/strong&gt; An engineer fixing an urgent issue, even at night, works like those making small changes. No matter their experience, they focus on fixing the problem with minimal risk to other parts of the system. This helps them solve issues quickly and safely.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Specialized Teams (Security, Cost Optimization):&lt;/strong&gt; Teams that work across different areas, like security or cost-saving groups, can also apply changes as patches. They might not change the core infrastructure, but their changes can affect many parts of the system. &lt;strong&gt;formae&lt;/strong&gt; handles these wider-reaching but targeted changes easily.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Working with Other Tools:&lt;/strong&gt; In many companies, people use different tools to make changes directly in cloud accounts. These could be special security tools or other IaC tools like Terraform, or even ClickOps. &lt;strong&gt;formae&lt;/strong&gt; works well alongside them. It detects these external changes and merges them, giving you a consistent, version-controlled and always up-to-date view of your entire infrastructure - &lt;strong&gt;entirely as code&lt;/strong&gt;.&lt;/p&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Reading&lt;/h2&gt; 
&lt;h3&gt;Articles&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.infoq.com/news/2025/10/iac-formae/&quot;&gt;New Infrastructure-as-Code Tool &quot;formae&quot; Takes Aim at Terraform&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>fuite</title>
      <link>https://tedneward.github.io/Research/tools/fuite/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/fuite/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/nolanlawson/fuite&quot;&gt;Sources&lt;/a&gt; | &lt;a href=&quot;https://nolanlawson.com/2021/12/17/introducing-fuite-a-tool-for-finding-memory-leaks-in-web-apps/&quot;&gt;Blog post introducing it&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Gaia</title>
      <link>https://tedneward.github.io/Research/tools/gaia/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/gaia/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://gaia-pipeline.io/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/gaia-pipeline/gaia&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Use code to build pipelines (Job objects). GUI dashboard.&lt;/p&gt; 
&lt;p&gt;Supports Go, Java, Python, C++, NodeJS, Ruby&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Programming-language independent&lt;/li&gt; 
 &lt;li&gt;First class support for tests&lt;/li&gt; 
 &lt;li&gt;Simple and efficient&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>curl</title>
      <link>https://tedneward.github.io/Research/tools/curl/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/curl/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://curl.se/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://everything.curl.dev/&quot;&gt;Book: Everything Curl&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>DBeaver</title>
      <link>https://tedneward.github.io/Research/tools/dbeaver/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/dbeaver/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://dbeaver.io/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/dbeaver/dbeaver&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Supports MySQL, PostgreSQL, SQLite, Oracle, DB2, SQL Server, Sybase, MS Access, Teradata, Firebird, Apache Hive, Phoenix, Presto, etc.&lt;/p&gt; 
&lt;p&gt;(Written in Java, so probably supports anything with a JDBC driver.)&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Detect-It-Easy</title>
      <link>https://tedneward.github.io/Research/tools/detect-it-easy/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/detect-it-easy/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/horsicq/Detect-It-Easy&quot;&gt;Github&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Diataxis</title>
      <link>https://tedneward.github.io/Research/tools/diataxis/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/diataxis/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://diataxis.fr/&quot;&gt;Website&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&quot;It prescribes approaches to content, architecture and form that emerge from a systematic approach to understanding the needs of documentation users.&lt;/p&gt; 
&lt;p&gt;&quot;Diátaxis identifies four distinct needs, and four corresponding forms of documentation - tutorials, how-to guides, technical reference and explanation. It places them in a systematic relationship, and proposes that documentation should itself be organised around the structures of those needs.&quot;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>DocToc</title>
      <link>https://tedneward.github.io/Research/tools/doctoc/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/doctoc/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/thlorenz/doctoc&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Links are compatible with anchors generated by github or other sites via a command line flag.&lt;/p&gt; 
&lt;p&gt;Source repo has examples of how to use it in a git hook.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Dr Memory</title>
      <link>https://tedneward.github.io/Research/tools/drmemory/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/drmemory/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;http://drmemory.org/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/DynamoRIO/drmemory&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Practical memory checking with Dr. Memory 
  &lt;ul&gt; 
   &lt;li&gt;Code Generation and Optimization (CGO) 2011&lt;/li&gt; 
   &lt;li&gt;Derek Bruening, Qin Zhao&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.researchgate.net/publication/224236404_Practical_memory_checking_with_Dr_Memory&quot;&gt;https://www.researchgate.net/publication/224236404_Practical_memory_checking_with_Dr_Memory&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://www.burningcutlery.com/derek/docs/drmem-CGO11.pdf&quot;&gt;http://www.burningcutlery.com/derek/docs/drmem-CGO11.pdf&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Dagger</title>
      <link>https://tedneward.github.io/Research/tools/dagger/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/dagger/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://dagger.io/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/dagger/dagger&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Features:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Use &lt;a href=&quot;/languages/cuelang&quot;&gt;CUE&lt;/a&gt; (a config language), not Yaml&lt;/li&gt; 
 &lt;li&gt;CUE is all about actions&lt;/li&gt; 
 &lt;li&gt; &lt;h1&gt;Dagger helps create custom actions in any language&lt;/h1&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;h1&gt;Dagger provides a huge collection of reusable actions&lt;/h1&gt; &lt;/li&gt; 
 &lt;li&gt;Run &quot;dagger do deploy&quot; to test &amp;amp; debug on your local machine&lt;/li&gt; 
 &lt;li&gt;Run Dagger pipelines on any Docker compatible runtimes&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;Run sample TODO app&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt; &lt;p&gt;Clone &amp;amp; run the following&lt;/p&gt; &lt;pre&gt;&lt;code&gt;git clone https://github.com/dagger/dagger
cd dagger
git checkout v0.2.4
cd pkg/universe.dagger.io/examples/todoapp
dagger do build
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;You should see the output similar to below&lt;/p&gt; &lt;pre&gt;&lt;code&gt;[✔] actions.deps                   62.1s
[✔] actions.build.run.script   0.4s
[✔] actions.test.script        0.5s
[✔] client.filesystem.&quot;./&quot;.read                  0.6s
[✔] actions.test                 2.0s
[✔] actions.build.run           12.4s
[✔] actions.build.contents    0.1s
[✔] client.filesystem.&quot;./_build&quot;.write      0.2s
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Run the following command to see your application up &amp;amp; running&lt;/p&gt; &lt;pre&gt;&lt;code&gt;start _build/index.html
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Update the application and see changes&lt;/p&gt; 
  &lt;ul&gt; 
   &lt;li&gt;In the todoapp directory, edit line 25 of src/components/Form.js by updating to &quot;What must be done today?&quot; &amp;amp; save the file&lt;/li&gt; 
   &lt;li&gt;Now run &quot;dagger do build&quot; again &amp;amp; then start _build/index.html to see latest changes&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>ddbug</title>
      <link>https://tedneward.github.io/Research/tools/ddbug/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/ddbug/index.html</guid>
      	<description>
	&lt;p&gt;ddbug is a utility that can extract useful information from DWARF/PDB debugging data. Its goal is to use the debugging information to provide insights into the code generation. Supports: ELF files with DWARF, Mach-O files with DWARF, Windows PDB files (mimimal)&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://github.com/gimli-rs/ddbug&quot;&gt;Github&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>devenv.sh</title>
      <link>https://tedneward.github.io/Research/tools/devenv/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/devenv/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://devenv.sh/&quot;&gt;Website&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Dify</title>
      <link>https://tedneward.github.io/Research/tools/dify/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/dify/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://dify.ai/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/langgenius/dify/&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Dify is an open-source LLM app development platform. Its intuitive interface combines AI workflow, RAG pipeline, agent capabilities, model management, observability features (including &lt;a href=&quot;https://www.comet.com/docs/opik/integrations/dify&quot;&gt;Opik&lt;/a&gt;, &lt;a href=&quot;https://docs.langfuse.com/&quot;&gt;Langfuse&lt;/a&gt;, and &lt;a href=&quot;https://docs.arize.com/phoenix&quot;&gt;Arize Phoenix&lt;/a&gt;) and more, letting you quickly go from prototype to production.&lt;/p&gt; 
&lt;h2&gt;Quick start&lt;/h2&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;Before installing Dify, make sure your machine meets the following minimum system requirements:&lt;/p&gt; 
 &lt;ul&gt; 
  &lt;li&gt;CPU &amp;gt;= 2 Core&lt;/li&gt; 
  &lt;li&gt;RAM &amp;gt;= 4 GiB&lt;/li&gt; 
 &lt;/ul&gt; 
&lt;/blockquote&gt; 
&lt;p&gt;The easiest way to start the Dify server is through &lt;a href=&quot;https://github.com/langgenius/dify/blob/main/docker/docker-compose.yaml&quot;&gt;Docker Compose&lt;/a&gt;. Before running Dify with the following commands, make sure that &lt;a href=&quot;https://docs.docker.com/get-docker/&quot;&gt;Docker&lt;/a&gt; and &lt;a href=&quot;https://docs.docker.com/compose/install/&quot;&gt;Docker Compose&lt;/a&gt; are installed on your machine:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;    cd dify
    cd docker
    cp .env.example .env
    docker compose up -d
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;After running, you can access the Dify dashboard in your browser at &lt;a href=&quot;http://localhost/install&quot;&gt;http://localhost/install&lt;/a&gt; and start the initialization process.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Dog/Doge</title>
      <link>https://tedneward.github.io/Research/tools/dog/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/dog/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://dog.ramfield.net/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/Dj-Codeman/dog_community&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;code&gt;dog-community&lt;/code&gt; is a maintained fork of the beloved terminal DNS client (dog/doge). It keeps the human-readable output you know, adds steady fixes, and supports DNS over HTTPS/TLS with JSON output for scripting.&lt;/p&gt; 
&lt;h2&gt;Usage&lt;/h2&gt; 
&lt;p&gt;Basics&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;doge example.net                         # default query
doge example.net MX                      # specific record type
doge example.net MX @1.1.1.1             # specific nameserver
doge example.net MX @1.1.1.1 -T          # TCP instead of UDP
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Arguments style&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;doge -q example.net -t MX -n 1.1.1.1 -T  # explicit flags
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;JSON &amp;amp; scripting&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;doge example.com AAAA -J | jq .
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Protocol modes&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;-U/--udp     # DNS over UDP
-T/--tcp     # DNS over TCP
-S/--tls     # DNS over TLS
-H/--https   # DNS over HTTPS
&lt;/code&gt;&lt;/pre&gt;
	</description>
    </item>
    <item>
      <title>DuneShell</title>
      <link>https://tedneward.github.io/Research/tools/duneshell/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/duneshell/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://adam-mcdaniel.github.io/dune-website/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/adam-mcdaniel/dune&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Darke</title>
      <link>https://tedneward.github.io/Research/tools/darke/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/darke/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://darke.handmade.network/&quot;&gt;Website&lt;/a&gt; | Not sure where the files are&lt;/p&gt; 
&lt;p&gt;Darke Files is a version control and file synchronization system. Its goal is to scale seamlessly between the two extremes:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;a full-featured version control system. It lets you work with branches and inspect and act on a rich version history. It works like version control systems programmers use today, for example Git.&lt;/li&gt; 
 &lt;li&gt;a file synchronization tool. It uploads your changed files to cloud storage so that you can forget it exists in the day-to-day operation. It works like cloud synchronization services everyone else uses, for example Dropbox or Google Drive.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;Darke Files can scale between those two extremes in a single repository. This enables teams with a wide range of requirements for such a system to work on the same project.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>deck</title>
      <link>https://tedneward.github.io/Research/tools/deck/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/deck/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/k1LoW/deck&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;h2&gt;Installation&lt;/h2&gt; 
&lt;p&gt;&lt;strong&gt;Homebrew:&lt;/strong&gt;&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-console&quot;&gt;$ brew install deck
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;&lt;strong&gt;go install:&lt;/strong&gt;&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-console&quot;&gt;$ go install github.com/k1LoW/deck/cmd/deck@latest
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;&lt;strong&gt;Manual installation:&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;Download the binary from the &lt;a href=&quot;https://github.com/k1LoW/deck/releases&quot;&gt;releases page&lt;/a&gt;&lt;/p&gt; 
&lt;h2&gt;Usage&lt;/h2&gt; 
&lt;h3&gt;Setup&lt;/h3&gt; 
&lt;h4&gt;Get and set your OAuth client credentials&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;Create (or reuse) a developer project at &lt;a href=&quot;https://console.cloud.google.com&quot;&gt;https://console.cloud.google.com&lt;/a&gt;.&lt;/li&gt; 
 &lt;li&gt;Enable &lt;a href=&quot;https://console.cloud.google.com/apis/library/slides.googleapis.com&quot;&gt;&lt;code&gt;Google Slides API&lt;/code&gt;&lt;/a&gt; and &lt;a href=&quot;https://console.cloud.google.com/apis/library/drive.googleapis.com&quot;&gt;&lt;code&gt;Google Drive API&lt;/code&gt;&lt;/a&gt; at the &lt;a href=&quot;https://console.cloud.google.com/apis/dashboard&quot;&gt;&lt;code&gt;API &amp;amp; Services&lt;/code&gt; page&lt;/a&gt;.&lt;/li&gt; 
 &lt;li&gt;Go to the &lt;a href=&quot;https://console.cloud.google.com/apis/credentials&quot;&gt;&lt;code&gt;Credentials&lt;/code&gt; page&lt;/a&gt; and click &lt;a href=&quot;https://console.cloud.google.com/auth/clients/create&quot;&gt;&lt;code&gt;+ CREATE CREDENTIALS&lt;/code&gt;&lt;/a&gt; at the top.&lt;/li&gt; 
 &lt;li&gt;Create an &lt;code&gt;OAuth client ID&lt;/code&gt; type of credentials.&lt;/li&gt; 
 &lt;li&gt;Choose the type &lt;code&gt;Desktop app&lt;/code&gt;. 
  &lt;ul&gt; 
   &lt;li&gt;Since there is no need to publish the app, add your email address as a test user from &lt;a href=&quot;https://console.cloud.google.com/auth/audience&quot;&gt;Google Auth Platform / Audience&lt;/a&gt;.&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Download the credentials file to &lt;code&gt;${XDG_DATA_HOME:-~/.local/share}/deck/credentials.json&lt;/code&gt;.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;For CI/CD automation (Service Account)&lt;/h4&gt; 
&lt;p&gt;If you&apos;re setting up &lt;code&gt;deck&lt;/code&gt; for automated workflows (GitHub Actions, CI/CD pipelines), see &lt;a href=&quot;docs/setup-service-account.md&quot;&gt;Service Account Setup Guide&lt;/a&gt;.&lt;/p&gt; 
&lt;h4&gt;Check your setup with &lt;code&gt;deck doctor&lt;/code&gt;&lt;/h4&gt; 
&lt;p&gt;You can verify if &lt;code&gt;deck&lt;/code&gt; is ready to use and diagnose any configuration issues with the &lt;code&gt;deck doctor&lt;/code&gt; command.&lt;/p&gt; 
&lt;h3&gt;Prepare presentation ID and markdown file with &lt;code&gt;deck new&lt;/code&gt;&lt;/h3&gt; 
&lt;p&gt;&lt;code&gt;deck&lt;/code&gt; requires two main components:&lt;br&gt; - &lt;strong&gt;Presentation ID&lt;/strong&gt;: A unique identifier for your Google Slides presentation (e.g., &lt;code&gt;xxxxxXXXXxxxxxXXXXxxxxxxxxxx&lt;/code&gt; from the URL &lt;code&gt;https://docs.google.com/presentation/d/xxxxxXXXXxxxxxXXXXxxxxxxxxxx/edit&lt;/code&gt;)&lt;br&gt; - &lt;strong&gt;Markdown file&lt;/strong&gt;: Your slide content written in markdown format&lt;/p&gt; 
&lt;h4&gt;When creating a new presentation&lt;/h4&gt; 
&lt;p&gt;You can create a new presentation with the &lt;code&gt;deck new&lt;/code&gt; command:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-console&quot;&gt;$ deck new deck.md --title &quot;Talk about deck&quot;
Applied frontmatter to deck.md
xxxxxXXXXxxxxxXXXXxxxxxxxxxx
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;This will create (or update) the given markdown file with frontmatter containing the presentation ID and title.&lt;/p&gt; 
&lt;h5&gt;Reusing theme from an existing presentation&lt;/h5&gt; 
&lt;p&gt;To reuse the theme from an existing presentation, you have two options:&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Option 1: Use the &lt;code&gt;--base&lt;/code&gt; flag&lt;/strong&gt;&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-console&quot;&gt;$ deck new deck.md --base yyyyyyyYYYYyYYYYYYYyyyyyyyyy --title &quot;Talk about deck&quot;
xxxxxXXXXxxxxxXXXXxxxxxxxxxx
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;&lt;strong&gt;Option 2: Set a default base presentation in your configuration file&lt;/strong&gt;&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-yaml&quot;&gt;# ~/.config/deck/config.yml
basePresentationID: &quot;yyyyyyyYYYYyYYYYYYYyyyyyyyyy&quot;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;With this configuration, you can reuse the theme from the base presentation without using the &lt;code&gt;--base&lt;/code&gt; flag. If both the configuration and &lt;code&gt;--base&lt;/code&gt; flag are present, the &lt;code&gt;--base&lt;/code&gt; flag takes precedence.&lt;/p&gt; 
&lt;h4&gt;When using an existing presentation&lt;/h4&gt; 
&lt;p&gt;Get the presentation ID you want to work with. You can list all presentations with &lt;code&gt;deck ls&lt;/code&gt;.&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-console&quot;&gt;$ deck ls
xxxxxXXXXxxxxxXXXXxxxxxxxxxx    My Presentation
yyyyyYYYYyyyyyYYYYyyyyyyyyyy    Team Project Slides
&lt;/code&gt;&lt;/pre&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;[!NOTE]&lt;br&gt; &lt;code&gt;deck&lt;/code&gt; fully supports Google Shared Drives (Team Drives). Presentations stored in shared drives are automatically included in listings and can be operated on just like personal drive presentations.&lt;/p&gt; 
&lt;/blockquote&gt; 
&lt;p&gt;To use this presentation, specify it with the &lt;code&gt;--presentation-id&lt;/code&gt; flag or add it to your markdown file&apos;s frontmatter as &lt;code&gt;presentationID&lt;/code&gt;.&lt;/p&gt; 
&lt;h3&gt;Write your slides in markdown&lt;/h3&gt; 
&lt;p&gt;Edit your markdown file with your favorite editor. Among horizontal rule syntaxes, three or more consecutive hyphens at the beginning of a line (e.g. &lt;code&gt;---&lt;/code&gt;) are treated as slide page separators. See &lt;a href=&quot;#markdown-file-format-for-deck&quot;&gt;Markdown file format for &lt;code&gt;deck&lt;/code&gt;&lt;/a&gt; for details.&lt;/p&gt; 
&lt;h3&gt;Apply markdown content to Google Slides with &lt;code&gt;deck apply&lt;/code&gt;&lt;/h3&gt; 
&lt;pre&gt;&lt;code class=&quot;language-console&quot;&gt;$ deck apply deck.md
&lt;/code&gt;&lt;/pre&gt; 
&lt;h4&gt;Watch mode&lt;/h4&gt; 
&lt;p&gt;You can use the &lt;code&gt;--watch&lt;/code&gt; flag to continuously monitor changes to your markdown file and automatically apply them to the presentation:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-console&quot;&gt;$ deck apply --watch deck.md
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;This is useful during the content creation process as it allows you to see your changes reflected in the presentation in real-time as you edit the markdown file.&lt;/p&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;[!NOTE]&lt;br&gt; The &lt;code&gt;--watch&lt;/code&gt; flag cannot be used together with the &lt;code&gt;--page&lt;/code&gt; flag.&lt;/p&gt; 
&lt;/blockquote&gt; 
&lt;h3&gt;Open presentation in your browser with &lt;code&gt;deck open&lt;/code&gt;&lt;/h3&gt; 
&lt;p&gt;You can open your Google Slides presentation in your default web browser:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-console&quot;&gt;$ deck open deck.md
&lt;/code&gt;&lt;/pre&gt; 
&lt;h2&gt;Markdown file format for &lt;code&gt;deck&lt;/code&gt;&lt;/h2&gt; 
&lt;p&gt;The Markdown used by &lt;code&gt;deck&lt;/code&gt; consists of YAML frontmatter and a body section.&lt;/p&gt; 
&lt;h3&gt;YAML Frontmatter&lt;/h3&gt; 
&lt;p&gt;&lt;code&gt;deck&lt;/code&gt; accepts YAML frontmatter at the beginning of your markdown file.&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-markdown&quot;&gt;---
presentationID: xxxxxXXXXxxxxxXXXXxxxxxxxxxx
title: Talk about deck
---

# First Slide

Content...
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;The frontmatter must be:&lt;br&gt; - At the very beginning of the file&lt;br&gt; - Enclosed between &lt;code&gt;---&lt;/code&gt; delimiters&lt;br&gt; - Valid YAML syntax&lt;br&gt; - Use &lt;code&gt;camelCase&lt;/code&gt; for fields used in &lt;code&gt;deck&lt;/code&gt; settings&lt;/p&gt; 
&lt;h4&gt;Available fields&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;code&gt;presentationID&lt;/code&gt; (string): Google Slides presentation ID. When specified, you can use the simplified command syntax.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;title&lt;/code&gt; (string): The title of the presentation. When specified, you can use the simplified command syntax.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;breaks&lt;/code&gt; (boolean): Control how line breaks are rendered. Default (&lt;code&gt;false&lt;/code&gt; or omitted) renders line breaks as spaces. When &lt;code&gt;true&lt;/code&gt;, line breaks in markdown are rendered as actual line breaks in slides. Can also be configured globally in &lt;code&gt;config.yml&lt;/code&gt;.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;codeBlockToImageCommand&lt;/code&gt; (string): Command to convert code blocks to images. When specified, code blocks in the presentation will be converted to images using this command. Can also be configured globally in &lt;code&gt;config.yml&lt;/code&gt;.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;defaults&lt;/code&gt; (array): Define conditional actions using CEL (Common Expression Language) expressions. Actions are automatically applied to pages based on page structure and content. Only applies to pages without explicit page configuration. Can also be configured globally in &lt;code&gt;config.yml&lt;/code&gt;.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Supported Markdown syntax&lt;/h3&gt; 
&lt;p&gt;&lt;code&gt;deck&lt;/code&gt; supports CommonMark and selected GitHub Flavored Markdown extensions. For comprehensive documentation, see &lt;a href=&quot;docs/markdown.md&quot;&gt;Markdown Support Documentation&lt;/a&gt;.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Key supported features:&lt;/strong&gt;&lt;br&gt; - Bold ( &lt;code&gt;**bold**&lt;/code&gt; )&lt;br&gt; - Italic ( &lt;code&gt;*italic*&lt;/code&gt; &lt;code&gt;__italic__&lt;/code&gt; )&lt;br&gt; - Strikethrough ( &lt;code&gt;~~strikethrough~~&lt;/code&gt; )&lt;br&gt; - List ( &lt;code&gt;-&lt;/code&gt; &lt;code&gt;*&lt;/code&gt; )&lt;br&gt; - Ordered list ( &lt;code&gt;1.&lt;/code&gt; &lt;code&gt;1)&lt;/code&gt; )&lt;br&gt; - Link ( &lt;code&gt;[Link](https://example.com)&lt;/code&gt; )&lt;br&gt; - Angle bracket autolinks ( &lt;code&gt;&amp;lt;https://example.com&amp;gt;&lt;/code&gt; )&lt;br&gt; - Code ( &lt;code&gt;`code`&lt;/code&gt; )&lt;br&gt; - &lt;code&gt;&amp;lt;br&amp;gt;&lt;/code&gt; (for newline)&lt;br&gt; - Image (&lt;code&gt;![Image](path/to/image.png)&lt;/code&gt; )&lt;br&gt; - Block quote ( &lt;code&gt;&amp;gt; block quote&lt;/code&gt; )&lt;br&gt; - Table (GitHub Flavored Markdown tables)&lt;br&gt; - RAW inline HTML (e.g., &lt;code&gt;&amp;lt;mark&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;small&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;kbd&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;cite&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;q&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;span&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;u&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;s&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;del&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;ins&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;sub&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;sup&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;var&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;samp&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;data&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;dfn&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;time&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;abbr&amp;gt;&lt;/code&gt;)&lt;/p&gt; 
&lt;h4&gt;Line break handling&lt;/h4&gt; 
&lt;p&gt;&lt;code&gt;deck&lt;/code&gt; provides configurable line break behavior through the &lt;code&gt;breaks&lt;/code&gt; setting:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;strong&gt;Default (&lt;code&gt;breaks: false&lt;/code&gt;)&lt;/strong&gt;: Single line breaks become spaces (per CommonMark/GFM specs)&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;With &lt;code&gt;breaks: true&lt;/code&gt;&lt;/strong&gt;: Line breaks are preserved (GitHub-style rendering)&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;For explicit breaks&lt;/strong&gt;: Use hard line break syntax (two spaces at line end per CommonMark standard) or &lt;code&gt;&amp;lt;br&amp;gt;&lt;/code&gt; tag&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;Example with &lt;code&gt;breaks: true&lt;/code&gt;:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-markdown&quot;&gt;---
breaks: true
---
Text with
line breaks
preserved
&lt;/code&gt;&lt;/pre&gt; 
&lt;h4&gt;Comments&lt;/h4&gt; 
&lt;p&gt;HTML comments &lt;code&gt;&amp;lt;!--&lt;/code&gt; &lt;code&gt;--&amp;gt;&lt;/code&gt; are used for speaker notes or &lt;a href=&quot;#page-configuration&quot;&gt;page configuration&lt;/a&gt;.&lt;/p&gt; 
&lt;h2&gt;How markdown maps to slide placeholders&lt;/h2&gt; 
&lt;p&gt;&lt;code&gt;deck&lt;/code&gt; inserts values according to the following rules regardless of the slide layout.&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;The shallowest heading level within each slide content is treated as the title and inserted into the title placeholder ( &lt;code&gt;CENTERED_TITLE&lt;/code&gt; or &lt;code&gt;TITLE&lt;/code&gt; ) in order.&lt;/li&gt; 
 &lt;li&gt;In most cases, this will be H1 (&lt;code&gt;#&lt;/code&gt;), which is the standard for slide titles&lt;/li&gt; 
 &lt;li&gt;The next heading level (minimum level + 1) is treated as the subtitle and inserted into the subtitle placeholder ( &lt;code&gt;SUBTITLE&lt;/code&gt; ) in order.&lt;/li&gt; 
 &lt;li&gt;When H1 is used as the title, H2 (&lt;code&gt;##&lt;/code&gt;) becomes the subtitle&lt;/li&gt; 
 &lt;li&gt;All other items are inserted into the body placeholder ( &lt;code&gt;BODY&lt;/code&gt; ) in order. 
  &lt;ul&gt; 
   &lt;li&gt;The remaining contents are divided into one or more bodies by headings corresponding to the title or subtitle in the slide.&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;For example:&lt;br&gt; - &lt;strong&gt;Standard case&lt;/strong&gt;: If a slide contains &lt;code&gt;#&lt;/code&gt; (H1), then &lt;code&gt;#&lt;/code&gt; becomes the title and &lt;code&gt;##&lt;/code&gt; becomes the subtitle&lt;br&gt; - &lt;strong&gt;Alternative case&lt;/strong&gt;: If a slide only contains &lt;code&gt;##&lt;/code&gt; (H2) or deeper, then &lt;code&gt;##&lt;/code&gt; becomes the title and &lt;code&gt;###&lt;/code&gt; becomes the subtitle&lt;/p&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;[!NOTE]&lt;br&gt; They are inserted in the order they appear in the markdown document, &lt;strong&gt;from the placeholder at the top of the slide&lt;/strong&gt; (or from the placeholder on the left if placeholders are at the same height).&lt;/p&gt; 
 &lt;p&gt;Also, if there are not enough placeholders, the remaining contents will not be rendered.&lt;/p&gt; 
&lt;/blockquote&gt; 
&lt;h3&gt;Example&lt;/h3&gt; 
&lt;p&gt;&lt;strong&gt;Input markdown document:&lt;/strong&gt;&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-markdown&quot;&gt;# CAP theorem

## In Database theory

## Consistency

Every read receives the most recent write or an error.

## Availability

Every request received by a non-failing node in the system must result in a response.

## Partition tolerance

The system continues to operate despite an arbitrary number of messages being dropped (or delayed) by the network between nodes.
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;&lt;strong&gt;Layout and placeholders:&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;&lt;img src=&quot;https://tedneward.github.io/Research/tools/img/layout.png&quot; alt=&quot;img&quot;&gt;&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Result of applying:&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;&lt;img src=&quot;https://tedneward.github.io/Research/tools/img/result.png&quot; alt=&quot;img&quot;&gt;&lt;/p&gt; 
&lt;h2&gt;Configuration File&lt;/h2&gt; 
&lt;p&gt;&lt;code&gt;deck&lt;/code&gt; supports global configuration files that provide default settings for all presentations. Configuration files are loaded in the following order:&lt;/p&gt; 
&lt;ol&gt; 
 &lt;li&gt;&lt;code&gt;${XDG_CONFIG_HOME:-~/.config}/deck/config-{profile}.yml&lt;/code&gt; (when using &lt;code&gt;--profile&lt;/code&gt; option)&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;${XDG_CONFIG_HOME:-~/.config}/deck/config.yml&lt;/code&gt; (default config file)&lt;/li&gt; 
&lt;/ol&gt; 
&lt;p&gt;The configuration file uses YAML format and supports the same fields as frontmatter. Settings in frontmatter take precedence over configuration file settings, which in turn take precedence over built-in defaults.&lt;/p&gt; 
&lt;h3&gt;Configuration file example&lt;/h3&gt; 
&lt;pre&gt;&lt;code class=&quot;language-yaml&quot;&gt;# Global configuration for deck
basePresentationID: &quot;1wIik04tlp1U4SBHTLrSu20dPFlAGTbRHxnqdRFF9nPo&quot;
breaks: true
codeBlockToImageCommand: &quot;go run testdata/txt2img/main.go&quot;
folderID: &quot;1aBcDeFgHiJkLmNoPqRsTuVwXyZ&quot;

defaults:
  # First page should always use title layout
  - if: page == 1
    layout: title
  # Pages with only one title and one H2 heading use section layout
  - if: titles.size() == 1 &amp;amp;&amp;amp; headings[2].size() == 1
    layout: section-purple
  # Skip pages with TODO in speaker notes
  - if: speakerNote.contains(&quot;TODO&quot;)
    skip: true
  # Default layout for all other pages
  - if: true
    layout: title-and-body
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;Available configuration fields&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;strong&gt;&lt;code&gt;basePresentationID&lt;/code&gt;&lt;/strong&gt; (string): Base presentation ID to use as a template when creating new presentations&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;&lt;code&gt;breaks&lt;/code&gt;&lt;/strong&gt; (boolean): Global line break rendering behavior&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;&lt;code&gt;codeBlockToImageCommand&lt;/code&gt;&lt;/strong&gt; (string): Global command to convert code blocks to images&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;&lt;code&gt;folderID&lt;/code&gt;&lt;/strong&gt; (string): Default folder ID to create presentations and upload temporary images to&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;&lt;code&gt;defaults&lt;/code&gt;&lt;/strong&gt; (array): A series of conditions and actions written in CEL expressions for default page configs&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Configuration precedence&lt;/h3&gt; 
&lt;p&gt;Settings are applied in the following order (highest to lowest priority):&lt;/p&gt; 
&lt;ol&gt; 
 &lt;li&gt;&lt;strong&gt;Command-line options&lt;/strong&gt; - Takes highest precedence when available&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Frontmatter settings&lt;/strong&gt; - Takes precedence over config file&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Configuration file settings&lt;/strong&gt; - Applied when neither command-line nor frontmatter specify the setting&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Built-in defaults&lt;/strong&gt; - Used when no other source specifies a setting&lt;/li&gt; 
&lt;/ol&gt; 
&lt;p&gt;This allows you to set organization-wide or project-wide defaults while still maintaining the flexibility to override them on a per-file basis using frontmatter or command-line options.&lt;/p&gt; 
&lt;h2&gt;Advanced features&lt;/h2&gt; 
&lt;h3&gt;Style for syntax&lt;/h3&gt; 
&lt;p&gt;Create a layout named &lt;code&gt;style&lt;/code&gt; and add a &lt;code&gt;Text box&lt;/code&gt; to enter specific words. The styles (&lt;code&gt;bold&lt;/code&gt;, &lt;code&gt;italic&lt;/code&gt;, &lt;code&gt;underline&lt;/code&gt;, &lt;code&gt;backgroundColor&lt;/code&gt;, &lt;code&gt;foregroundColor&lt;/code&gt;, &lt;code&gt;fontFamily&lt;/code&gt;) will be applied as the style for each Markdown syntax.&lt;/p&gt; 
&lt;p&gt;&lt;img src=&quot;https://tedneward.github.io/Research/tools/img/style.png&quot; alt=&quot;img&quot;&gt;&lt;/p&gt; 
&lt;table&gt; 
 &lt;thead&gt; 
  &lt;tr&gt;
   &lt;th&gt; Word &lt;/th&gt;
   &lt;th&gt; &lt;/th&gt;
  &lt;/tr&gt; 
 &lt;/thead&gt; 
 &lt;tbody&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;bold&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; style for &lt;strong&gt;bold&lt;/strong&gt;. &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;italic&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; style for &lt;em&gt;italic&lt;/em&gt;. &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;link&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; style for &lt;a href=&quot;#&quot;&gt;link&lt;/a&gt;. &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;code&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; style for &lt;code&gt;code&lt;/code&gt;. &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;del&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; style for ~~strikethrough~~ (also applies to &lt;code&gt;&amp;lt;del&amp;gt;&lt;/code&gt; tag). &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;blockquote&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; style for block quote. &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; HTML element names &lt;/td&gt;
   &lt;td&gt; style for content of inline HTML elements ( e.g. &lt;code&gt;&amp;lt;cite&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;q&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;s&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;ins&amp;gt;&lt;/code&gt;, etc. ) &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; (other word) &lt;/td&gt;
   &lt;td&gt; style for content of inline HTML elements with matching class name ( e.g. &lt;code&gt;&amp;lt;span class=&quot;notice&quot;&amp;gt;THIS IS NOTICE&amp;lt;/span&amp;gt;&lt;/code&gt; ) &lt;/td&gt;
  &lt;/tr&gt; 
 &lt;/tbody&gt; 
&lt;/table&gt; 
&lt;h3&gt;Code blocks to images&lt;/h3&gt; 
&lt;p&gt;You can convert &lt;a href=&quot;testdata/codeblock.md&quot;&gt;Markdown code blocks&lt;/a&gt; to images by specifying a command that outputs image data (PNG, JPEG, GIF) to standard output or to a file by using the &lt;code&gt;{{output}}&lt;/code&gt; placeholder for the output file path.&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-console&quot;&gt;$ deck apply --code-block-to-image-command &quot;some-command&quot; -i xxxxxXXXXxxxxxXXXXxxxxxxxxxx deck.md
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Alternatively, you can configure it in &lt;code&gt;config.yml&lt;/code&gt; or frontmatter:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-yaml&quot;&gt;codeBlockToImageCommand: &quot;some-command&quot;
&lt;/code&gt;&lt;/pre&gt; 
&lt;h4&gt;How to receive values&lt;/h4&gt; 
&lt;p&gt;From code blocks like the following, you can obtain the optional language identifier &lt;code&gt;go&lt;/code&gt; and the content within the code block.&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;```go
package main

import &quot;fmt&quot;

func main() {
	fmt.Println(&quot;Hello, 世界&quot;)
}
```
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;There are three ways to receive code block information within the command:&lt;/p&gt; 
&lt;ol&gt; 
 &lt;li&gt;&lt;strong&gt;Receive from standard input&lt;/strong&gt;&lt;/li&gt; 
&lt;/ol&gt; 
&lt;ul&gt; 
 &lt;li&gt;The content of the code block is passed as standard input&lt;/li&gt; 
 &lt;li&gt;The optional language identifier cannot be obtained, so use it in combination with other methods&lt;/li&gt; 
&lt;/ul&gt; 
&lt;ol&gt; 
 &lt;li&gt;&lt;strong&gt;Receive as environment variables&lt;/strong&gt;&lt;/li&gt; 
&lt;/ol&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;code&gt;CODEBLOCK_LANG&lt;/code&gt;: Optional language identifier of the code block (e.g., &lt;code&gt;go&lt;/code&gt;, &lt;code&gt;python&lt;/code&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;CODEBLOCK_CONTENT&lt;/code&gt;: Content of the code block&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;CODEBLOCK_OUTPUT&lt;/code&gt;: Path to a temporary output file&lt;/li&gt; 
&lt;/ul&gt; 
&lt;ol&gt; 
 &lt;li&gt;&lt;strong&gt;Receive with CEL template syntax&lt;/strong&gt;&lt;/li&gt; 
&lt;/ol&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;code&gt;{{lang}}&lt;/code&gt;: Optional language identifier of the code block&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;{{content}}&lt;/code&gt;: Content of the code block&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;{{output}}&lt;/code&gt;: Path to a temporary output file&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;{{env.XXX}}&lt;/code&gt;: Value of environment variable XXX&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;The template expansion uses CEL (Common Expression Language) for evaluating expressions within &lt;code&gt;{{ }}&lt;/code&gt; delimiters. This supports:&lt;br&gt; - Ternary operators: &lt;code&gt;{{ lang == &quot;&quot; ? &quot;md&quot; : lang }}&lt;/code&gt;&lt;br&gt; - String concatenation: &lt;code&gt;{{ &quot;prefix_&quot; + lang }}&lt;/code&gt;&lt;br&gt; - Boolean logic: &lt;code&gt;{{ lang != &quot;&quot; &amp;amp;&amp;amp; content.contains(&quot;main&quot;) }}&lt;/code&gt;&lt;br&gt; - Arithmetic operations: &lt;code&gt;{{ count + 1 }}&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;These methods can be used in combination, and you can choose the appropriate method according to the command requirements.&lt;/p&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;[!NOTE]&lt;br&gt; When &lt;code&gt;{{output}}&lt;/code&gt; is not specified, &lt;code&gt;deck&lt;/code&gt; reads the image data from the command&apos;s stdout. When &lt;code&gt;{{output}}&lt;/code&gt; is specified, the command should write the image to that file path, and &lt;code&gt;deck&lt;/code&gt; will read the image data from that file.&lt;/p&gt; 
&lt;/blockquote&gt; 
&lt;h4&gt;Examples&lt;/h4&gt; 
&lt;pre&gt;&lt;code class=&quot;language-console&quot;&gt;# Convert Mermaid diagrams to images
$ deck apply -c &apos;mmdc -i - -o {{output}} --quiet&apos; deck.md
&lt;/code&gt;&lt;/pre&gt; 
&lt;pre&gt;&lt;code class=&quot;language-console&quot;&gt;# Generate code images using the built-in text-to-image tool
$ deck apply -c &apos;go run testdata/txt2img/main.go&apos; deck.md
&lt;/code&gt;&lt;/pre&gt; 
&lt;pre&gt;&lt;code class=&quot;language-console&quot;&gt;# Use different tools depending on the language
$ deck apply -c &apos;if [ {{lang}} = &quot;mermaid&quot; ]; then mmdc -i - -o {{output}} --quiet; else go run testdata/txt2img/main.go; fi&apos; deck.md

# Alternatively, you can use Songmu/laminate to use the appropriate tool for each language.
$ deck apply -c &apos;laminate&apos; deck.md
&lt;/code&gt;&lt;/pre&gt; 
&lt;h2&gt;Page configuration&lt;/h2&gt; 
&lt;p&gt;You can configure individual pages using JSON comments. Available settings:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;strong&gt;&lt;code&gt;&quot;layout&quot;&lt;/code&gt;&lt;/strong&gt;: Specifies which slide layout to use from your presentation template. Different layouts have different placeholder arrangements (title, subtitle, body, etc.)&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;&lt;code&gt;&quot;freeze&quot;&lt;/code&gt;&lt;/strong&gt;: Prevents &lt;code&gt;deck&lt;/code&gt; from modifying the page (useful for slides with completed designs)&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;&lt;code&gt;&quot;ignore&quot;&lt;/code&gt;&lt;/strong&gt;: Excludes the page from slide generation (for drafts, notes, or unused content)&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;&lt;code&gt;&quot;skip&quot;&lt;/code&gt;&lt;/strong&gt;: Creates the slide but skips it during presentation playback (automatically advances to next slide)&lt;/li&gt; 
&lt;/ul&gt; 
&lt;pre&gt;&lt;code class=&quot;language-markdown&quot;&gt;&amp;lt;!-- {&quot;layout&quot;: &quot;title-and-body&quot;} --&amp;gt;
# Your slide content

---

&amp;lt;!-- {&quot;freeze&quot;: true} --&amp;gt;
# This slide won&apos;t be modified

---

&amp;lt;!-- {&quot;ignore&quot;: true} --&amp;gt;
# This content won&apos;t appear in slides

---

&amp;lt;!-- {&quot;skip&quot;: true} --&amp;gt;
# This slide will be skipped during presentation
&lt;/code&gt;&lt;/pre&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;[!TIP]&lt;br&gt; Use &lt;code&gt;deck ls-layouts&lt;/code&gt; to see all available layout names for your presentation:&lt;/p&gt; 
 &lt;pre&gt;&lt;code class=&quot;language-console&quot;&gt;$ deck ls-layouts deck.md
title
section
section-dark
title-and-body
title-and-body-half
title-and-body-2col
title-and-body-3col
&lt;/code&gt;&lt;/pre&gt; 
&lt;/blockquote&gt; 
&lt;p&gt;&lt;img src=&quot;https://tedneward.github.io/Research/tools/img/layout_name.png&quot; alt=&quot;img&quot;&gt;&lt;/p&gt; 
&lt;h2&gt;Default page configs with CEL expressions&lt;/h2&gt; 
&lt;p&gt;The &lt;code&gt;defaults&lt;/code&gt; field in Frontmatter or configuration file allows you to define default page configs using CEL (Common Expression Language) expressions. This feature automatically sets layouts and controls page behavior based on their structure and content, eliminating the need for manual configuration on each page.&lt;/p&gt; 
&lt;h3&gt;Available actions&lt;/h3&gt; 
&lt;p&gt;The following actions can be applied to pages through the &lt;code&gt;defaults&lt;/code&gt; configuration:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;strong&gt;&lt;code&gt;layout&lt;/code&gt;&lt;/strong&gt;: Set layout automatically&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;&lt;code&gt;freeze&lt;/code&gt;&lt;/strong&gt;: Freeze page from modifications&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;&lt;code&gt;ignore&lt;/code&gt;&lt;/strong&gt;: Exclude page from generation&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;&lt;code&gt;skip&lt;/code&gt;&lt;/strong&gt;: Skip page during presentation&lt;/li&gt; 
&lt;/ul&gt; 
&lt;pre&gt;&lt;code class=&quot;language-yaml&quot;&gt;---
defaults:
  # First page should always use title layout
  - if: page == 1
    layout: title
  # Pages with only one title and one H2 heading use section layout
  - if: titles.size() == 1 &amp;amp;&amp;amp; headings[2].size() == 1
    layout: section-purple
  # Skip pages with TODO in speaker notes
  - if: speakerNote.contains(&quot;TODO&quot;)
    skip: true
  # Default layout for all other pages
  - if: true
    layout: title-and-body
---
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;Available CEL variables&lt;/h3&gt; 
&lt;table&gt; 
 &lt;thead&gt; 
  &lt;tr&gt;
   &lt;th&gt; Variable &lt;/th&gt;
   &lt;th&gt; Type &lt;/th&gt;
   &lt;th&gt; Description &lt;/th&gt;
  &lt;/tr&gt; 
 &lt;/thead&gt; 
 &lt;tbody&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;page&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; &lt;code&gt;int&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Current page number (1-based) &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;pageTotal&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; &lt;code&gt;int&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Total number of pages &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;titles&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; &lt;code&gt;[]string&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; List of titles in the page &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;subtitles&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; &lt;code&gt;[]string&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; List of subtitles in the page &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;bodies&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; &lt;code&gt;[]string&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; List of body texts in the page &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;blockQuotes&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; &lt;code&gt;[]string&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; List of block quotes in the page &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;codeBlocks&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; &lt;code&gt;[]CodeBlock&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; List of code blocks in the page &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;images&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; &lt;code&gt;[]Image&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; List of images in the page &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;comments&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; &lt;code&gt;[]string&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; List of comments in the page &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;headings&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; &lt;code&gt;map[int][]string&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Headings grouped by level &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;speakerNote&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; &lt;code&gt;string&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; Speaker note &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;code&gt;topHeadingLevel&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; &lt;code&gt;int&lt;/code&gt; &lt;/td&gt;
   &lt;td&gt; The highest heading level in the content &lt;/td&gt;
  &lt;/tr&gt; 
 &lt;/tbody&gt; 
&lt;/table&gt; 
&lt;h3&gt;CEL condition examples&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;code&gt;page == 1&lt;/code&gt; - First page only&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;titles.size() == 0&lt;/code&gt; - Pages without titles&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;codeBlocks.size() &amp;gt; 0&lt;/code&gt; - Pages containing code blocks&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;headings[3].size() &amp;gt;= 2&lt;/code&gt; - Pages with 2 or more H3 headings&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;bodies[0].contains(&quot;TODO&quot;)&lt;/code&gt; - Pages with TODO in first body text&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;page &amp;gt; pageTotal - 3&lt;/code&gt; - Last 3 pages&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;images.size() &amp;gt;= 2&lt;/code&gt; - Pages with 2 or more images&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Important notes&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;strong&gt;Evaluation order&lt;/strong&gt;: Conditions are evaluated in order, and the first matching condition&apos;s action is applied&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Priority&lt;/strong&gt;: Default actions only apply to pages without explicit page configuration (via JSON comments like &lt;code&gt;&amp;lt;!-- {&quot;layout&quot;: &quot;title&quot;} --&amp;gt;&lt;/code&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Performance&lt;/strong&gt;: Using &lt;code&gt;ignore&lt;/code&gt; for unnecessary content improves processing speed&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Workflow&lt;/strong&gt;: This feature enables automatic page management based on content patterns, reducing manual configuration overhead&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Profile support&lt;/h2&gt; 
&lt;p&gt;&lt;code&gt;deck&lt;/code&gt; supports multiple profiles through the &lt;code&gt;--profile&lt;/code&gt; option. This feature allows you to manage separate profiles (authentication Google accounts or environments).&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-console&quot;&gt;$ deck apply deck.md --profile work
$ deck ls --profile personal
$ deck new presentation.md --profile project-a
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;When using profiles, authentication files are managed as follows:&lt;br&gt; - &lt;strong&gt;Credentials file&lt;/strong&gt;: &lt;code&gt;credentials-{profile}.json&lt;/code&gt; - Create this file manually to use profile-specific credentials. If this file exists, it will be automatically used for the specified profile.&lt;br&gt; - &lt;strong&gt;Token file&lt;/strong&gt;: &lt;code&gt;token-{profile}.json&lt;/code&gt; - This file is automatically generated when you use the &lt;code&gt;--profile&lt;/code&gt; option and complete the OAuth authentication process.&lt;/p&gt; 
&lt;h2&gt;FAQ&lt;/h2&gt; 
&lt;h3&gt;A setting permission error occurs during image upload, as shown below&lt;/h3&gt; 
&lt;pre&gt;&lt;code&gt;Error: failed to apply page: failed to upload image: failed to set permission for image: googleapi: Error 403: The user does not have sufficient permissions for this file., insufficientFilePermissions
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Please verify that you can grant public read access to files in Google Drive. Organizational policies may prevent this. If restricted, create a folder with appropriate permissions and specify its ID using the &lt;code&gt;--folder-id&lt;/code&gt; flag during &lt;code&gt;deck apply&lt;/code&gt;.&lt;/p&gt; 
&lt;p&gt;To insert images into slides, &lt;code&gt;deck&lt;/code&gt; temporarily uploads image files to Google Drive, obtains a publicly accessible URL from there, and passes it to the API. Therefore, you must be able to grant reader permissions to anyone for image files on Google Drive.&lt;/p&gt; 
&lt;h2&gt;Integration&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/zonuexe/deck-slides.el&quot;&gt;zonuexe/deck-slides.el&lt;/a&gt; ... Emacs integration for creating presentations using Markdown and Google Slides&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/Songmu/laminate&quot;&gt;Songmu/laminate&lt;/a&gt; ... Selects image generation commands based on code block language. Useful for converting code blocks to images&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;With AI agent&lt;/h2&gt; 
&lt;p&gt;By collaborating with AI agents to create Markdown-formatted slides, you may be able to create effective presentations.&lt;/p&gt; 
&lt;details&gt; &lt;summary&gt;It is a good idea to provide the following rules for creating presentations with `deck` in the prompt. (Click to expand)&lt;/summary&gt; 
 &lt;pre&gt;&lt;code&gt;Create a presentation in Markdown according to the following rules.

# Rules for describing presentations using Markdown

Unless otherwise specified, please follow the rules below.

## Basic Structure
- Use a line containing only three or more consecutive hyphens (`---`, `----`, etc.) from the beginning to the end of the line to indicate page breaks between slides.
- Other horizontal rule elements (like `- - -`, `***`, `___`) remain in the content as visual separators and can be used to separate multiple body placeholders.
- Within each slide, the minimum heading level will be treated as the title, and the next level as the subtitle. Higher level headings will be treated as body content. It is recommended to use only one title heading per slide.

## YAML Frontmatter
You can include YAML frontmatter at the beginning of the file:
```yaml
---
title: &quot;Presentation Title&quot;
presentationID: &quot;presentation_id&quot;
breaks: true
author: &quot;Author Name&quot;
date: &quot;2024-01-01&quot;
tags: [&quot;tag1&quot;, &quot;tag2&quot;]
custom:
  nested: &quot;value&quot;
  number: 42
---
```

## Supported Markdown Syntax
The following syntax can be used in the slide content:

### Text Formatting
- **Bold** (`**bold**`)
- *Italic* (`*italic*` or `__italic__`)
- `Inline code` (&amp;lt;code&amp;gt;\`code\`&amp;lt;/code&amp;gt;)
- Combined formatting (e.g., ***bold and italic***)

### Lists
- Bullet lists (`-` or `*`)
- Numbered lists (`1.` or `1)`)
- Nested lists (with proper indentation)
- Alphabetical lists (a. b. c.)

### Links and Images
- Links (`[Link text](https://example.com)`)
- Angle bracket autolinks (`&amp;lt;https://example.com&amp;gt;`)
- Images (`![alt text](image.jpg)`)
- Supports PNG, JPEG, GIF formats
- Supports both local files and URLs (HTTP/HTTPS)

### Block Elements
- Block quotes (`&amp;gt; quoted text`)
- Nested block quotes
- Code blocks with language specification:
  ```language
  code content
  ```
- Mermaid diagrams (in code blocks with `mermaid` language)

### Tables
- GitHub Flavored Markdown (GFM) tables
- Supports table headers with automatic bold formatting
- Cell content can include inline formatting (bold, italic, code)
- Example:
  ```markdown
  | Header 1 | Header 2 | Header 3 |
  |----------|----------|----------|
  | Cell 1   | **Bold** | `code`   |
  | Cell 2   | *Italic* | Normal   |
  ```
- Header rows are automatically styled with bold text and gray background
- Tables created by users in Google Slides are preserved

### HTML Elements
You can use the following HTML inline elements:
- `&amp;lt;strong&amp;gt;`, `&amp;lt;em&amp;gt;`, `&amp;lt;b&amp;gt;`, `&amp;lt;i&amp;gt;`, `&amp;lt;mark&amp;gt;`, `&amp;lt;small&amp;gt;`
- `&amp;lt;code&amp;gt;`, `&amp;lt;kbd&amp;gt;`, `&amp;lt;cite&amp;gt;`, `&amp;lt;q&amp;gt;`, `&amp;lt;ruby&amp;gt;`, `&amp;lt;rt&amp;gt;`
- `&amp;lt;span&amp;gt;`, `&amp;lt;u&amp;gt;`, `&amp;lt;s&amp;gt;`, `&amp;lt;sub&amp;gt;`, `&amp;lt;sup&amp;gt;`, `&amp;lt;var&amp;gt;`
- `&amp;lt;samp&amp;gt;`, `&amp;lt;data&amp;gt;`, `&amp;lt;dfn&amp;gt;`, `&amp;lt;time&amp;gt;`, `&amp;lt;abbr&amp;gt;`, `&amp;lt;rp&amp;gt;`
- `&amp;lt;br&amp;gt;` (for line breaks)
- Use `class` attribute for custom styling

### Line Break Handling
- Default (`breaks: false`): Soft line breaks become spaces
- With `breaks: true`: Soft line breaks become actual line breaks
- Use `&amp;lt;br&amp;gt;` tags for explicit line breaks

## Page Configuration
Use HTML comments for page settings and speaker notes:
- Page settings: `&amp;lt;!-- {&quot;layout&quot;: &quot;title-and-body&quot;} --&amp;gt;`
- Available settings: `&quot;freeze&quot;: true`, `&quot;ignore&quot;: true`, `&quot;skip&quot;: true`
- Speaker notes: `&amp;lt;!-- This is a speaker note --&amp;gt;` (use separate comments for notes)

## Important Notes
- If a comment (`&amp;lt;!-- --&amp;gt;`) contains JSON, it&apos;s a page setting - do not overwrite it
- If `&quot;freeze&quot;: true` is present in page settings, do not modify that page content at all
- Write speaker notes in separate comments, not in JSON configuration comments
- Code blocks can be converted to images using the `--code-block-to-image-command` option
&lt;/code&gt;&lt;/pre&gt; 
&lt;/details&gt; 
&lt;h2&gt;Alternatives&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/googleworkspace/md2googleslides&quot;&gt;googleworkspace/md2googleslides&lt;/a&gt;: Generates Google Slides from markdown&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>DevKnife</title>
      <link>https://tedneward.github.io/Research/tools/devknife/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/devknife/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://devknife.app/&quot;&gt;Website&lt;/a&gt; | Commercial&lt;/p&gt; 
&lt;p&gt;JSON Formatter &amp;amp; Editor | JSON/YAML/TOML/XML/CSV Converter | Regex Tester | Text Compare | JWT Decoder | Port Scanner | Time Inspector | Index Now | Markdown Editor | Encoder &amp;amp; Decoder | Domain &amp;amp; IP WHOIS | Network Speed Test | Color Picker | Data Generator | IP Location | Hasher | Text Inspector | SVG Editor | Password Generator | Tailwind Colors&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>dnSpy</title>
      <link>https://tedneward.github.io/Research/tools/dnspy/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/dnspy/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/dnSpy/dnSpy&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>dotnetReleaser</title>
      <link>https://tedneward.github.io/Research/tools/dotnetreleaser/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/dotnetreleaser/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/xoofx/dotnet-releaser&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>DynamoRIO</title>
      <link>https://tedneward.github.io/Research/tools/dynamorio/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/dynamorio/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://dynamorio.org&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/DynamoRIO/dynamorio&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://github.com/lgeek/dynamorio_pin_escape&quot;&gt;dynamorio_pin_escape&lt;/a&gt;: Escaping DynamoRIO and Pin - or why it&apos;s a worse-than-you-think idea to run untrusted code or to input untrusted data&lt;br&gt; - Cosmin Gorgovan (2014)&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Daytona</title>
      <link>https://tedneward.github.io/Research/tools/daytona/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/daytona/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.daytona.io/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/daytonaio/daytona&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Delinker</title>
      <link>https://tedneward.github.io/Research/tools/delinker/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/delinker/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/jnider/delinker&quot;&gt;Github&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Reverse the Linking Process&lt;br&gt; - Compiler, Architecture, and Tools Conference (CATC) 2018&lt;br&gt; - Joel Nider&lt;br&gt; - &lt;a href=&quot;https://software.intel.com/en-us/download/reverse-the-linking-process&quot;&gt;https://software.intel.com/en-us/download/reverse-the-linking-process&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Diagrams</title>
      <link>https://tedneward.github.io/Research/tools/diagrams/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/diagrams/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://diagrams.mingrammer.com/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/mingrammer/diagrams&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>docmd</title>
      <link>https://tedneward.github.io/Research/tools/docmd/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/docmd/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://docmd.mgks.dev/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/mgks/docmd&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Draw.io</title>
      <link>https://tedneward.github.io/Research/tools/drawio/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/drawio/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://drawio-app.com/&quot;&gt;Website&lt;/a&gt;&lt;/p&gt; 
&lt;hr&gt; 
&lt;p&gt;&lt;a href=&quot;https://drawio-app.com/github-support/&quot;&gt;Integrating Draw.io into Github repository&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Easy2Boot</title>
      <link>https://tedneward.github.io/Research/tools/easy2boot/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/easy2boot/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://easy2boot.xyz/&quot;&gt;Website&lt;/a&gt;&lt;/p&gt; 
&lt;h2&gt;Reading&lt;/h2&gt; 
&lt;h3&gt;Articles&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.xda-developers.com/multi-boot-usb-drive-for-almost-any-os-new-or-old/&quot;&gt;I made a multi-boot USB drive for almost any OS, new or old&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Crap4j</title>
      <link>https://tedneward.github.io/Research/tools/crap4j/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/crap4j/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;http://www.crap4j.org/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://code.google.com/archive/p/crap4j/&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Q:&lt;/strong&gt; What Are Change Risk Anti Patterns?&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;A:&lt;/strong&gt; They are code patterns that are associated with an increased risk of breaking an existing piece of code when it’s being modified.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Q:&lt;/strong&gt; What are some examples of Change Risk Anti-Patterns?&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;A:&lt;/strong&gt; A good example of a Java change risk anti-pattern, and one used in CRAP, is a method with high cyclomatic complexity (i.e. a lot of branches). Several studies show a definite correlation between excessive code complexity and an increased probability of introducing defects during maintenance. Another change risk anti-pattern used in CRAP is lack of automated tests. Modifying existing code without having some tests you can run to ensure that the changes have not introduced regressions is, not surprisingly, quite risky – especially if the person modifying the code is not the original developer.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Q:&lt;/strong&gt; How is CRAP calculated?&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;A:&lt;/strong&gt; The current version of CRAP combines the two change risk anti-patterns we just discussed: excessive method complexity and lack of automated tests for those methods.&lt;/p&gt; 
&lt;p&gt;Given a Java method m, CRAP for m is calculated as follows:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;CRAP(m) = comp(m)^2 * (1 – cov(m)/100)^3 + comp(m)
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Where comp(m) is the cyclomatic complexity of method m, and cov(m) is the test code coverage provided by automated tests (e.g. JUnit tests, not manual QA). Cyclomatic complexity is a well-known and widely used metric and it’s calculated as one plus the number of unique decisions in the method. For code coverage we use basis path coverage. Low CRAP numbers indicate code with relatively low change and maintenance risk – because it’s not too complex and/or it’s well-protected by automated and repeatable tests. High CRAP numbers indicate code that’s risky to change because of a hazardous combination of high complexity and low, or no, automated test coverage.&lt;/p&gt; 
&lt;p&gt;Generally speaking, you can lower your CRAP score either by adding automated tests or by refactoring to reduce complexity. Preferably both; and it’s a good idea to write the tests firsts so you can refactor more safely.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Q:&lt;/strong&gt; You said “current version of CRAP”, does that mean that CRAP might change?&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;A:&lt;/strong&gt; Yes, we believe that the current version of CRAP is a very good start and it has proven useful and rather accurate in detecting risky code. But we also believe that metrics should be open to change and evolve as we gain experience using them and to keep up with changes in programming practices.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Q:&lt;/strong&gt; I understand how CRAP is calculated for a given method, but how do I interpret the CRAP number I get?&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;A:&lt;/strong&gt; Bob Evans and I have looked at a lot of examples (using our code and many open source projects) and listened to a LOT of opinions. After much debate, we decided to initially use a CRAP score of 30 as the threshold for crappiness. Below is a table that shows the amount of test coverage required to stay below the CRAP threshold based on the complexity of a method:&lt;/p&gt; 
&lt;p&gt;Complexity vs Coverage&lt;br&gt; Method&apos;s Cyclomatic Complexity | % of coverage required to be below CRAPpy threshold&lt;br&gt; ------------------------------ | ---------------------------------------------------&lt;br&gt; 0–5 | 0%&lt;br&gt; 6-10 | 42%&lt;br&gt; 11-15 | 57%&lt;br&gt; 16-20 | 71%&lt;br&gt; 21-25 | 80%&lt;br&gt; 26-30 | 100%&lt;br&gt; 31+ | Time to refactor&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Q:&lt;/strong&gt; What Are Change Risk Anti Patterns?&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;A:&lt;/strong&gt; They are code patterns that are associated with an increased risk of breaking an existing piece of code when it’s being modified.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Q:&lt;/strong&gt; What are some examples of Change Risk Anti-Patterns?&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;A:&lt;/strong&gt; A good example of a Java change risk anti-pattern, and one used in CRAP, is a method with high cyclomatic complexity (i.e. a lot of branches). Several studies show a definite correlation between excessive code complexity and an increased probability of introducing defects during maintenance. Another change risk anti-pattern used in CRAP is lack of automated tests. Modifying existing code without having some tests you can run to ensure that the changes have not introduced regressions is, not surprisingly, quite risky – especially if the person modifying the code is not the original developer.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Q:&lt;/strong&gt; How is CRAP calculated?&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;A:&lt;/strong&gt; The current version of CRAP combines the two change risk anti-patterns we just discussed: excessive method complexity and lack of automated tests for those methods.&lt;/p&gt; 
&lt;p&gt;Given a Java method m, CRAP for m is calculated as follows:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;CRAP(m) = comp(m)^2 * (1 – cov(m)/100)^3 + comp(m)
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Where comp(m) is the cyclomatic complexity of method m, and cov(m) is the test code coverage provided by automated tests (e.g. JUnit tests, not manual QA). Cyclomatic complexity is a well-known and widely used metric and it’s calculated as one plus the number of unique decisions in the method. For code coverage we use basis path coverage. Low CRAP numbers indicate code with relatively low change and maintenance risk – because it’s not too complex and/or it’s well-protected by automated and repeatable tests. High CRAP numbers indicate code that’s risky to change because of a hazardous combination of high complexity and low, or no, automated test coverage.&lt;/p&gt; 
&lt;p&gt;Generally speaking, you can lower your CRAP score either by adding automated tests or by refactoring to reduce complexity. Preferably both; and it’s a good idea to write the tests firsts so you can refactor more safely.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Q:&lt;/strong&gt; You said “current version of CRAP”, does that mean that CRAP might change?&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;A:&lt;/strong&gt; Yes, we believe that the current version of CRAP is a very good start and it has proven useful and rather accurate in detecting risky code. But we also believe that metrics should be open to change and evolve as we gain experience using them and to keep up with changes in programming practices.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Q:&lt;/strong&gt; I understand how CRAP is calculated for a given method, but how do I interpret the CRAP number I get?&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;A:&lt;/strong&gt; Bob Evans and I have looked at a lot of examples (using our code and many open source projects) and listened to a LOT of opinions. After much debate, we decided to initially use a CRAP score of 30 as the threshold for crappiness. Below is a table that shows the amount of test coverage required to stay below the CRAP threshold based on the complexity of a method:&lt;/p&gt; 
&lt;p&gt;In other words, you can have high-complexity methods BUT you better have a lot of tests for them. Please note that we don’t recommend having zero tests – even for simple methods of complexity 5 and below. Every piece of code that does something non-trivial should have some tests but – after many discussions – we believe that the CRAP metric will be more useful if it highlights the truly crappy and risky code, not just the code that could be made better by refactoring or adding some tests&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Q:&lt;/strong&gt; OK. Crap4J has labeled one of my methods as crappy, what do I do now?&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;A:&lt;/strong&gt; First of all, take a look at the CRAP details page in the report (the link is at the bottom of the report). The CRAP page shows all methods sorted by CRAP (from highest to lowest) and displays both complexity and test coverage information.&lt;/p&gt; 
&lt;p&gt;If a method is crappy because it has acceptable complexity (e.g. 8) but inadequate tests (e.g. 0%), the obvious thing is to write some tests for it to increase coverage.&lt;/p&gt; 
&lt;p&gt;If the method is well tested by high-complexity, it’s a good idea to refactor. Method extraction is a very safe refactoring and can really improve code legibility if you give the extracted method a name that describes what it does (e.g. validateCardNumber(String num) is a good method extraction name, check(String num) is not.)&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Q:&lt;/strong&gt; What is the CRAPload number?&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;A:&lt;/strong&gt; Crap load represents the &quot;minimum&quot; amount of work that could be done to get below the crap threshold of 30 for a method. The summary Crapload number is for the whole project and is just the sum of crap load for all methods. The idea is that this gives you a floor value for the amount of work to get rid of crap. Usually, the amount of work will be greater.&lt;/p&gt; 
&lt;p&gt;Examining this in more detail, to lower the Crap score, there are two options: reduce cyclomatic complexity in a method, or write tests that cover more of the paths in the method. In the case of the Crapload number, we take the simplest possible restructuring of code, which is to refactor it into methods that are half the size of the previous method, say using the Extract Method refactoring. For example, I have a method of complexity 60. if I refactor by extracting half the method into a new method, then I would have two methods of complexity 30.&lt;/p&gt; 
&lt;p&gt;Obviously, this blind refactoring is a pretty poor way to &quot;fix&quot; a system, and in reality, some other, more appropriate, restructuring of the system would be the action to take. In lieu of being able to determine that programmatically, we can at least compute the minimum amount of work that could possibly be done to remove Crap from the system.&lt;/p&gt; 
&lt;p&gt;Crap load for a method is calculated as follows:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;  public int getCrapLoad(float crapThreshold) {
    int crapLoad = 0;
    if (getCrap() &amp;gt;= crapThreshold) {
      int complexity = getComplexity();
      float coverage = getCoverage();
      crapLoad += complexity * (1.0 - coverage);
      crapLoad += complexity / crapThreshold;
    }
    return crapLoad;
  }
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;So, interpreting that, if the CRAP score for a method is above the threshold, 30, then for every point of uncovered complexity, add 1 for a test to cover that path. Then for every bit of complexity over the threshold, figure out the number of extract methods dividing in half that need to be done to get below the threshold.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>8mb.local</title>
      <link>https://tedneward.github.io/Research/tools/8mblocal/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/8mblocal/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://8mb.campuscal.tech/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/JMS1717/8mb.local&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;8mb.local is a self‑hosted, fire‑and‑forget video compressor. Drop a file, choose a target size (e.g., 8MB, 25MB, 50MB, 100MB), and let GPU-accelerated encoding produce compact outputs with AV1/HEVC/H.264. Supports NVIDIA NVENC, Intel/AMD VAAPI (Linux), and CPU fallback. The stack includes a SvelteKit UI, FastAPI backend, Celery worker, Redis broker, and real‑time progress via Server‑Sent Events (SSE).&lt;/p&gt; 
&lt;h2&gt;Features&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;Multi-vendor GPU support: Auto-detects NVIDIA NVENC, Intel/AMD VAAPI (Linux), or falls back to CPU&lt;/li&gt; 
 &lt;li&gt;Robust encoder validation: Tests actual encoder initialization, not just availability listing&lt;/li&gt; 
 &lt;li&gt;Automatic CPU fallback: Gracefully handles missing drivers, permission issues, or hardware access problems&lt;/li&gt; 
 &lt;li&gt;Drag‑and‑drop UI with helpful presets and advanced options (codec, container, tune, audio bitrate)&lt;/li&gt; 
 &lt;li&gt;Configurable codec visibility: Enable/disable specific codecs in Settings page&lt;/li&gt; 
 &lt;li&gt;Resolution control: Set max width/height while maintaining aspect ratio&lt;/li&gt; 
 &lt;li&gt;Video trimming: Specify start/end times (seconds or HH:MM:SS format)&lt;/li&gt; 
 &lt;li&gt;ffprobe analysis on upload for instant estimates and warnings&lt;/li&gt; 
 &lt;li&gt;Real‑time progress tracking: Multi-signal progress using actual output size, time processed, bitrate, and wall-clock estimates for smooth, accurate updates&lt;/li&gt; 
 &lt;li&gt;Real‑time FFmpeg logs: Streaming logs during compression for instant feedback&lt;/li&gt; 
 &lt;li&gt;Live Queue Management: View all active jobs with real-time progress, cancel individual jobs, or clear entire queue&lt;/li&gt; 
 &lt;li&gt;One‑click Cancel: Stop an in‑flight encode; worker interrupts FFmpeg immediately&lt;/li&gt; 
 &lt;li&gt;Queue Clear: Remove all jobs (cancel running, remove queued/completed) with one click&lt;/li&gt; 
 &lt;li&gt;Automatic file size optimization: If output exceeds target by &amp;gt;2%, automatically re-encodes with adjusted bitrate&lt;/li&gt; 
 &lt;li&gt;Smart retry notifications: Audio alerts and visual notifications when auto-retry occurs&lt;/li&gt; 
 &lt;li&gt;History tracking enabled by default: Recent jobs stored in /app/history.json&lt;/li&gt; 
 &lt;li&gt;Auto‑download enabled by default&lt;/li&gt; 
 &lt;li&gt;Hardware encoders: AV1, HEVC (H.265), H.264 (GPU-accelerated when available)&lt;/li&gt; 
 &lt;li&gt;Software fallback: libx264, libx265, libaom-av1 for CPU-only systems&lt;/li&gt; 
 &lt;li&gt;Output container choice: MP4 or MKV, with compatibility safeguards&lt;/li&gt; 
 &lt;li&gt;Version tracking: UI displays current version (v125+), backend provides /api/version endpoint&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Ansible</title>
      <link>https://tedneward.github.io/Research/tools/ansible/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/ansible/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.redhat.com/en/ansible-collaborative&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/ansible/ansible&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;h2&gt;Reading&lt;/h2&gt; 
&lt;h3&gt;Articles, Blogs, Essays&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.xda-developers.com/automated-my-entire-home-network-with-ansible/&quot;&gt;I&apos;m automating my entire home network with Ansible&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.xda-developers.com/ansible-made-my-entire-homelab-reproducible-with-one-command/&quot;&gt;Ansible made my entire homelab reproducible with one command&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Apache Drill</title>
      <link>https://tedneward.github.io/Research/tools/apache-drill/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/apache-drill/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://drill.apache.org/&quot;&gt;Website&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Autotools</title>
      <link>https://tedneward.github.io/Research/tools/autotools/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/autotools/index.html</guid>
      	<description>
	&lt;p&gt;Website? Github?&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Autoconf / Automake Basics 
  &lt;ul&gt; 
   &lt;li&gt;Mark K. Kim; Linux Users&apos; Group of Davis. March 2, 2004.&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.lugod.org/presentations/autotools/presentation/autotools.pdf&quot;&gt;https://www.lugod.org/presentations/autotools/presentation/autotools.pdf&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Autotools Mythbuster 
  &lt;ul&gt; 
   &lt;li&gt;&quot;Autotools Mythbuster is a no-nonsense guide to Autotools, written with the idea of providing a full, integrated view of the tools in the GNU build chain: autoconf, automake, libtool, pkg-config, and so on.&quot;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://autotools.io/&quot;&gt;https://autotools.io/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Autotools Tutorial 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.lrde.epita.fr/~adl/autotools.html&quot;&gt;https://www.lrde.epita.fr/~adl/autotools.html&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Autotools Tutorial for Beginners 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;http://markuskimius.wikidot.com/programming:tut:autotools&quot;&gt;http://markuskimius.wikidot.com/programming:tut:autotools&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Autotools, 2nd Edition 
  &lt;ul&gt; 
   &lt;li&gt;A Practitioner&apos;s Guide to GNU Autoconf, Automake, and Libtool&lt;/li&gt; 
   &lt;li&gt;2019; John Calcote&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://nostarch.com/autotools2e&quot;&gt;https://nostarch.com/autotools2e&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Chapter 2: A Brief Introduction to the GNU Autotools 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://nostarch.com/download/samples/Autotools2e_Sample_Ch2.pdf&quot;&gt;https://nostarch.com/download/samples/Autotools2e_Sample_Ch2.pdf&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Autotools: A Demystification Tutorial 
  &lt;ul&gt; 
   &lt;li&gt;Embedded Linux Conference 2016; Thomas Petazzoni&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=_zX8LJ9Xjyk&quot;&gt;https://www.youtube.com/watch?v=_zX8LJ9Xjyk&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://events.linuxfoundation.org/sites/events/files/slides/petazzoni-autotools-tutorial.pdf&quot;&gt;http://events.linuxfoundation.org/sites/events/files/slides/petazzoni-autotools-tutorial.pdf&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Autotools: a practitioner&apos;s guide to Autoconf, Automake and Libtool 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;http://freesoftwaremagazine.com/books/autotools_a_guide_to_autoconf_automake_libtool/&quot;&gt;http://freesoftwaremagazine.com/books/autotools_a_guide_to_autoconf_automake_libtool/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Four Languages and Lots of Macros: Analyzing Autotools Build Systems 
  &lt;ul&gt; 
   &lt;li&gt;GPCE 2017&lt;/li&gt; 
   &lt;li&gt;Jafar M. Al-Kofahi, Suresh Kothari, Christian Kästner&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://conf.researchr.org/event/gpce-2017/gpce-2017-gpce-2017-four-languages-and-lots-of-macros-analyzing-autotools-build-systems&quot;&gt;https://conf.researchr.org/event/gpce-2017/gpce-2017-gpce-2017-four-languages-and-lots-of-macros-analyzing-autotools-build-systems&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.cs.cmu.edu/~ckaestne/pdf/gpce17.pdf&quot;&gt;https://www.cs.cmu.edu/~ckaestne/pdf/gpce17.pdf&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;GNU Autoconf: A uniform means of creating makefiles at build time 
  &lt;ul&gt; 
   &lt;li&gt;Ethan McCallum - C/C++ Users Journal, January 2006&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://collaboration.cmc.ec.gc.ca/science/rpn/biblio/ddj/Website/articles/CUJ/2006/0601/0601mccallum/0601mccallum.html&quot;&gt;http://collaboration.cmc.ec.gc.ca/science/rpn/biblio/ddj/Website/articles/CUJ/2006/0601/0601mccallum/0601mccallum.html&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://web.archive.org/http://www.drdobbs.com/gnu-autoconf/184402060&quot;&gt;https://web.archive.org/http://www.drdobbs.com/gnu-autoconf/184402060&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://web.archive.org/http://collaboration.cmc.ec.gc.ca/science/rpn/biblio/ddj/Website/articles/CUJ/2006/0601/0601mccallum/0601mccallum.html&quot;&gt;https://web.archive.org/http://collaboration.cmc.ec.gc.ca/science/rpn/biblio/ddj/Website/articles/CUJ/2006/0601/0601mccallum/0601mccallum.html&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;GNU Autoconf, Automake and Libtool 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.sourceware.org/autobook/&quot;&gt;https://www.sourceware.org/autobook/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Minimal autotools template for C++11/14 projects 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/mpoullet/autotools-cpp-template&quot;&gt;https://github.com/mpoullet/autotools-cpp-template&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Minimal autotools template for C/C++ library projects 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/mpoullet/autotools-lib-template&quot;&gt;https://github.com/mpoullet/autotools-lib-template&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>BDE Verify</title>
      <link>https://tedneward.github.io/Research/tools/bdeverify/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/bdeverify/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/bloomberg/bde_verify&quot;&gt;Source&lt;/a&gt; | &lt;a href=&quot;http://bloomberg.github.io/bde_verify/bde_verify_build/html/&quot;&gt;Website&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>BLint</title>
      <link>https://tedneward.github.io/Research/tools/blint/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/blint/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/owasp-dep-scan/blint&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Several source code analysis tools can examine a code repository and generate an SBOM. But what about a binary executable, where the code repository may not be available and the executable is the only artifact to work with? Enter BLint, which aids in generating an SBOM for a binary executable. Creating BLint as open source and adopting it into the OWASP family means that it will be available to all and will grow and evolve.&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Can be used to detect overlooked security weaknesses and code signing or authenticode issues of compiled binaries in CI/CD pipelines. Third-party or proprietary dependencies in the form of binaries should be analyzed as part of software supply chain security efforts&lt;/li&gt; 
 &lt;li&gt;Does not rely on signatures but instead focuses on capabilities&lt;/li&gt; 
 &lt;li&gt;Does not execute the target, preserving resources and avoiding the need for a live environment&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;Supported binary formats:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Android (apk, aab)&lt;/li&gt; 
 &lt;li&gt;ELF (GNU, musl)&lt;/li&gt; 
 &lt;li&gt;PE (exe, dll)&lt;/li&gt; 
 &lt;li&gt;Mach-O (x64, arm64)&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;The SBOM feature is supported for these types:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Android (apk/aab)&lt;/li&gt; 
 &lt;li&gt;.NET executable binaries&lt;/li&gt; 
 &lt;li&gt;Go binaries&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;They are looking at adding the following capabilities:&lt;/p&gt; 
&lt;ol&gt; 
 &lt;li&gt;Detecting libraries dynamically loaded during runtime&lt;/li&gt; 
 &lt;li&gt;Offering a deep mode that will list symbols within static libraries.&lt;/li&gt; 
 &lt;li&gt;Add additional annotations and refine existing ones.&lt;/li&gt; 
 &lt;li&gt;Add CycloneDx 1.6 support for the SBOM feature.&lt;/li&gt; 
&lt;/ol&gt; 
&lt;p&gt;&lt;a href=&quot;https://www.helpnetsecurity.com/2024/05/14/blint-open-source-check-security-properties-executables/&quot;&gt;&quot;BLint: Open-source tool to check the security properties of your executables&quot;&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Boomerang</title>
      <link>https://tedneward.github.io/Research/tools/boomerang/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/boomerang/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;http://boomerang.sourceforge.net/index.php&quot;&gt;Website&lt;/a&gt;&lt;/p&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;This project is an attempt to develop a real decompiler for machine code programs through the open source community. A decompiler takes as input an executable file, and attempts to create a high level, compilable, possibly even maintainable source file that does the same thing. It is therefore the opposite of a compiler, which takes a source file and makes an executable. However, a general decompiler does not attempt to reverse every action of the decompiler, rather it transforms the input program repeatedly until the result is high level source code. It therefore won&apos;t recreate the original source file; probably nothing like it. It does not matter if the executable file has symbols or not, or was compiled from any particular language. (However, declarative languages like ML are not considered.)&lt;/p&gt; 
&lt;/blockquote&gt; 
&lt;p&gt;No updates since 2012, Sourceforge page lists a number of complaints. Probably dead.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Browser Extensions</title>
      <link>https://tedneward.github.io/Research/tools/browser-extensions/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/browser-extensions/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://ardalis.com/chrome-browser-tabs-to-links/&quot;&gt;Bookmarks to Tabs&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Byte-Me</title>
      <link>https://tedneward.github.io/Research/tools/byte-me/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/byte-me/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://byte-me.dev/&quot;&gt;Website&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>cave_miner</title>
      <link>https://tedneward.github.io/Research/tools/cave-miner/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/cave-miner/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/Antonin-Deniau/cave_miner&quot;&gt;Github&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Cherrybomb</title>
      <link>https://tedneward.github.io/Research/tools/cherry-bomb/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/cherry-bomb/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.blstsecurity.com/cherrybomb&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/blst-security/cherrybomb&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Clover</title>
      <link>https://tedneward.github.io/Research/tools/clover/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/clover/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://bitbucket.org/atlassian/clover/src/master/&quot;&gt;Source&lt;/a&gt; | &lt;a href=&quot;http://confluence.atlassian.com/display/CLOVER/Clover+Documentation+Home&quot;&gt;Docs&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>coala</title>
      <link>https://tedneward.github.io/Research/tools/coala/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/coala/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://coala.io/#/home&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/coala/coala&quot;&gt;GitHub&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;coala provides a unified interface for linting and fixing code with a single configuration file, regardless of the programming languages used. You can use coala from within your favorite editor, integrate it with your CI, get the results as JSON, or customize it to your needs with its flexible configuration syntax.&lt;/p&gt; 
&lt;p&gt;coala has a set of official bears (plugins) for several languages, including popular languages such as C/C++, Python, JavaScript, CSS, Java and many more, in addition to some generic language independent algorithms. To learn more about the different languages supported and the bears themselves, click below.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>codesize</title>
      <link>https://tedneward.github.io/Research/tools/codesize/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/codesize/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/zeux/codesize&quot;&gt;Github&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Cppcheck</title>
      <link>https://tedneward.github.io/Research/tools/cppcheck/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/cppcheck/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;http://cppcheck.sourceforge.net/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/danmar/cppcheck&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Act</title>
      <link>https://tedneward.github.io/Research/tools/act/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/act/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://nektosact.com/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/nektos/act&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;code&gt;brew install act&lt;/code&gt; (macOS) | &lt;code&gt;choco install act-cli&lt;/code&gt; (Windows)&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Ant</title>
      <link>https://tedneward.github.io/Research/tools/ant/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/ant/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;http://ant.apache.org/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;http://ant.apache.org/git.html&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;The main known usage of Ant is the build of Java applications. Ant supplies a number of built-in tasks allowing to compile, assemble, test and run Java applications. Ant can also be used effectively to build non Java applications, for instance C or C++ applications. More generally, Ant can be used to pilot any type of process which can be described in terms of targets and tasks.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>AST-grep</title>
      <link>https://tedneward.github.io/Research/tools/ast-grep/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/ast-grep/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://ast-grep.github.io/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/ast-grep/ast-grep&quot;&gt;GitHub&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Search and Rewrite&lt;/strong&gt;&lt;br&gt; ast-grep is a code tool for structural search and replace. It is like syntax-aware grep/sed! You can write code patterns to locate and modify code, based on AST, in thousands of files, interactively.&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;ast-grep -p &apos;$A &amp;amp;&amp;amp; $A()&apos; -r &apos;$A?.()&apos;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;&lt;strong&gt;Scan as Linter&lt;/strong&gt;&lt;br&gt; ast-grep is a versatile and flexible tool for linting code with AST patterns. You can easily add new customized rules with intuitive syntax and enjoy pretty error reporting out of box.&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;ast-grep scan
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;&lt;strong&gt;Programmatic Usage&lt;/strong&gt;&lt;br&gt; ast-grep also provides node-js binding to access syntax trees programmatically. You can use jQuery like utility methods to traverse syntax tree nodes. Node API also has opt-in type safety.&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;npm install @ast-grep/napi
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;&lt;strong&gt;Polyglot&lt;/strong&gt;&lt;br&gt; Supports C, C#, Go, Java, Javascript, Kotlin, Python, Rust, TypeScript, and many more.&lt;/p&gt; 
&lt;p&gt;Rules are written in YAML files&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Avatar-2</title>
      <link>https://tedneward.github.io/Research/tools/avatar/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/avatar/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/avatartwo/avatar2&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Avatar²: Towards an open source binary firmware analysis framework 
  &lt;ul&gt; 
   &lt;li&gt;34C3 (2017)&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://media.ccc.de/v/34c3-9195-avatar&quot;&gt;https://media.ccc.de/v/34c3-9195-avatar&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=cRxmxapS8N4&quot;&gt;https://www.youtube.com/watch?v=cRxmxapS8N4&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://events.ccc.de/congress/2017/Fahrplan/events/9195.html&quot;&gt;https://events.ccc.de/congress/2017/Fahrplan/events/9195.html&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Avatar²: A Multi-target Orchestration Platform 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;http://s3.eurecom.fr/docs/bar18_muench.pdf&quot;&gt;http://s3.eurecom.fr/docs/bar18_muench.pdf&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Dynamic Binary Firmware Analysis: Challenges &amp;amp; Solutions 
  &lt;ul&gt; 
   &lt;li&gt;2019 PhD Dissertation; Marius Muench&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://www.eurecom.fr/en/publication/5969/detail/dynamic-binary-firmware-analysis-challenges-and-solutions&quot;&gt;http://www.eurecom.fr/en/publication/5969/detail/dynamic-binary-firmware-analysis-challenges-and-solutions&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>BEdit</title>
      <link>https://tedneward.github.io/Research/tools/bedit/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/bedit/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://kipt.itch.io/bedit&quot;&gt;Website&lt;/a&gt; | Closed source&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Bloaty McBloatface</title>
      <link>https://tedneward.github.io/Research/tools/bloaty-mcbloatface/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/bloaty-mcbloatface/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;http://blog.reverberate.org/2016/11/07/introducing-bloaty-mcbloatface.html&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/google/bloaty&quot;&gt;Github&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://github.com/CppCon/CppCon2019/tree/master/Presentations/abusing_compiler_tools&quot;&gt;Talk: “(Ab)using Compiler Tools”&lt;/a&gt;; CppCon 2019; Reka Kovacs (&lt;a href=&quot;https://www.youtube.com/watch?v=5Lke40ywMaU&quot;&gt;YouTube&lt;/a&gt;)&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Boost.Build</title>
      <link>https://tedneward.github.io/Research/tools/boostbuild/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/boostbuild/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;http://www.boost.org/build/&quot;&gt;Website&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://github.com/boostcon/cppnow_presentations_2016/blob/master/03_friday/understanding_boost_build.pdf&quot;&gt;Understanding Boost.Build&lt;/a&gt; (&lt;a href=&quot;https://www.youtube.com/watch?v=8yc7ZvU0yOw&quot;&gt;YouTube&lt;/a&gt;) -- C++Now 2016; Steven Watanabe&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://github.com/boostcon/2011_presentations/raw/master/mon/Boost.Build.pdf&quot;&gt;Complete Overview on Boost.Jam and Boost.Build&lt;/a&gt; (&lt;a href=&quot;https://www.youtube.com/watch?v=OgYwvzUUupM&quot;&gt;YouTube&lt;/a&gt;) -- BoostCon 2011; Boris Schaeling&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Build2</title>
      <link>https://tedneward.github.io/Research/tools/build2/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/build2/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://build2.org/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/build2/&quot;&gt;Github&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=Nni2Qu2WitY&quot;&gt;C++ Dependency Management: from Package Consumption to Project Development&lt;/a&gt; -- CppCon 2018; Boris Kolpackov&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Cake (C# Make)</title>
      <link>https://tedneward.github.io/Research/tools/cake/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/cake/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://cakebuild.net/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/cake-build&quot;&gt;Source&lt;/a&gt; | &lt;a href=&quot;https://cakebuild.net/docs&quot;&gt;Docs&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>CFR</title>
      <link>https://tedneward.github.io/Research/tools/cfr/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/cfr/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.benf.org/other/cfr/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/leibnitz27/cfr&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Clamshell</title>
      <link>https://tedneward.github.io/Research/tools/clamshell/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/clamshell/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/benrutter/clamshell&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>CMake</title>
      <link>https://tedneward.github.io/Research/tools/cmake/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/cmake/index.html</guid>
      	<description>
	&lt;p&gt;CMake is an open-source, cross-platform family of tools designed to build, test and package software. CMake is used to control the software compilation process using simple platform and compiler independent configuration files, and generate native makefiles and workspaces that can be used in the compiler environment of your choice.&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://cmake.org/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://gitlab.kitware.com/cmake/cmake&quot;&gt;Github&lt;/a&gt;&lt;/p&gt; 
&lt;h3&gt;Reading&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://cliutils.gitlab.io/modern-cmake/&quot;&gt;An Introduction to Modern CMake&lt;/a&gt; - Henry Schreiner (HTML)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://cmake.org/cmake/help/latest/guide/tutorial/index.html&quot;&gt;CMake Tutorial&lt;/a&gt; (HTML)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.jetbrains.com/help/clion/quick-cmake-tutorial.html&quot;&gt;Quick CMake tutorial&lt;/a&gt; (HTML)&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;&lt;a href=&quot;https://learnxinyminutes.com/docs/cmake/&quot;&gt;Learn X in Y Minutes&lt;/a&gt;&lt;/h2&gt; 
&lt;p&gt;CMake is a cross-platform, open-source build system. This tool allows you to test, compile, and create packages of your source code.&lt;/p&gt; 
&lt;p&gt;The problem that CMake tries to solve is the problem of Makefiles and Autoconfigure on cross-platforms (different make interpreters have different commands) and the ease-of-use on linking 3rd party libraries.&lt;/p&gt; 
&lt;p&gt;CMake is an extensible, open-source system that manages the build process in an operating system and compiler-agnostic manner. Unlike many cross-platform systems, CMake is designed to be used in conjunction with the native build environment. Simple configuration files placed in each source directory (called CMakeLists.txt files) are used to generate standard build files (e.g., makefiles on Unix and projects/workspaces in Windows MSVC) which are used in the usual way.&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-cmake&quot;&gt;# In CMake, this is a comment

# To run our code, please perform the following commands:
#  - mkdir build &amp;amp;&amp;amp; cd build
#  - cmake ..
#  - make
# 
# With those steps, we will follow the best practice to compile into a subdir
# and the second line will request to CMake to generate a new OS-dependent
# Makefile. Finally, run the native Make command.

#------------------------------------------------------------------------------
# Basic
#------------------------------------------------------------------------------
#
# The CMake file MUST be named as &quot;CMakeLists.txt&quot;.

# Setup the minimum version required of CMake to generate the Makefile
cmake_minimum_required (VERSION 2.8)

# Raises a FATAL_ERROR if version &amp;lt; 2.8
cmake_minimum_required (VERSION 2.8 FATAL_ERROR)

# We define the name of our project, and this changes some directories
# naming convention generated by CMake. We can send the LANG of code
# as the second param
project (learncmake C)

# Set the project source dir (just convention)
set( LEARN_CMAKE_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR} )
set( LEARN_CMAKE_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR} )

# It&apos;s useful to set up the current version of our code in the build system
# using a `semver` style
set (LEARN_CMAKE_VERSION_MAJOR 1)
set (LEARN_CMAKE_VERSION_MINOR 0)
set (LEARN_CMAKE_VERSION_PATCH 0)

# Send the variables (version number) to the source code header
configure_file (
  &quot;${PROJECT_SOURCE_DIR}/TutorialConfig.h.in&quot;
  &quot;${PROJECT_BINARY_DIR}/TutorialConfig.h&quot;
)

# Include Directories
# In GCC, this will invoke the &quot;-I&quot; command
include_directories( include )

# Where are the additional libraries installed? Note: provide includes
# path here, subsequent checks will resolve everything else
set( CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} &quot;${CMAKE_SOURCE_DIR}/CMake/modules/&quot; )

# Conditions
if ( CONDITION )
  # Output!

  # Incidental information
  message(STATUS &quot;My message&quot;)

  # CMake Warning, continue processing
  message(WARNING &quot;My message&quot;)

  # CMake Warning (dev), continue processing
  message(AUTHOR_WARNING &quot;My message&quot;)

  # CMake Error, continue processing, but skip generation
  message(SEND_ERROR &quot;My message&quot;)

  # CMake Error, stop processing and generation
  message(FATAL_ERROR &quot;My message&quot;)
endif()

if( CONDITION )

elseif( CONDITION )

else( CONDITION )

endif( CONDITION )

# Loops
foreach(loop_var arg1 arg2 ...)
  COMMAND1(ARGS ...)
  COMMAND2(ARGS ...)
  ...
endforeach(loop_var)

foreach(loop_var RANGE total)
foreach(loop_var RANGE start stop [step])

foreach(loop_var IN [LISTS [list1 [...]]]
                    [ITEMS [item1 [...]]])

while(condition)
  COMMAND1(ARGS ...)
  COMMAND2(ARGS ...)
  ...
endwhile(condition)


# Logic Operations
if(FALSE AND (FALSE OR TRUE))
  message(&quot;Don&apos;t display!&quot;)
endif()

# Set a regular, cache, or environment variable to a given value.
# If the PARENT_SCOPE option is given, the variable will be set in the scope
# above the current scope.
# `set(&amp;lt;variable&amp;gt; &amp;lt;value&amp;gt;... [PARENT_SCOPE])`

# How to reference variables inside quoted and unquoted arguments?
# A variable reference is replaced by either the variable value or by the 
# empty string if the variable is not set.
${variable_name}

# Lists
# Setup the list of source files
set( LEARN_CMAKE_SOURCES 
  src/main.c
  src/imagem.c
  src/pather.c
)

# Calls the compiler
#
# ${PROJECT_NAME} refers to Learn_CMake 
add_executable( ${PROJECT_NAME} ${LEARN_CMAKE_SOURCES} )

# Link the libraries
target_link_libraries( ${PROJECT_NAME} ${LIBS} m )

# Where are the additional libraries installed? Note: provide includes
# path here, subsequent checks will resolve everything else
set( CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} &quot;${CMAKE_SOURCE_DIR}/CMake/modules/&quot; )

# Compiler Condition (gcc ; g++)
if ( &quot;${CMAKE_C_COMPILER_ID}&quot; STREQUAL &quot;GNU&quot; )
  message( STATUS &quot;Setting the flags for ${CMAKE_C_COMPILER_ID} compiler&quot; )
  add_definitions( --std=c99 )
endif()

# Check for OS
if( UNIX )
    set( LEARN_CMAKE_DEFINITIONS
        &quot;${LEARN_CMAKE_DEFINITIONS} -Wall -Wextra -Werror -Wno-deprecated-declarations -Wno-unused-parameter -Wno-comment&quot; )
endif()
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;More Resources&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://cmake.org/cmake-tutorial/&quot;&gt;CMake tutorial&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://cmake.org/documentation/&quot;&gt;CMake documentation&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://amzn.com/1930934319/&quot;&gt;Mastering CMake&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://cliutils.gitlab.io/modern-cmake/&quot;&gt;An Introduction to Modern CMake&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/friendlyanon/cmake-init&quot;&gt;cmake-init&lt;/a&gt;: an opinionated CMake project initializer that generates CMake projects which are FetchContent ready, separate consumer and developer targets, provide install rules with proper relocatable CMake packages and use modern CMake (3.14+). (Install with &lt;code&gt;[pip3](/languaegs/python) install cmake-init&lt;/code&gt;; generated scripts require &lt;code&gt;[conan](/tools/conan)&lt;/code&gt;)&lt;/li&gt; 
&lt;/ul&gt; 
&lt;hr&gt; 
&lt;h2&gt;Links&lt;/h2&gt; 
&lt;p&gt;&lt;a href=&quot;https://github.com/onqtam/awesome-cmake&quot;&gt;Awesome CMake&lt;/a&gt;: A curated list of awesome CMake scripts, modules, examples and others&lt;/p&gt; 
&lt;h2&gt;Examples&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;C++/CMake modern boilerplate 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/Lectem/cpp-boilerplate&quot;&gt;https://github.com/Lectem/cpp-boilerplate&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;CMake: config mode of find_package command (examples) 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/forexample/package-example&quot;&gt;https://github.com/forexample/package-example&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;CMake cookbook recipes 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/dev-cafe/cmake-cookbook&quot;&gt;https://github.com/dev-cafe/cmake-cookbook&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;CMake Examples 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/ttroy50/cmake-examples&quot;&gt;https://github.com/ttroy50/cmake-examples&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;learning-cmake: a simple CMake tutorial project which contains some different scenarios 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/Akagi201/learning-cmake&quot;&gt;https://github.com/Akagi201/learning-cmake&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Modern CMake Examples 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/pr0g/cmake-examples&quot;&gt;https://github.com/pr0g/cmake-examples&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Polly: Collection of CMake toolchain files and scripts for cross-platform build and CI testing (GCC, Visual Studio, iOS, Android, Clang analyzer, sanitizers etc.) 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/ruslo/polly&quot;&gt;https://github.com/ruslo/polly&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Reading&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;Basic CMake usage 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://codingnest.com/basic-cmake/&quot;&gt;https://codingnest.com/basic-cmake/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;CGold: The Hitchhiker’s Guide to the CMake 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://cgold.readthedocs.io/en/latest/&quot;&gt;https://cgold.readthedocs.io/en/latest/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;CMake 3.16 added support for precompiled headers &amp;amp; unity builds - what you need to know 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;http://onqtam.com/programming/2019-12-20-pch-unity-cmake-3-16/&quot;&gt;http://onqtam.com/programming/2019-12-20-pch-unity-cmake-3-16/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;CMake Coding Style 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://community.kde.org/Policies/CMake_Coding_Style&quot;&gt;https://community.kde.org/Policies/CMake_Coding_Style&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Dev Santa Claus - Nick Sarten 
  &lt;ul&gt; 
   &lt;li&gt;Part 1: Adding Clang Sanitizers to a CMake Build 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://genbattle.bitbucket.io/blog/2018/01/05/Dev-Santa-Claus-Part-1/&quot;&gt;https://genbattle.bitbucket.io/blog/2018/01/05/Dev-Santa-Claus-Part-1/&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;Part 2: C++ code coverage metrics with gcov 
    &lt;ul&gt; 
     &lt;li&gt;setting up code coverage metrics for a C++ codebase built using Bamboo, CMake, and GCC&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://genbattle.bitbucket.io/blog/2018/01/19/Dev-Santa-Claus-Part-2/&quot;&gt;https://genbattle.bitbucket.io/blog/2018/01/19/Dev-Santa-Claus-Part-2/&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Effective CMake by Kai Wolf 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;http://effective-cmake.com&quot;&gt;http://effective-cmake.com&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://leanpub.com/effective-cmake&quot;&gt;https://leanpub.com/effective-cmake&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Effective Modern CMake - Manuel Binna 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://gist.github.com/mbinna/c61dbb39bca0e4fb7d1f73b0d66a4fd1&quot;&gt;https://gist.github.com/mbinna/c61dbb39bca0e4fb7d1f73b0d66a4fd1&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Everything You Never Wanted to Know About CMake 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://izzys.casa/2019/02/everything-you-never-wanted-to-know-about-cmake/&quot;&gt;https://izzys.casa/2019/02/everything-you-never-wanted-to-know-about-cmake/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;How to Build a CMake-Based Project 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;http://preshing.com/20170511/how-to-build-a-cmake-based-project/&quot;&gt;http://preshing.com/20170511/how-to-build-a-cmake-based-project/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;It&apos;s Time To Do CMake Right 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://pabloariasal.github.io/2018/02/19/its-time-to-do-cmake-right/&quot;&gt;https://pabloariasal.github.io/2018/02/19/its-time-to-do-cmake-right/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Learn CMake&apos;s Scripting Language in 15 Minutes 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;http://preshing.com/20170522/learn-cmakes-scripting-language-in-15-minutes/&quot;&gt;http://preshing.com/20170522/learn-cmakes-scripting-language-in-15-minutes/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Professional CMake: A Practical Guide 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://crascit.com/professional-cmake/&quot;&gt;https://crascit.com/professional-cmake/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;siliceum - Clément Grégoire 
  &lt;ul&gt; 
   &lt;li&gt;CMake basics 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://www.siliceum.com/en/blog/post/cmake_01_cmake-basics&quot;&gt;https://www.siliceum.com/en/blog/post/cmake_01_cmake-basics&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;CMake customization points 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://www.siliceum.com/en/blog/post/cmake_02_customization-points&quot;&gt;https://www.siliceum.com/en/blog/post/cmake_02_customization-points&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Speed up your C++ unit tests cycles with CMake/CTest (and the right testing framework) 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://a4z.bitbucket.io/blog/2018/05/17/Speed-up-your-test-cycles-with-CMake.html&quot;&gt;https://a4z.bitbucket.io/blog/2018/05/17/Speed-up-your-test-cycles-with-CMake.html&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;The Architecture of Open Source Applications: CMake 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;http://www.aosabook.org/en/cmake.html&quot;&gt;http://www.aosabook.org/en/cmake.html&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;The Ultimate Guide to Modern CMake 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://rix0r.nl/blog/2015/08/13/cmake-guide/&quot;&gt;https://rix0r.nl/blog/2015/08/13/cmake-guide/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Tutorial: Easy dependency management for C++ with CMake and Git 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;http://foonathan.net/blog/2016/07/07/cmake-dependency-handling.html&quot;&gt;http://foonathan.net/blog/2016/07/07/cmake-dependency-handling.html&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Using ccache with CMake 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://crascit.com/2016/04/09/using-ccache-with-cmake/&quot;&gt;https://crascit.com/2016/04/09/using-ccache-with-cmake/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Talks&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;Building C++ 
  &lt;ul&gt; 
   &lt;li&gt;C++ Edinburgh 2018; Morris Hafner&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=n_f-2p5eDBo&quot;&gt;https://www.youtube.com/watch?v=n_f-2p5eDBo&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;C++ Weekly - Jason Turner 
  &lt;ul&gt; 
   &lt;li&gt;Ep 78 - Intro to CMake 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=HPMvU64RUTY&quot;&gt;https://www.youtube.com/watch?v=HPMvU64RUTY&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://github.com/lefticus/cpp_starter_project&quot;&gt;https://github.com/lefticus/cpp_starter_project&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;Ep 82 - Intro To CTest 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=ZlMbqFcJEzA&quot;&gt;https://www.youtube.com/watch?v=ZlMbqFcJEzA&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;Ep 208 - The Ultimate CMake / C++ Quick Start 
    &lt;ul&gt; 
     &lt;li&gt;&quot;CMake, sanitizers, clang-tidy, conan, cmake-format, clang-format, cppcheck, doxygen, ctest, catch, {fmt}, and more!&quot;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=YbgH7yat-Jo&quot;&gt;https://www.youtube.com/watch?v=YbgH7yat-Jo&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Deep CMake for Library Authors 
  &lt;ul&gt; 
   &lt;li&gt;CppCon 2019; Craig Scott&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=m0DwB4OvDXk&quot;&gt;https://www.youtube.com/watch?v=m0DwB4OvDXk&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Effective CMake 
  &lt;ul&gt; 
   &lt;li&gt;Daniel Pfeifer&lt;/li&gt; 
   &lt;li&gt;C++Now 2017 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=bsXLMQ6WgIk&quot;&gt;https://www.youtube.com/watch?v=bsXLMQ6WgIk&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://github.com/boostcon/cppnow_presentations_2017/raw/master/05-19-2017_friday/effective_cmake__daniel_pfeifer__cppnow_05-19-2017.pdf&quot;&gt;https://github.com/boostcon/cppnow_presentations_2017/raw/master/05-19-2017_friday/effective_cmake__daniel_pfeifer__cppnow_05-19-2017.pdf&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;MUCplusplus 2017 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=rLopVhns4Zs&quot;&gt;https://www.youtube.com/watch?v=rLopVhns4Zs&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Effective dependency management with CMake 
  &lt;ul&gt; 
   &lt;li&gt;MUCplusplus 2017; Kai Wolf&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=QayyhI-36os&quot;&gt;https://www.youtube.com/watch?v=QayyhI-36os&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Embracing Modern CMake 
  &lt;ul&gt; 
   &lt;li&gt;Stephen Kelly&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://steveire.wordpress.com/2017/11/05/embracing-modern-cmake/&quot;&gt;https://steveire.wordpress.com/2017/11/05/embracing-modern-cmake/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Dublin C++ User Group 2017 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=JsjI5xr1jxM&quot;&gt;https://www.youtube.com/watch?v=JsjI5xr1jxM&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;NDC TechTown 2019 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=mn1ZnO3MtVk&quot;&gt;https://www.youtube.com/watch?v=mn1ZnO3MtVk&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;How to CMake Good 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://vector-of-bool.github.io/2018/08/12/cmake-good.html&quot;&gt;https://vector-of-bool.github.io/2018/08/12/cmake-good.html&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/playlist?list=PLK6MXr8gasrGmIiSuVQXpfFuE1uPT615s&quot;&gt;https://www.youtube.com/playlist?list=PLK6MXr8gasrGmIiSuVQXpfFuE1uPT615s&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Introduction to CMake 
  &lt;ul&gt; 
   &lt;li&gt;SwedenCpp 2018; Florent Castelli&lt;/li&gt; 
   &lt;li&gt;Examples: 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://bit.ly/swedencpp-cmake-workshop&quot;&gt;https://bit.ly/swedencpp-cmake-workshop&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://github.com/Orphis/cmake-workshop&quot;&gt;https://github.com/Orphis/cmake-workshop&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;Slides: 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://bit.ly/swedencpp-cmake-slides&quot;&gt;https://bit.ly/swedencpp-cmake-slides&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://docs.google.com/presentation/d/1vIEfCE33-1BEMT1nNQQbhe-1va-3m2pL9c6_WrIIjdU/&quot;&gt;https://docs.google.com/presentation/d/1vIEfCE33-1BEMT1nNQQbhe-1va-3m2pL9c6_WrIIjdU/&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;Video: 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=jt3meXdP-QI&quot;&gt;https://www.youtube.com/watch?v=jt3meXdP-QI&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Modern CMake for modular design 
  &lt;ul&gt; 
   &lt;li&gt;Meeting C++ 2017; Mathieu Ropert&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=ztrnb-bVVPo&quot;&gt;https://www.youtube.com/watch?v=ztrnb-bVVPo&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;More Modern CMake - Working with CMake 3.12 and later 
  &lt;ul&gt; 
   &lt;li&gt;Meeting C++ 2018; Deniz Bahadir&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://meetingcpp.com/2018/Talks/items/More_Modern_CMake___Working_with_CMake_3_12_and_later.html&quot;&gt;https://meetingcpp.com/2018/Talks/items/More_Modern_CMake___Working_with_CMake_3_12_and_later.html&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://meetingcpp.com/mcpp/slides/2018/MoreModernCMake.pdf&quot;&gt;https://meetingcpp.com/mcpp/slides/2018/MoreModernCMake.pdf&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=y7ndUhdQuU8&quot;&gt;https://www.youtube.com/watch?v=y7ndUhdQuU8&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Oh No! More Modern CMake 
  &lt;ul&gt; 
   &lt;li&gt;Meeting C++ 2019; Deniz Bahadir&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=y9kSr5enrSk&quot;&gt;https://www.youtube.com/watch?v=y9kSr5enrSk&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/Bagira80/More-Modern-CMake&quot;&gt;https://github.com/Bagira80/More-Modern-CMake&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Using Modern CMake Patterns to Enforce a Good Modular Design 
  &lt;ul&gt; 
   &lt;li&gt;CppCon 2017; Mathieu Ropert&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=eC9-iRN2b04&quot;&gt;https://www.youtube.com/watch?v=eC9-iRN2b04&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Additional software&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;BLT (Build, Link and Triumph): A streamlined CMake build system foundation for developing HPC software 
  &lt;ul&gt; 
   &lt;li&gt;composition of CMake macros and several widely used open source tools assembled to simplify HPC software development.&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/llnl/blt&quot;&gt;https://github.com/llnl/blt&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://llnl-blt.readthedocs.io/en/latest/&quot;&gt;http://llnl-blt.readthedocs.io/en/latest/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;CMake Unit 
  &lt;ul&gt; 
   &lt;li&gt;A unit testing framework for CMake.&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/polysquare/cmake-unit&quot;&gt;https://github.com/polysquare/cmake-unit&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;CMakeBuildPackage: Automatic project build script with CMake 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/berenm/CMakeBuildPackage&quot;&gt;https://github.com/berenm/CMakeBuildPackage&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;cmake format: Source code formatter for cmake listfiles. 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/cheshirekow/cmake_format&quot;&gt;https://github.com/cheshirekow/cmake_format&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;CMake Modules 
  &lt;ul&gt; 
   &lt;li&gt;Additional CMake Modules 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://github.com/bilke/cmake-modules&quot;&gt;https://github.com/bilke/cmake-modules&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;Ryan&apos;s CMake Modules 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://github.com/rpavlik/cmake-modules&quot;&gt;https://github.com/rpavlik/cmake-modules&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;cmany: CMake build tree batching tool 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/biojppm/cmany&quot;&gt;https://github.com/biojppm/cmany&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;configure-cmake: autotools-style configure script wrapper around CMake 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/nemequ/configure-cmake&quot;&gt;https://github.com/nemequ/configure-cmake&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;CPM.cmake 
  &lt;ul&gt; 
   &lt;li&gt;CMake&apos;s missing package manager. A small CMake script for setup-free, cross-platform and reproducible dependency management.&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/TheLartians/CPM.cmake&quot;&gt;https://github.com/TheLartians/CPM.cmake&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Izzy&apos;s eXtension Modules: Make CMake less painful when trying to write Modern Flexible CMake 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/slurps-mad-rips/ixm&quot;&gt;https://github.com/slurps-mad-rips/ixm&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;ucm - useful cmake macros 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/onqtam/ucm&quot;&gt;https://github.com/onqtam/ucm&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>CocoR</title>
      <link>https://tedneward.github.io/Research/tools/cocor/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/cocor/index.html</guid>
      	<description>
	&lt;p&gt;&quot;Coco/R is a compiler generator, which takes an attributed grammar of a source language and generates a scanner and a parser for this language. The scanner works as a deterministic finite automaton. The parser uses recursive descent. LL(1) conflicts can be resolved by a multi-symbol lookahead or by semantic checks. Thus the class of accepted grammars is LL(k) for an arbitrary k. There are versions of Coco/R for different languages (see below). The latest versions from the University of Linz are those for C#, Java and C++.&quot;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;http://www.ssw.uni-linz.ac.at/Coco/&quot;&gt;Website&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>CodeSpeak</title>
      <link>https://tedneward.github.io/Research/tools/codespeak/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/codespeak/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://codespeak.dev/&quot;&gt;Website&lt;/a&gt;&lt;/p&gt; 
&lt;h2&gt;Getting Started&lt;/h2&gt; 
&lt;p&gt;&lt;code&gt;uv tool install codespeak-cli&lt;/code&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>CppNet</title>
      <link>https://tedneward.github.io/Research/tools/cppnet/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/cppnet/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/xtravar/CppNet&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Affine</title>
      <link>https://tedneward.github.io/Research/tools/affine/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/affine/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://affine.pro/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/toeverything/AFFiNE&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Obsidian/Notion competitor.&lt;/p&gt; 
&lt;h2&gt;Installation/Self-Hosting&lt;/h2&gt; 
&lt;p&gt;&lt;a href=&quot;https://docs.affine.pro/self-host-affine/install/docker-compose-recommend&quot;&gt;Docker Compose&lt;/a&gt;&lt;/p&gt; 
&lt;h3&gt;1. Create folders to put persisted data&lt;/h3&gt; 
&lt;pre&gt;&lt;code&gt;mkdir affine
cd affine
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;2. Get latest docker-compose.yml&lt;/p&gt; 
&lt;p&gt;You can choose to download the latest compose file tagged together with AFFiNE releases.&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;wget -O docker-compose.yml https://github.com/toeverything/affine/releases/latest/download/docker-compose.yml
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;or go to &lt;a href=&quot;https://docs.affine.pro/self-host-affine/references/docker-compose-yml&quot;&gt;docker-compose.yml&lt;/a&gt; and copy the content, put it in manually created &lt;code&gt;docker-compose.yml&lt;/code&gt; file in the folder created in &lt;a href=&quot;https://docs.affine.pro/self-host-affine/install/docker-compose-recommend#step1&quot;&gt;Step 1&lt;/a&gt;.&lt;/p&gt; 
&lt;p&gt;3. Get .env file&lt;/p&gt; 
&lt;p&gt;A &lt;code&gt;.env&lt;/code&gt; file is required to configure docker volumes mapping to specific where the user data will be persisted at and other required environment variables.&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;wget -O .env https://github.com/toeverything/affine/releases/latest/download/default.env.example
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;or go to &lt;a href=&quot;https://docs.affine.pro/self-host-affine/references/env&quot;&gt;.env&lt;/a&gt; and copy the content, put it in manually created &lt;code&gt;.env&lt;/code&gt; file in the folder created in &lt;a href=&quot;https://docs.affine.pro/self-host-affine/install/docker-compose-recommend#step1&quot;&gt;Step 1&lt;/a&gt;.&lt;/p&gt; 
&lt;p&gt;Then, you need to update the &lt;code&gt;.env&lt;/code&gt; file to correct the fields to your configurations.&lt;/p&gt; 
&lt;p&gt;.env&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;The folder for Postgres data, usually to be the one in step 1 with &apos;/postgres&apos; suffix
DB_DATA_LOCATION=./postgres
The folder for uploaded blobs, usually to be the one in step 1 with &apos;/storage&apos; suffix
UPLOAD_LOCATION=./storage
The folder for custom configurations, usually to be the one in step with &apos;/config&apos; suffix
CONFIG_LOCATION=./config

DATABASE credentials and names to initialize Postgres
DB_USERNAME=affine
DB_PASSWORD=
DB_DATABASE=affine
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;WARNING&lt;/p&gt; 
&lt;p&gt;Most of the values in &lt;code&gt;.env&lt;/code&gt; file shouldn&apos;t be changed once your host initialized and start to have data written.&lt;/p&gt; 
&lt;p&gt;If you do want to, for example, change the location of the &lt;code&gt;affine&lt;/code&gt; folder, please check out &lt;a href=&quot;https://docs.affine.pro/self-host-affine/administer/backup-and-restore&quot;&gt;Backup and Restore&lt;/a&gt; for help.&lt;/p&gt; 
&lt;p&gt;4. Start the containers&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;docker compose up -d
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;5. Validate the deploy in browser&lt;/p&gt; 
&lt;p&gt;If everything goes perfect, you will be able to visit your AFFiNE in browser with &lt;a href=&quot;http://localhost:3010/&quot;&gt;http://localhost:3010&lt;/a&gt;. You might update the port to what you configured in &lt;code&gt;.env&lt;/code&gt; file.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Antigravity (IDE)</title>
      <link>https://tedneward.github.io/Research/tools/antigravity/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/antigravity/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://antigravity.google/&quot;&gt;Website&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Atom (text editor)</title>
      <link>https://tedneward.github.io/Research/tools/atom/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/atom/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;http://atom.io/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/atom&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Built on &lt;a href=&quot;../presentation/electron&quot;&gt;Electron&lt;/a&gt;.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Backdoor Factory (BDF)</title>
      <link>https://tedneward.github.io/Research/tools/backdoor-factory/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/backdoor-factory/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/secretsquirrel/the-backdoor-factory&quot;&gt;Github&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>bingrep</title>
      <link>https://tedneward.github.io/Research/tools/bingrep/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/bingrep/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/m4b/bingrep&quot;&gt;Github&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>BookLore</title>
      <link>https://tedneward.github.io/Research/tools/booklore/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/booklore/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/adityachandelgit/BookLore&quot;&gt;Source&lt;/a&gt; | &lt;a href=&quot;https://hub.docker.com/r/booklore/booklore&quot;&gt;Docker Hub&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Provides an intuitive interface to browse, read, and track your progress across PDFs and eBooks. With robust metadata management, multi-user support, and a sleek, modern UI, BookLore makes it easy to build and explore your personal library.&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;```
services:
    booklore:
        # Official Docker Hub image:
        image: booklore/booklore:latest
        # Or the GHCR image:
        # image: ghcr.io/booklore-app/booklore:latest
        container_name: booklore
        environment:
            - PUID=1000
            - PGID=1000
            - TZ=Etc/UTC
            - DATABASE_URL=jdbc:mariadb://mariadb:3306/booklore   # Only modify this if you&apos;re familiar with JDBC and your database setup
            - DATABASE_USERNAME=booklore                          # Must match MYSQL_USER defined in the mariadb container
            - DATABASE_PASSWORD=your_secure_password              # Use a strong password; must match MYSQL_PASSWORD defined in the mariadb container 
            - SWAGGER_ENABLED=false                               # Enable or disable Swagger UI (API docs). Set to &apos;true&apos; to allow access; &apos;false&apos; to block access (recommended for production).
        depends_on:
            mariadb:
                condition: service_healthy
        ports:
            - &quot;6060:6060&quot;
        volumes:
            - /your/local/path/to/booklore/data:/app/data       # Internal app data (settings, metadata, cache)
            - /your/local/path/to/booklore/books1:/books1       # Book library folder — point to one of your collections
            - /your/local/path/to/booklore/books2:/books2       # Another book library — you can mount multiple library folders this way
            - /your/local/path/to/booklore/bookdrop:/bookdrop   # Bookdrop folder — drop new files here for automatic import into libraries
        restart: unless-stopped

    mariadb:
        image: lscr.io/linuxserver/mariadb:11.4.5
        container_name: mariadb
        environment:
            - PUID=1000
            - PGID=1000
            - TZ=Etc/UTC
            - MYSQL_ROOT_PASSWORD=super_secure_password  # Use a strong password for the database&apos;s root user, should be different from MYSQL_PASSWORD
            - MYSQL_DATABASE=booklore
            - MYSQL_USER=booklore                        # Must match DATABASE_USERNAME defined in the booklore container
            - MYSQL_PASSWORD=your_secure_password        # Use a strong password; must match DATABASE_PASSWORD defined in the booklore container
        volumes:
            - /your/local/path/to/mariadb/config:/config
        restart: unless-stopped
        healthcheck:
            test: [&quot;CMD&quot;, &quot;mariadb-admin&quot;, &quot;ping&quot;, &quot;-h&quot;, &quot;localhost&quot;]
            interval: 5s
            timeout: 5s
            retries: 10
```
&lt;/code&gt;&lt;/pre&gt;
	</description>
    </item>
    <item>
      <title>bore</title>
      <link>https://tedneward.github.io/Research/tools/bore/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/bore/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;http://bore.pub/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/ekzhang/bore&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Build tools and research</title>
      <link>https://tedneward.github.io/Research/tools/building/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/building/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;autotools.html&quot;&gt;Autotools&lt;/a&gt; | &lt;a href=&quot;bazel.html&quot;&gt;Bazel&lt;/a&gt; | &lt;a href=&quot;boostbuild.html&quot;&gt;Boost.Build&lt;/a&gt; | &lt;a href=&quot;build2.html&quot;&gt;build2&lt;/a&gt; | &lt;a href=&quot;cmake.html&quot;&gt;CMake&lt;/a&gt; | &lt;a href=&quot;fastbuild.html&quot;&gt;FASTBuild&lt;/a&gt; | &lt;a href=&quot;gradle.html&quot;&gt;Gradle&lt;/a&gt; | &lt;a href=&quot;make.html&quot;&gt;Make and GNUMake&lt;/a&gt; | &lt;a href=&quot;meson.html&quot;&gt;Meson&lt;/a&gt; | &lt;a href=&quot;msbuild.html&quot;&gt;MSBuild&lt;/a&gt; &lt;a href=&quot;ninja.html&quot;&gt;Ninja&lt;/a&gt; | &lt;a href=&quot;tundra.html&quot;&gt;Tundra&lt;/a&gt; | &lt;a href=&quot;tup.html&quot;&gt;Tup&lt;/a&gt; | &lt;a href=&quot;xcode.html&quot;&gt;Xcode&lt;/a&gt; | &lt;a href=&quot;xmake.html&quot;&gt;xmake&lt;/a&gt;&lt;/p&gt; 
&lt;h1&gt;Readings&lt;/h1&gt; 
&lt;ul&gt; 
 &lt;li&gt;Build Systems à la Carte 
  &lt;ul&gt; 
   &lt;li&gt;Microsoft Research 2018&lt;/li&gt; 
   &lt;li&gt;Andrey Mokhov, Neil Mitchell, Simon Peyton Jones&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.microsoft.com/en-us/research/publication/build-systems-la-carte/&quot;&gt;https://www.microsoft.com/en-us/research/publication/build-systems-la-carte/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/snowleopard/build&quot;&gt;https://github.com/snowleopard/build&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://blogs.ncl.ac.uk/andreymokhov/the-task-abstraction/&quot;&gt;https://blogs.ncl.ac.uk/andreymokhov/the-task-abstraction/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://blogs.ncl.ac.uk/andreymokhov/build-systems-a-la-carte/&quot;&gt;https://blogs.ncl.ac.uk/andreymokhov/build-systems-a-la-carte/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://icfp18.sigplan.org/event/icfp-2018-papers-build-systems-a-la-carte&quot;&gt;https://icfp18.sigplan.org/event/icfp-2018-papers-build-systems-a-la-carte&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=BQVT6wiwCxM&quot;&gt;https://www.youtube.com/watch?v=BQVT6wiwCxM&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Build Systems à La Carte: Theory and Practice 
    &lt;ul&gt; 
     &lt;li&gt;Journal of Functional Programming 30 (2020)&lt;/li&gt; 
     &lt;li&gt;Andrey Mokhov, Neil Mitchell, Simon Peyton Jones&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://doi.org/10.1017/S0956796820000088&quot;&gt;https://doi.org/10.1017/S0956796820000088&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Build System Rules and Algorithms 
  &lt;ul&gt; 
   &lt;li&gt;Mike Shal (2009)&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://gittup.org/tup/build_system_rules_and_algorithms.pdf&quot;&gt;http://gittup.org/tup/build_system_rules_and_algorithms.pdf&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Build System Partial Updates - &lt;a href=&quot;http://gittup.org/blog/2014/09/11-build-system-partial-updates/&quot;&gt;http://gittup.org/blog/2014/09/11-build-system-partial-updates/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Clobber Builds - Mike Shal 
  &lt;ul&gt; 
   &lt;li&gt;Part 1 - Missing Dependencies - &lt;a href=&quot;http://gittup.org/blog/2014/03/6-clobber-builds-part-1---missing-dependencies/&quot;&gt;http://gittup.org/blog/2014/03/6-clobber-builds-part-1---missing-dependencies/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Part 2 - Fixing Missing Dependencies - &lt;a href=&quot;http://gittup.org/blog/2014/05/7-clobber-builds-part-2---fixing-missing-dependencies/&quot;&gt;http://gittup.org/blog/2014/05/7-clobber-builds-part-2---fixing-missing-dependencies/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Part 3 - Other Clobber Causes - &lt;a href=&quot;http://gittup.org/blog/2014/06/8-clobber-builds-part-3---other-clobber-causes/&quot;&gt;http://gittup.org/blog/2014/06/8-clobber-builds-part-3---other-clobber-causes/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Part 4 - Fixing Other Clobber Causes - &lt;a href=&quot;http://gittup.org/blog/2015/03/13-clobber-builds-part-4---fixing-other-clobber-causes/&quot;&gt;http://gittup.org/blog/2015/03/13-clobber-builds-part-4---fixing-other-clobber-causes/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Correct, Efficient, and Tailored: The Future of Build Systems 
  &lt;ul&gt; 
   &lt;li&gt;IEEE Software, vol. 35, no. 2, 2018&lt;/li&gt; 
   &lt;li&gt;G. Maudoux and K. Mens&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://doi.ieeecomputersociety.org/10.1109/MS.2018.111095025&quot;&gt;https://doi.ieeecomputersociety.org/10.1109/MS.2018.111095025&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;The C++ Build Process Explained 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/green7ea/cpp-compilation&quot;&gt;https://github.com/green7ea/cpp-compilation&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Caching&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;Caching Function Calls Using Precise Dependencies 
  &lt;ul&gt; 
   &lt;li&gt;Programming Language Design and Implementation (PLDI) 2000&lt;/li&gt; 
   &lt;li&gt;Allan Heydon, Roy Levin, Yuan Yu&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://www.vestasys.org/doc/pubs/pldi-00-04-20.pdf&quot;&gt;http://www.vestasys.org/doc/pubs/pldi-00-04-20.pdf&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Vesta Configuration Management System - &lt;a href=&quot;http://www.vestasys.org/#publications&quot;&gt;http://www.vestasys.org/#publications&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;cHash: Detection of Redundant Compilations via AST Hashing 
  &lt;ul&gt; 
   &lt;li&gt;USENIX Annual Technical Conference 2017&lt;/li&gt; 
   &lt;li&gt;Christian Dietrich, Valentin Rothberg, Ludwig Füracker, Andreas Ziegler, Daniel Lohmann&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.usenix.org/conference/atc17/technical-sessions/presentation/dietrich&quot;&gt;https://www.usenix.org/conference/atc17/technical-sessions/presentation/dietrich&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;cHash Compiler Plugins and related tools - &lt;a href=&quot;https://github.com/luhsra/chash&quot;&gt;https://github.com/luhsra/chash&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Correctness&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;Detecting Incorrect Build Rules 
  &lt;ul&gt; 
   &lt;li&gt;International Conference on Software Engineering (ICSE) 2019&lt;/li&gt; 
   &lt;li&gt;Nandor Licker, Andrew Rice&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://2019.icse-conferences.org/details/icse-2019-Technical-Papers/82/Detecting-Incorrect-Build-Rules&quot;&gt;https://2019.icse-conferences.org/details/icse-2019-Technical-Papers/82/Detecting-Incorrect-Build-Rules&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.repository.cam.ac.uk/handle/1810/288468&quot;&gt;https://www.repository.cam.ac.uk/handle/1810/288468&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;mkcheck: Incremental Build Verification 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://github.com/nandor/mkcheck&quot;&gt;https://github.com/nandor/mkcheck&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Oops, My Tests Broke the Build: An Explorative Analysis of Travis CI with GitHub 
  &lt;ul&gt; 
   &lt;li&gt;Mining Software Repositories (MSR) 2017&lt;/li&gt; 
   &lt;li&gt;M. Beller, G. Gousios, A. Zaidman&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://www.gousios.gr/pub/tests-broke-build-explorative-analysis-travis-ci-github.pdf&quot;&gt;http://www.gousios.gr/pub/tests-broke-build-explorative-analysis-travis-ci-github.pdf&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.slideshare.net/inventitech/oops-my-tests-broke-the-build-an-explorative-analysis-of-travis-ci-with-github&quot;&gt;https://www.slideshare.net/inventitech/oops-my-tests-broke-the-build-an-explorative-analysis-of-travis-ci-with-github&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Programmers’ Build Errors: A Case Study (at Google) 
  &lt;ul&gt; 
   &lt;li&gt;International Conference on Software Engineering (ICSE) 2014&lt;/li&gt; 
   &lt;li&gt;Hyunmin Seo, Caitlin Sadowski, Sebastian Elbaum, Edward Aftandilian, Robert Bowdidge&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://research.google.com/pubs/pub42184.html&quot;&gt;https://research.google.com/pubs/pub42184.html&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Dependencies&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;Automatic Object Linkage, with Include Graphs (Source code sharing without static libraries) 
  &lt;ul&gt; 
   &lt;li&gt;2018; Thomas Young&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://upcoder.com/19/automatic-object-linkage-with-include-graphs&quot;&gt;https://upcoder.com/19/automatic-object-linkage-with-include-graphs&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Build Predictor: More Accurate Missed Dependency Prediction in Build Configuration Files 
  &lt;ul&gt; 
   &lt;li&gt;Computer Software and Applications Conference (COMPSAC 2014)&lt;/li&gt; 
   &lt;li&gt;Bo Zhou, Xia Xin, David Lo, Xinyu Wang&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://www.mysmu.edu/faculty/davidlo/papers/compsac14-dependency.pdf&quot;&gt;http://www.mysmu.edu/faculty/davidlo/papers/compsac14-dependency.pdf&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.semanticscholar.org/paper/Build-Predictor%3A-More-Accurate-Missed-Dependency-in-Zhou-Xia/a4d4b05c8594fc7358a89f0afffb7e405b65fa0d&quot;&gt;https://www.semanticscholar.org/paper/Build-Predictor%3A-More-Accurate-Missed-Dependency-in-Zhou-Xia/a4d4b05c8594fc7358a89f0afffb7e405b65fa0d&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Program Repository 
  &lt;ul&gt; 
   &lt;li&gt;LLVM with Program Repository Support&lt;br&gt; - &lt;a href=&quot;https://github.com/SNSystems/llvm-project-prepo&quot;&gt;https://github.com/SNSystems/llvm-project-prepo&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Program Repository: What’s the Idea? 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://github.com/SNSystems/llvm-project-prepo/wiki&quot;&gt;https://github.com/SNSystems/llvm-project-prepo/wiki&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;Early Overview 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://github.com/SNSystems/llvm-project-prepo/wiki/Early-Overview&quot;&gt;https://github.com/SNSystems/llvm-project-prepo/wiki/Early-Overview&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;Toy programming demo of a repository for statically compiled programs 
    &lt;ul&gt; 
     &lt;li&gt;2016 US LLVM Developers&apos; Meeting; Paul Bowen-Huggett&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://llvm.org/devmtg/2016-11/Slides/Bowen-Hugett-ToyProgrammingDemo.pdf&quot;&gt;https://llvm.org/devmtg/2016-11/Slides/Bowen-Hugett-ToyProgrammingDemo.pdf&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://youtu.be/-pL94rqyQ6c&quot;&gt;https://youtu.be/-pL94rqyQ6c&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;Targeting a statically compiled program repository with LLVM 
    &lt;ul&gt; 
     &lt;li&gt;2019 EuroLLVM Developers’ Meeting; Phil Camp , Russell Gallop&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=mlQyEBDnDJE&quot;&gt;https://www.youtube.com/watch?v=mlQyEBDnDJE&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;http://llvm.org/devmtg/2019-04/slides/Lightning-Camp-Program_Repo.pdf&quot;&gt;http://llvm.org/devmtg/2019-04/slides/Lightning-Camp-Program_Repo.pdf&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;LLVM Build Times Using a Program Repository 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://www.snsystems.com/technology/tech-blog/llvm-build-times-using-a-program-repository&quot;&gt;https://www.snsystems.com/technology/tech-blog/llvm-build-times-using-a-program-repository&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;Compile Faster with the Program Repository and ccache 
    &lt;ul&gt; 
     &lt;li&gt;2020 European LLVM Developers Meeting; Ying Yi, Paul Bowen-Huggett&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;http://www.llvm.org/devmtg/2020-04/talks.html#LightningTalk_51&quot;&gt;http://www.llvm.org/devmtg/2020-04/talks.html#LightningTalk_51&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;mtime comparison considered harmful 
  &lt;ul&gt; 
   &lt;li&gt;&quot;tl;dr: Rebuilding a target because its mtime is older than the mtimes of its dependencies, like make does, is very error prone. redo does it better, and so can you.&quot;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://apenwarr.ca/log/20181113&quot;&gt;https://apenwarr.ca/log/20181113&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Non-recursive Make Considered Harmful 
  &lt;ul&gt; 
   &lt;li&gt;Proceedings of the 9th International Symposium on Haskell, 2016&lt;/li&gt; 
   &lt;li&gt;Andrey Mokhov, Neil Mitchell, Simon Peyton Jones, Simon Marlow&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.microsoft.com/en-us/research/publication/non-recursive-make-considered-harmful/&quot;&gt;https://www.microsoft.com/en-us/research/publication/non-recursive-make-considered-harmful/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://simonmar.github.io/bib/shake-2016_abstract.html&quot;&gt;https://simonmar.github.io/bib/shake-2016_abstract.html&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Recursive Make Considered Harmful 
  &lt;ul&gt; 
   &lt;li&gt;Journal of AUUG Inc, 19(1):14–25, 1998&lt;/li&gt; 
   &lt;li&gt;Peter Miller&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://aegis.sourceforge.net/auug97.pdf&quot;&gt;http://aegis.sourceforge.net/auug97.pdf&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://sites.e-advies.nl/nonrecursive-make.html&quot;&gt;http://sites.e-advies.nl/nonrecursive-make.html&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Distributed&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;Build in the Cloud 
  &lt;ul&gt; 
   &lt;li&gt;Accessing Source Code: &lt;a href=&quot;http://google-engtools.blogspot.com/2011/06/build-in-cloud-accessing-source-code.html&quot;&gt;http://google-engtools.blogspot.com/2011/06/build-in-cloud-accessing-source-code.html&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;How the Build System works: &lt;a href=&quot;http://google-engtools.blogspot.com/2011/08/build-in-cloud-how-build-system-works.html&quot;&gt;http://google-engtools.blogspot.com/2011/08/build-in-cloud-how-build-system-works.html&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Distributing Build Steps: &lt;a href=&quot;http://google-engtools.blogspot.com/2011/09/build-in-cloud-distributing-build-steps.html&quot;&gt;http://google-engtools.blogspot.com/2011/09/build-in-cloud-distributing-build-steps.html&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Distributing Build Outputs: &lt;a href=&quot;http://google-engtools.blogspot.com/2011/10/build-in-cloud-distributing-build.html&quot;&gt;http://google-engtools.blogspot.com/2011/10/build-in-cloud-distributing-build.html&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;CloudBuild: Microsoft’s Distributed and Caching Build Service 
  &lt;ul&gt; 
   &lt;li&gt;International Conference on Software Engineering (ICSE) 2016&lt;/li&gt; 
   &lt;li&gt;Hamed Esfahani, Jonas Fietz, Qi Ke, Alexei Kolomiets, Erica Lan, Erik Mavrinac, Wolfram Schulte, Newton Sanches, Srikanth Kandula&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://dl.acm.org/citation.cfm?id=2889222&quot;&gt;https://dl.acm.org/citation.cfm?id=2889222&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.microsoft.com/en-us/research/publication/cloudbuild-microsofts-distributed-and-caching-build-service/&quot;&gt;https://www.microsoft.com/en-us/research/publication/cloudbuild-microsofts-distributed-and-caching-build-service/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;From Laptop to Lambda: Outsourcing Everyday Jobs to Thousands of Transient Functional Containers 
  &lt;ul&gt; 
   &lt;li&gt;2019 USENIX Annual Technical Conference&lt;/li&gt; 
   &lt;li&gt;Sadjad Fouladi, Francisco Romero, Dan Iter, Qian Li, Shuvo Chatterjee, Christos Kozyrakis, Matei Zaharia, Keith Winstein&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.usenix.org/conference/atc19/presentation/fouladi&quot;&gt;https://www.usenix.org/conference/atc19/presentation/fouladi&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Outsourcing Everyday Jobs to Thousands of Cloud Functions with gg 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://www.usenix.org/system/files/login/articles/login_fall19_02_fouladi.pdf&quot;&gt;https://www.usenix.org/system/files/login/articles/login_fall19_02_fouladi.pdf&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;gg: The Stanford Builder 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://github.com/stanfordsnr/gg&quot;&gt;https://github.com/stanfordsnr/gg&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Incremental Building&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;A Sound and Optimal Incremental Build System with Dynamic Dependencies 
  &lt;ul&gt; 
   &lt;li&gt;SPLASH 2015 OOPSLA&lt;/li&gt; 
   &lt;li&gt;Sebastian Erdweg, Moritz Lichter, Manuel Weiel&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=QsgLSDMLLTo&quot;&gt;https://www.youtube.com/watch?v=QsgLSDMLLTo&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://2015.splashcon.org/event/oopsla2015-a-sound-and-optimal-incremental-build-system&quot;&gt;https://2015.splashcon.org/event/oopsla2015-a-sound-and-optimal-incremental-build-system&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Bringing Incremental Builds to Continuous Integration 
  &lt;ul&gt; 
   &lt;li&gt;SaTToSE (Seminar Series on Advanced Techniques &amp;amp; Tools for Software Evolution) 2017&lt;/li&gt; 
   &lt;li&gt;Guillaume Maudoux and Kim Mens&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://dial.uclouvain.be/pr/boreal/object/boreal:189543&quot;&gt;https://dial.uclouvain.be/pr/boreal/object/boreal:189543&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://sattose.wdfiles.com/local--files/2017:schedule/SATToSE_2017_paper_3.pdf&quot;&gt;http://sattose.wdfiles.com/local--files/2017:schedule/SATToSE_2017_paper_3.pdf&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Constructing Hybrid Incremental Compilers for Cross-Module Extensibility with an Internal Build System 
  &lt;ul&gt; 
   &lt;li&gt;‹Programming› 2020&lt;/li&gt; 
   &lt;li&gt;Jeff Smits, Gabriël Konat, Eelco Visser&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://2020.programming-conference.org/details/programming-2020-papers/16/Constructing-Hybrid-Incremental-Compilers-for-Cross-Module-Extensibility-with-an-Inte&quot;&gt;https://2020.programming-conference.org/details/programming-2020-papers/16/Constructing-Hybrid-Incremental-Compilers-for-Cross-Module-Extensibility-with-an-Inte&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Scalable Incremental Building with Dynamic Task Dependencies 
  &lt;ul&gt; 
   &lt;li&gt;Automated Software Engineering (ASE) 2018&lt;/li&gt; 
   &lt;li&gt;Gabriël Konat, Sebastian Erdweg, Eelco Visser&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://doi.org/10.1145/3238147.3238196&quot;&gt;https://doi.org/10.1145/3238147.3238196&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://eelcovisser.org/post/306/scalable-incremental-building-with-dynamic-task-dependencies&quot;&gt;https://eelcovisser.org/post/306/scalable-incremental-building-with-dynamic-task-dependencies&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.student.informatik.tu-darmstadt.de/~xx00seba/publications/pie-scalable-incremental-build.pdf&quot;&gt;https://www.student.informatik.tu-darmstadt.de/~xx00seba/publications/pie-scalable-incremental-build.pdf&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Reproducibility&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;An introduction to deterministic builds with C/C++ 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://blog.conan.io/2019/09/02/Deterministic-builds-with-C-C++.html&quot;&gt;https://blog.conan.io/2019/09/02/Deterministic-builds-with-C-C++.html&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Automated Localization for Unreproducible Builds 
  &lt;ul&gt; 
   &lt;li&gt;ICSE 2018&lt;/li&gt; 
   &lt;li&gt;Zhilei Ren, He Jiang, Jifeng Xuan, Zijiang Yang&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://arxiv.org/abs/1803.06766&quot;&gt;https://arxiv.org/abs/1803.06766&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://blog.acolyer.org/2018/06/22/automated-localization-for-unreproducible-builds/&quot;&gt;https://blog.acolyer.org/2018/06/22/automated-localization-for-unreproducible-builds/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Deterministic builds with Clang and LLD 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;http://blog.llvm.org/2019/11/deterministic-builds-with-clang-and-lld.html&quot;&gt;http://blog.llvm.org/2019/11/deterministic-builds-with-clang-and-lld.html&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Reproducible Builds — a set of software development practices that create an independently-verifiable path from source to binary code 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://reproducible-builds.org/&quot;&gt;https://reproducible-builds.org/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;hr&gt; 
&lt;h1&gt;Build Performance&lt;/h1&gt; 
&lt;h2&gt;Build Performance Readings&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;2 tips to make your C++ projects compile 3 times faster 
  &lt;ul&gt; 
   &lt;li&gt;Tip #1: Distributing compilation load&lt;/li&gt; 
   &lt;li&gt;Tip #2: Using a distcc server container&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://developers.redhat.com/blog/2019/05/15/2-tips-to-make-your-c-projects-compile-3-times-faster/&quot;&gt;https://developers.redhat.com/blog/2019/05/15/2-tips-to-make-your-c-projects-compile-3-times-faster/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;30% faster Windows builds with clang-cl and the new &lt;code&gt;/Zc:dllexportInlines-&lt;/code&gt; flag 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;http://blog.llvm.org/2018/11/30-faster-windows-builds-with-clang-cl_14.html&quot;&gt;http://blog.llvm.org/2018/11/30-faster-windows-builds-with-clang-cl_14.html&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Anders Schau Knatten 
  &lt;ul&gt; 
   &lt;li&gt;Another Reason to Avoid #includes in Headers 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://blog.knatten.org/2012/11/09/another-reason-to-avoid-includes-in-headers/&quot;&gt;https://blog.knatten.org/2012/11/09/another-reason-to-avoid-includes-in-headers/&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;How to avoid includes in headers 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://blog.knatten.org/2012/11/30/how-to-avoid-includes-in-headers/&quot;&gt;https://blog.knatten.org/2012/11/30/how-to-avoid-includes-in-headers/&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Aras Pranckevičius 
  &lt;ul&gt; 
   &lt;li&gt;Unreasonable Effectiveness of Profilers (profiling the build system) - &lt;a href=&quot;http://aras-p.info/blog/2017/08/08/Unreasonable-Effectiveness-of-Profilers/&quot;&gt;http://aras-p.info/blog/2017/08/08/Unreasonable-Effectiveness-of-Profilers/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Forced Inlining Might Be Slow - &lt;a href=&quot;https://aras-p.info/blog/2017/10/09/Forced-Inlining-Might-Be-Slow/&quot;&gt;https://aras-p.info/blog/2017/10/09/Forced-Inlining-Might-Be-Slow/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Best unknown MSVC flag: d2cgsummary - &lt;a href=&quot;https://aras-p.info/blog/2017/10/23/Best-unknown-MSVC-flag-d2cgsummary/&quot;&gt;https://aras-p.info/blog/2017/10/23/Best-unknown-MSVC-flag-d2cgsummary/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Slow to Compile Table Initializers - &lt;a href=&quot;https://aras-p.info/blog/2017/10/24/Slow-to-Compile-Table-Initializers/&quot;&gt;https://aras-p.info/blog/2017/10/24/Slow-to-Compile-Table-Initializers/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Investigating compile times, and Clang -ftime-report - &lt;a href=&quot;http://aras-p.info/blog/2019/01/12/Investigating-compile-times-and-Clang-ftime-report/&quot;&gt;http://aras-p.info/blog/2019/01/12/Investigating-compile-times-and-Clang-ftime-report/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Another cool MSVC flag: /d1reportTime 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;http://aras-p.info/blog/2019/01/21/Another-cool-MSVC-flag-d1reportTime/&quot;&gt;http://aras-p.info/blog/2019/01/21/Another-cool-MSVC-flag-d1reportTime/&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;Reports where the compiler frontend spends time.&lt;/li&gt; 
     &lt;li&gt;Passing /d1reportTime to the MSVC compiler (cl.exe) will make it print: 
      &lt;ul&gt; 
       &lt;li&gt;Which header files are included (hierarchically), with time taken for each,&lt;/li&gt; 
       &lt;li&gt;Which classes are being parsed, with time taken for each,&lt;/li&gt; 
       &lt;li&gt;Which functions are being parsed, with time taken for each.&lt;/li&gt; 
      &lt;/ul&gt; &lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Big Project Build Times–Chromium 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://randomascii.wordpress.com/2020/03/30/big-project-build-times-chromium/&quot;&gt;https://randomascii.wordpress.com/2020/03/30/big-project-build-times-chromium/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;C++ Compilation Speed 
  &lt;ul&gt; 
   &lt;li&gt;Walter Bright - DDJ, August 17, 2010&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://digitalmars.com/articles/b54.html&quot;&gt;https://digitalmars.com/articles/b54.html&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://www.drdobbs.com/cpp/c-compilation-speed/228701711&quot;&gt;http://www.drdobbs.com/cpp/c-compilation-speed/228701711&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;C++ Compilation: Fixing It 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;http://virtuallyrandom.com/c-compilation-fixing-it/&quot;&gt;http://virtuallyrandom.com/c-compilation-fixing-it/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Faster C++ builds 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;http://www.bitsnbites.eu/faster-c-builds/&quot;&gt;http://www.bitsnbites.eu/faster-c-builds/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Identifying and Understanding Header File Hotspots in C/C++ Build Processes 
  &lt;ul&gt; 
   &lt;li&gt;Automated Software Engineering, Vol. 23, No. 4, 2016&lt;/li&gt; 
   &lt;li&gt;Shane McIntosh, Bram Adams, Meiyappan Nagappan, Ahmed E. Hassan&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://rebels.ece.mcgill.ca/journalpaper/2015/07/08/identifying-and-understanding-header-file-hotspots-in-c-cpp-build-processes.html&quot;&gt;http://rebels.ece.mcgill.ca/journalpaper/2015/07/08/identifying-and-understanding-header-file-hotspots-in-c-cpp-build-processes.html&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Improving C++ Builds with Split DWARF 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.productive-cpp.com/improving-cpp-builds-with-split-dwarf/&quot;&gt;https://www.productive-cpp.com/improving-cpp-builds-with-split-dwarf/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Improving Compilation Time of C/C++ Projects 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://interrupt.memfault.com/blog/improving-compilation-times-c-cpp-projects&quot;&gt;https://interrupt.memfault.com/blog/improving-compilation-times-c-cpp-projects&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Investigating C++ compile times 
  &lt;ul&gt; 
   &lt;li&gt;My journey investigating slow compile times in C++ 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://metanokid.github.io/coding-scars/investigating-cpp-compile-times-0&quot;&gt;https://metanokid.github.io/coding-scars/investigating-cpp-compile-times-0&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;Useful tools to investigate C++ compile times 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://metanokid.github.io/coding-scars/investigating-cpp-compile-times-1&quot;&gt;https://metanokid.github.io/coding-scars/investigating-cpp-compile-times-1&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;Understanding MSBuild to create flame graphs 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://metanokid.github.io/coding-scars/investigating-cpp-compile-times-2&quot;&gt;https://metanokid.github.io/coding-scars/investigating-cpp-compile-times-2&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;Improving C++ compile times using flame graphs 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://metanokid.github.io/coding-scars/investigating-cpp-compile-times-3&quot;&gt;https://metanokid.github.io/coding-scars/investigating-cpp-compile-times-3&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;Getting data from C++ Build Insights SDK 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://metanokid.github.io/coding-scars/investigating-cpp-compile-times-4&quot;&gt;https://metanokid.github.io/coding-scars/investigating-cpp-compile-times-4&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Physical Design of The Machinery 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;http://ourmachinery.com/post/physical-design/&quot;&gt;http://ourmachinery.com/post/physical-design/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Reducing Build Time through Precompilations for Evolving Large Software 
  &lt;ul&gt; 
   &lt;li&gt;International Conference on Software Maintenance (ICSM) 2005&lt;/li&gt; 
   &lt;li&gt;Yu, Yijun; Dayani-Fard, Homayoun; Mylopoulos, John and Andritsos, Periklis&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://www.cs.toronto.edu/%7Eperiklis/pubs/icsm05.pdf&quot;&gt;http://www.cs.toronto.edu/%7Eperiklis/pubs/icsm05.pdf&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://oro.open.ac.uk/6944/&quot;&gt;http://oro.open.ac.uk/6944/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;To Unify or Not to Unify: A Case Study on Unified Builds (in WebKit) 
  &lt;ul&gt; 
   &lt;li&gt;Compiler Construction (CC) 2019&lt;/li&gt; 
   &lt;li&gt;Takafumi Kubota, Yusuke Suzuki, and Kenji Kono&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://doi.org/10.1145/3302516.3307347&quot;&gt;https://doi.org/10.1145/3302516.3307347&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Build Performance Software&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;Cotire (compile time reducer) 
  &lt;ul&gt; 
   &lt;li&gt;a CMake module that speeds up the build process of CMake based build systems by fully automating techniques as precompiled header usage and single compilation unit builds for C and C++.&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/sakra/cotire&quot;&gt;https://github.com/sakra/cotire&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Benchmarking and Profiling&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;C++ Compile Health Watchdog 
  &lt;ul&gt; 
   &lt;li&gt;Benchmark and accountability tool for C++ compile-time overhead / compile-time health.&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/Philip-Trettner/cpp-compile-overhead&quot;&gt;https://github.com/Philip-Trettner/cpp-compile-overhead&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Results: &lt;a href=&quot;https://artificial-mind.net/projects/compile-health/&quot;&gt;https://artificial-mind.net/projects/compile-health/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Clang -ftime-trace and ftime-trace-granularity=N 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;http://releases.llvm.org/9.0.0/tools/clang/docs/ReleaseNotes.html#new-compiler-flags&quot;&gt;http://releases.llvm.org/9.0.0/tools/clang/docs/ReleaseNotes.html#new-compiler-flags&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Clang Time Trace Feature 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://www.snsystems.com/technology/tech-blog/clang-time-trace-feature&quot;&gt;https://www.snsystems.com/technology/tech-blog/clang-time-trace-feature&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;Clang Build Analyzer 
    &lt;ul&gt; 
     &lt;li&gt;Clang build analysis tool using -ftime-trace&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://github.com/aras-p/ClangBuildAnalyzer&quot;&gt;https://github.com/aras-p/ClangBuildAnalyzer&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://aras-p.info/blog/2019/09/28/Clang-Build-Analyzer/&quot;&gt;https://aras-p.info/blog/2019/09/28/Clang-Build-Analyzer/&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;time-trace: timeline / flame chart profiler for Clang 
      &lt;ul&gt; 
       &lt;li&gt;&lt;a href=&quot;https://aras-p.info/blog/2019/01/16/time-trace-timeline-flame-chart-profiler-for-Clang/&quot;&gt;https://aras-p.info/blog/2019/01/16/time-trace-timeline-flame-chart-profiler-for-Clang/&lt;/a&gt;&lt;/li&gt; 
      &lt;/ul&gt; &lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;CTMark (Compile Time Mark) 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/llvm-mirror/test-suite/tree/master/CTMark&quot;&gt;https://github.com/llvm-mirror/test-suite/tree/master/CTMark&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Metabench: A simple framework for compile-time microbenchmarks 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;http://metaben.ch/&quot;&gt;http://metaben.ch/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/ldionne/metabench&quot;&gt;https://github.com/ldionne/metabench&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Templight: Template Instantiation Profiler and Debugger 
  &lt;ul&gt; 
   &lt;li&gt;a Clang-based tool to profile the time and memory consumption of template instantiations and to perform interactive debugging sessions to gain introspection into the template instantiation process&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/mikael-s-persson/templight&quot;&gt;https://github.com/mikael-s-persson/templight&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Use templight and Templar to debug C++ templates 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://baptiste-wicht.com/posts/2016/02/use-templight-and-templar-to-debug-cpp-templates.html&quot;&gt;https://baptiste-wicht.com/posts/2016/02/use-templight-and-templar-to-debug-cpp-templates.html&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;Templight: A Clang Extension for Debugging and Profiling C++ Template Metaprograms 
    &lt;ul&gt; 
     &lt;li&gt;2015 EuroLLVM Developers’ Meeting, Zoltan Porkolab&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://llvm.org/devmtg/2015-04/slides/EuroLLVM2015Templight.pdf&quot;&gt;https://llvm.org/devmtg/2015-04/slides/EuroLLVM2015Templight.pdf&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=djAPtopWhRU&quot;&gt;https://www.youtube.com/watch?v=djAPtopWhRU&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Visual C++ 
  &lt;ul&gt; 
   &lt;li&gt;vcperf: A build analysis tool for the MSVC toolchain 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://github.com/microsoft/vcperf&quot;&gt;https://github.com/microsoft/vcperf&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;MSBuild Flame Graph: Turns MSBuild executions into flame graphs 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://github.com/MetanoKid/msbuild-flame-graph&quot;&gt;https://github.com/MetanoKid/msbuild-flame-graph&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;C++ Build Insights 
    &lt;ul&gt; 
     &lt;li&gt;Get started with C++ Build Insights 
      &lt;ul&gt; 
       &lt;li&gt;&lt;a href=&quot;https://docs.microsoft.com/en-us/cpp/build-insights/get-started-with-cpp-build-insights&quot;&gt;https://docs.microsoft.com/en-us/cpp/build-insights/get-started-with-cpp-build-insights&lt;/a&gt;&lt;/li&gt; 
      &lt;/ul&gt; &lt;/li&gt; 
     &lt;li&gt;Introducing C++ Build Insights 
      &lt;ul&gt; 
       &lt;li&gt;&lt;a href=&quot;https://devblogs.microsoft.com/cppblog/introducing-c-build-insights/&quot;&gt;https://devblogs.microsoft.com/cppblog/introducing-c-build-insights/&lt;/a&gt;&lt;/li&gt; 
      &lt;/ul&gt; &lt;/li&gt; 
     &lt;li&gt;Analyze your builds programmatically with the C++ Build Insights SDK 
      &lt;ul&gt; 
       &lt;li&gt;&lt;a href=&quot;https://devblogs.microsoft.com/cppblog/analyze-your-builds-programmatically-with-the-c-build-insights-sdk/&quot;&gt;https://devblogs.microsoft.com/cppblog/analyze-your-builds-programmatically-with-the-c-build-insights-sdk/&lt;/a&gt;&lt;/li&gt; 
      &lt;/ul&gt; &lt;/li&gt; 
     &lt;li&gt;Finding build bottlenecks with C++ Build Insights 
      &lt;ul&gt; 
       &lt;li&gt;&lt;a href=&quot;https://devblogs.microsoft.com/cppblog/finding-build-bottlenecks-with-cpp-build-insights/&quot;&gt;https://devblogs.microsoft.com/cppblog/finding-build-bottlenecks-with-cpp-build-insights/&lt;/a&gt;&lt;/li&gt; 
      &lt;/ul&gt; &lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Caching&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;ccache: A Fast C/C++ Compiler Cache 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://ccache.samba.org&quot;&gt;https://ccache.samba.org&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;distcc: A free distributed C/C++ compiler system 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/distcc/distcc&quot;&gt;https://github.com/distcc/distcc&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;icecream: Distributed compiler with a central scheduler to share build load 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/icecc/icecream&quot;&gt;https://github.com/icecc/icecream&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;sccache - Shared Compilation Cache 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/mozilla/sccache&quot;&gt;https://github.com/mozilla/sccache&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Dependencies Analysis and Optimization&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;cpp-dependencies: Tool to check C++ #include dependencies (dependency graphs created in .dot format) 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/tomtom-international/cpp-dependencies&quot;&gt;https://github.com/tomtom-international/cpp-dependencies&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Header Hero: optimizing C++ codebase header #include dependencies 
  &lt;ul&gt; 
   &lt;li&gt;A tool for optimizing C++ header files and reducing build times.&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://bitbucket.org/bitsquid/header_hero&quot;&gt;https://bitbucket.org/bitsquid/header_hero&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://bitsquid.blogspot.com/2011/10/caring-by-sharing-header-hero.html&quot;&gt;https://bitsquid.blogspot.com/2011/10/caring-by-sharing-header-hero.html&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://aras-p.info/blog/2018/01/17/Header-Hero-Improvements/&quot;&gt;https://aras-p.info/blog/2018/01/17/Header-Hero-Improvements/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;include-what-you-use 
  &lt;ul&gt; 
   &lt;li&gt;A tool for use with clang to analyze #includes in C and C++ source files&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://include-what-you-use.org/&quot;&gt;https://include-what-you-use.org/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/include-what-you-use/include-what-you-use&quot;&gt;https://github.com/include-what-you-use/include-what-you-use&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Build Performance Talks&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;Common-sense acceleration of your MLOC build 
  &lt;ul&gt; 
   &lt;li&gt;CppCon 2014; Matt Hargett&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=t4M3yG1dWho&quot;&gt;https://www.youtube.com/watch?v=t4M3yG1dWho&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Compiling C++ is slow - let&apos;s go faster 
  &lt;ul&gt; 
   &lt;li&gt;StockholmCpp 2020; Tobias Hieta&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=X4pyOtawqjg&quot;&gt;https://www.youtube.com/watch?v=X4pyOtawqjg&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://gist.github.com/tru/ad677ba2b1d543e238b0e09eb3aad3ac&quot;&gt;https://gist.github.com/tru/ad677ba2b1d543e238b0e09eb3aad3ac&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;LLVM Compile-Time: Challenges. Improvements. Outlook. 
  &lt;ul&gt; 
   &lt;li&gt;2017 LLVM Developers’ Meeting; Michael Zolotukhin&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=bYHMwyyZ6Mk&quot;&gt;https://www.youtube.com/watch?v=bYHMwyyZ6Mk&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Optimizing builds on Windows 
  &lt;ul&gt; 
   &lt;li&gt;2019 LLVM Developers’ Meeting; Alexandre Ganea&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=usPL_DROn4k&quot;&gt;https://www.youtube.com/watch?v=usPL_DROn4k&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://llvm.org/devmtg/2019-10/slides/Ganea-OptimizingBuildesOnWindows.pdf&quot;&gt;https://llvm.org/devmtg/2019-10/slides/Ganea-OptimizingBuildesOnWindows.pdf&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Optimizing compilation times with Templates 
  &lt;ul&gt; 
   &lt;li&gt;CppCon 2017: Eddie Elizondo&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=NPWQ7xKfIHQ&quot;&gt;https://www.youtube.com/watch?v=NPWQ7xKfIHQ&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/eduardo-elizondo/cppcon2017&quot;&gt;https://github.com/eduardo-elizondo/cppcon2017&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Practical Techniques for Improving C++ Build Times 
  &lt;ul&gt; 
   &lt;li&gt;CppCon 2017; Dmitry Panin&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=h8UoYG4dvH8&quot;&gt;https://www.youtube.com/watch?v=h8UoYG4dvH8&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;The Hitchhiker&apos;s Guide to Faster Builds 
  &lt;ul&gt; 
   &lt;li&gt;Viktor Kirilov&lt;/li&gt; 
   &lt;li&gt;slides: &lt;a href=&quot;https://slides.com/onqtam/faster_builds&quot;&gt;https://slides.com/onqtam/faster_builds&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;CppOnSea 2019 - &lt;a href=&quot;https://www.youtube.com/watch?v=anbOy47fBYI&quot;&gt;https://www.youtube.com/watch?v=anbOy47fBYI&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;C++ Russia 2019 - &lt;a href=&quot;https://www.youtube.com/watch?v=5rRLHRRqg5A&quot;&gt;https://www.youtube.com/watch?v=5rRLHRRqg5A&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;code::dive 2018 
    &lt;ul&gt; 
     &lt;li&gt;Part 1: &lt;a href=&quot;https://www.youtube.com/watch?v=WSFbNhCbdJM&quot;&gt;https://www.youtube.com/watch?v=WSFbNhCbdJM&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;Part 2: &lt;a href=&quot;https://www.youtube.com/watch?v=9-Y5JnJlypM&quot;&gt;https://www.youtube.com/watch?v=9-Y5JnJlypM&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Visual Studio 
  &lt;ul&gt; 
   &lt;li&gt;clcache.py - a compiler cache for Microsoft Visual Studio 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://github.com/frerich/clcache&quot;&gt;https://github.com/frerich/clcache&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;CompileTimer: Set of tests to benchmark the compile time of C++ constructs 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://github.com/janwilmans/CompileTimer&quot;&gt;https://github.com/janwilmans/CompileTimer&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;Make VC++ Compiles Fast Through Parallel Compilation 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://randomascii.wordpress.com/2014/03/22/make-vc-compiles-fast-through-parallel-compilation/&quot;&gt;https://randomascii.wordpress.com/2014/03/22/make-vc-compiles-fast-through-parallel-compilation/&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;Visual Studio 2017 Throughput Improvements and Advice 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://blogs.msdn.microsoft.com/vcblog/2018/01/04/visual-studio-2017-throughput-improvements-and-advice/&quot;&gt;https://blogs.msdn.microsoft.com/vcblog/2018/01/04/visual-studio-2017-throughput-improvements-and-advice/&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;hr&gt; 
&lt;h1&gt;Software&lt;/h1&gt; 
&lt;ul&gt; 
 &lt;li&gt;Build System Shootout: Comparison of build program expressive power 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/ndmitchell/build-shootout&quot;&gt;https://github.com/ndmitchell/build-shootout&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;TraceCode: Trace a build to find out which source files are built in a binary 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/nexB/tracecode-toolkit&quot;&gt;https://github.com/nexB/tracecode-toolkit&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Debug your build by tracing and reversing: stracing your build from sources to binaries 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://fosdem.org/2018/schedule/event/debugging_tools_stracing_build/&quot;&gt;https://fosdem.org/2018/schedule/event/debugging_tools_stracing_build/&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;hr&gt; 
&lt;h1&gt;Talks&lt;/h1&gt; 
&lt;h2&gt;2019&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;Behind the Scenes of a C++ Build System 
  &lt;ul&gt; 
   &lt;li&gt;CppCon 2019; Jussi Pakkanen&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=34KzT2yvQuM&quot;&gt;https://www.youtube.com/watch?v=34KzT2yvQuM&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/CppCon/CppCon2019/tree/master/Presentations/behind_the_scenes_of_a_cpp_build_system&quot;&gt;https://github.com/CppCon/CppCon2019/tree/master/Presentations/behind_the_scenes_of_a_cpp_build_system&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Building Modules 
  &lt;ul&gt; 
   &lt;li&gt;CppCon 2019; Michael Spencer&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=L0SHHkBenss&quot;&gt;https://www.youtube.com/watch?v=L0SHHkBenss&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;2018&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;Build Systems: a Simple Solution to a Complicated Problem 
  &lt;ul&gt; 
   &lt;li&gt;CppCon 2018; Peter Bindels&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=mWOmkwv8N_U&quot;&gt;https://www.youtube.com/watch?v=mWOmkwv8N_U&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Creating the Complete Build Package 
  &lt;ul&gt; 
   &lt;li&gt;CppCon 2018&lt;/li&gt; 
   &lt;li&gt;Panelists: Boris Kolpackov, Titus Winter, Robert Schumacher, Paddy McDonald, Manuel Klimek&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=TjdCxXdjaSA&quot;&gt;https://www.youtube.com/watch?v=TjdCxXdjaSA&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Don&apos;t package your libraries, write packagable libraries! 
  &lt;ul&gt; 
   &lt;li&gt;CppCon 2018; Robert Schumacher&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=sBP17HQAQjk&quot;&gt;https://www.youtube.com/watch?v=sBP17HQAQjk&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;What to Expect from a Next-Generation C++ Build System 
  &lt;ul&gt; 
   &lt;li&gt;CppCon 2018; Boris Kolpackov&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=cJP7SSLjvSI&quot;&gt;https://www.youtube.com/watch?v=cJP7SSLjvSI&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;2016&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;A New Architecture for Building Software 
  &lt;ul&gt; 
   &lt;li&gt;2016 LLVM Developers’ Meeting; Daniel Dunbar&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=b_T-eCToX1I&quot;&gt;https://www.youtube.com/watch?v=b_T-eCToX1I&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://www.llvm.org/devmtg/2016-11/#talk10&quot;&gt;http://www.llvm.org/devmtg/2016-11/#talk10&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;llbuild: A low-level build system, used by Xcode and the Swift Package Manager 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://github.com/apple/swift-llbuild&quot;&gt;https://github.com/apple/swift-llbuild&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;2017&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;Building C++ Modules 
  &lt;ul&gt; 
   &lt;li&gt;CppCon 2017; Boris Kolpackov&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=E8EbDcLQAoc&quot;&gt;https://www.youtube.com/watch?v=E8EbDcLQAoc&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;There Will Be Build Systems: I Configure Your Milkshake 
  &lt;ul&gt; 
   &lt;li&gt;CppCon 2017; Isabella Muerte&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=7THzO-D0ta4&quot;&gt;https://www.youtube.com/watch?v=7THzO-D0ta4&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Calca</title>
      <link>https://tedneward.github.io/Research/tools/calca/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/calca/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://calca.io/&quot;&gt;Website&lt;/a&gt; | Commercial?&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Checker (Framework)</title>
      <link>https://tedneward.github.io/Research/tools/checker/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/checker/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://checkerframework.org/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/typetools/checker-framework/&quot;&gt;Source&lt;/a&gt; | &lt;a href=&quot;https://checkerframework.org/manual/checker-framework-manual.pdf&quot;&gt;Doc (PDF)&lt;/a&gt; | &lt;a href=&quot;https://checkerframework.org/tutorial/&quot;&gt;Tutorials&lt;/a&gt;&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://checkerframework.org/manual/checker-framework-dataflow-manual.pdf&quot;&gt;Dataflow Manual&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://checkerframework.org/annotation-file-utilities/&quot;&gt;Annotation File Utilities&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Clang static analysis reading</title>
      <link>https://tedneward.github.io/Research/tools/clang/static-analysis/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/clang/static-analysis/index.html</guid>
      	<description>
	&lt;ul&gt; 
 &lt;li&gt; &lt;p&gt;Clang Static Analyzer&lt;/p&gt; 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;http://clang-analyzer.llvm.org/&quot;&gt;http://clang-analyzer.llvm.org/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Checker Developer Manual 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;http://clang-analyzer.llvm.org/checker_dev_manual.html&quot;&gt;http://clang-analyzer.llvm.org/checker_dev_manual.html&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;Clang Static Analysis 
    &lt;ul&gt; 
     &lt;li&gt;Meeting C++ 2016; Gabor Horvath&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=UcxF6CVueDM&quot;&gt;https://www.youtube.com/watch?v=UcxF6CVueDM&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;Clang Static Analyzer - A Checker Developer&apos;s Guide. 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://github.com/haoNoQ/clang-analyzer-guide&quot;&gt;https://github.com/haoNoQ/clang-analyzer-guide&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;Faster, Stronger C++ Analysis with the Clang Static Analyzer 
    &lt;ul&gt; 
     &lt;li&gt;2018 LLVM Developers’ Meeting; George Karpenkov, Artem Dergachev&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=4n3l-ZcDJNY&quot;&gt;https://www.youtube.com/watch?v=4n3l-ZcDJNY&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Clang-Tidy: Clang-based C++ “linter” tool&lt;/p&gt; 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;http://clang.llvm.org/extra/clang-tidy/&quot;&gt;http://clang.llvm.org/extra/clang-tidy/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Clang-Tidy - KDAB 
    &lt;ul&gt; 
     &lt;li&gt;part 1: Modernize your source code using C++11/C++14 - &lt;a href=&quot;https://www.kdab.com/clang-tidy-part-1-modernize-source-code-using-c11c14/&quot;&gt;https://www.kdab.com/clang-tidy-part-1-modernize-source-code-using-c11c14/&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;part 2: Integrate qmake and other build systems using Bear - &lt;a href=&quot;https://www.kdab.com/clang-tidy-part-2-integrate-qmake-and-other-build-systems-using-bear/&quot;&gt;https://www.kdab.com/clang-tidy-part-2-integrate-qmake-and-other-build-systems-using-bear/&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;How to use Clang Tidy to automatically correct code 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://github.com/KratosMultiphysics/Kratos/wiki/How-to-use-Clang-Tidy-to-automatically-correct-code&quot;&gt;https://github.com/KratosMultiphysics/Kratos/wiki/How-to-use-Clang-Tidy-to-automatically-correct-code&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;Intro to clang-tidy - C++ Weekly - Ep 3 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=OchPaGEH4TE&quot;&gt;https://www.youtube.com/watch?v=OchPaGEH4TE&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Clang Thread Safety Analysis&lt;/p&gt; 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://clang.llvm.org/docs/ThreadSafetyAnalysis.html&quot;&gt;https://clang.llvm.org/docs/ThreadSafetyAnalysis.html&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;C/C++ Thread Safety Analysis 
    &lt;ul&gt; 
     &lt;li&gt;DeLesley Hutchins, Aaron Ballman, Dean Sutherland&lt;/li&gt; 
     &lt;li&gt;2014 IEEE 14th International Working Conference on Source Code Analysis and Manipulation&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://research.google/pubs/pub42958/&quot;&gt;https://research.google/pubs/pub42958/&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;Thread Safety Analysis in C and C++ 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://insights.sei.cmu.edu/sei_blog/2014/10/thread-safety-analysis-in-c-and-c.html&quot;&gt;https://insights.sei.cmu.edu/sei_blog/2014/10/thread-safety-analysis-in-c-and-c.html&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;Thread Safety Annotations in Clang 
    &lt;ul&gt; 
     &lt;li&gt;DeLesley Hutchins&lt;/li&gt; 
     &lt;li&gt;2011 LLVM Developers&apos; Meeting; &lt;a href=&quot;https://llvm.org/devmtg/2011-11/Hutchins_ThreadSafety.pdf&quot;&gt;https://llvm.org/devmtg/2011-11/Hutchins_ThreadSafety.pdf&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=5Xx0zktqSs4&quot;&gt;https://www.youtube.com/watch?v=5Xx0zktqSs4&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>cmdpixl</title>
      <link>https://tedneward.github.io/Research/tools/cmdpixl/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/cmdpixl/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/knosmos/cmdpxl&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Written in Python; install with &lt;code&gt;pip install cmdpxl&lt;/code&gt;.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>CodeChecker</title>
      <link>https://tedneward.github.io/Research/tools/codechecker/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/codechecker/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/Ericsson/codechecker&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Compiler Explorer (Godbolt)</title>
      <link>https://tedneward.github.io/Research/tools/compilerexplorer/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/compilerexplorer/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://godbolt.org/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/compiler-explorer/compiler-explorer&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Edit code in C, C++, C#, F#, Rust, Go, D, Haskell, Swift, Pascal, ispc, Python, Java, or any of the other 30+ supported languages components, and see how that code looks after being compiled in real time.&lt;/p&gt; 
&lt;p&gt;Articles:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://android-developers.googleblog.com/2024/09/become-better-android-developer-compiler-explorer.html&quot;&gt;&quot;Tools not Rules&quot;&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Crab</title>
      <link>https://tedneward.github.io/Research/tools/crab/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/crab/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/seahorn/crab&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://github.com/seahorn/crab-llvm&quot;&gt;Crab-llvm&lt;/a&gt;: Abstract Interpretation of LLVM bitcode&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Ampt</title>
      <link>https://tedneward.github.io/Research/tools/ampt/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/ampt/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.getampt.com/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/getampt&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Ampt automatically provisions, manages, and optimizes cloud environments on AWS. They are fully-managed, highly-secure, completely isolated, and come pre-configured with all the cloud resources you need to deploy and scale modern apps.&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;// Import your favorite Node.js libraries and the Ampt SDK
import axios from &apos;axios&apos;;
import { task } from &apos;@ampt/sdk&apos;;

// Write your business logic
const fetchData = async () =&amp;gt; {
  const response = await axios.get(&apos;https://api.my-saas.com&apos;);
  // Do something with this data
}

// Create a &apos;task&apos; handler
const myTask = task(&apos;Fetch Sample Data&apos;, fetchData)

// Schedule it to run every hour
myTask.every(&quot;1 hour&quot;)
&lt;/code&gt;&lt;/pre&gt;
	</description>
    </item>
    <item>
      <title>AnythingLLM</title>
      <link>https://tedneward.github.io/Research/tools/anythingllm/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/anythingllm/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://anythingllm.com/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/Mintplex-Labs/anything-llm&quot;&gt;Source&lt;/a&gt; | &lt;a href=&quot;https://docs.anythingllm.com/&quot;&gt;Docs&lt;/a&gt; | &lt;a href=&quot;https://anythingllm.com/download&quot;&gt;Download&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;A full-stack application that enables you to turn any document, resource, or piece of content into context that any LLM can use as a reference during chatting. This application allows you to pick and choose which LLM or Vector Database you want to use as well as supporting multi-user management and permissions.&lt;/p&gt; 
&lt;p&gt;&lt;img src=&quot;https://github.com/Mintplex-Labs/anything-llm/assets/16845892/cfc5f47c-bd91-4067-986c-f3f49621a859&quot; alt=&quot;Chatting&quot;&gt;&lt;/p&gt; 
&lt;h3&gt;Product Overview&lt;/h3&gt; 
&lt;p&gt;AnythingLLM is a full-stack application where you can use commercial off-the-shelf LLMs or popular open source LLMs and vectorDB solutions to build a private ChatGPT with no compromises that you can run locally as well as host remotely and be able to chat intelligently with any documents you provide it.&lt;/p&gt; 
&lt;p&gt;AnythingLLM divides your documents into objects called &lt;code&gt;workspaces&lt;/code&gt;. A Workspace functions a lot like a thread, but with the addition of containerization of your documents. Workspaces can share documents, but they do not talk to each other so you can keep your context for each workspace clean.&lt;/p&gt; 
&lt;h2&gt;Cool features of AnythingLLM&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;🆕 &lt;a href=&quot;https://docs.anythingllm.com/mcp-compatibility/overview&quot;&gt;&lt;strong&gt;Full MCP-compatibility&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;🆕 &lt;a href=&quot;https://docs.anythingllm.com/agent-flows/overview&quot;&gt;&lt;strong&gt;No-code AI Agent builder&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;🖼️ &lt;strong&gt;Multi-modal support (both closed and open-source LLMs!)&lt;/strong&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://docs.anythingllm.com/agent/custom/introduction&quot;&gt;&lt;strong&gt;Custom AI Agents&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;👤 Multi-user instance support and permissioning &lt;em&gt;Docker version only&lt;/em&gt;&lt;/li&gt; 
 &lt;li&gt;🦾 Agents inside your workspace (browse the web, etc)&lt;/li&gt; 
 &lt;li&gt;💬 &lt;a href=&quot;https://github.com/Mintplex-Labs/anythingllm-embed/blob/main/README.md&quot;&gt;Custom Embeddable Chat widget for your website&lt;/a&gt; &lt;em&gt;Docker version only&lt;/em&gt;&lt;/li&gt; 
 &lt;li&gt;📖 Multiple document type support (PDF, TXT, DOCX, etc)&lt;/li&gt; 
 &lt;li&gt;Simple chat UI with Drag-n-Drop functionality and clear citations.&lt;/li&gt; 
 &lt;li&gt;100% Cloud deployment ready.&lt;/li&gt; 
 &lt;li&gt;Works with all popular &lt;a href=&quot;#supported-llms-embedder-models-speech-models-and-vector-databases&quot;&gt;closed and open-source LLM providers&lt;/a&gt;.&lt;/li&gt; 
 &lt;li&gt;Built-in cost &amp;amp; time-saving measures for managing very large documents compared to any other chat UI.&lt;/li&gt; 
 &lt;li&gt;Full Developer API for custom integrations!&lt;/li&gt; 
 &lt;li&gt;Much more...install and find out!&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Supported LLMs, Embedder Models, Speech models, and Vector Databases&lt;/h3&gt; 
&lt;p&gt;&lt;strong&gt;Large Language Models (LLMs):&lt;/strong&gt;&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;/server/storage/models/README.md#text-generation-llm-selection&quot;&gt;Any open-source llama.cpp compatible model&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://openai.com&quot;&gt;OpenAI&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://openai.com&quot;&gt;OpenAI (Generic)&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://azure.microsoft.com/en-us/products/ai-services/openai-service&quot;&gt;Azure OpenAI&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://aws.amazon.com/bedrock/&quot;&gt;AWS Bedrock&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.anthropic.com/&quot;&gt;Anthropic&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://build.nvidia.com/explore/discover&quot;&gt;NVIDIA NIM (chat models)&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://ai.google.dev/&quot;&gt;Google Gemini Pro&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://huggingface.co/&quot;&gt;Hugging Face (chat models)&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://ollama.ai/&quot;&gt;Ollama (chat models)&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://lmstudio.ai&quot;&gt;LM Studio (all models)&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://localai.io/&quot;&gt;LocalAI (all models)&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.together.ai/&quot;&gt;Together AI (chat models)&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://fireworks.ai/&quot;&gt;Fireworks AI (chat models)&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.perplexity.ai/&quot;&gt;Perplexity (chat models)&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://openrouter.ai/&quot;&gt;OpenRouter (chat models)&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://deepseek.com/&quot;&gt;DeepSeek (chat models)&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://mistral.ai/&quot;&gt;Mistral&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://groq.com/&quot;&gt;Groq&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://cohere.com/&quot;&gt;Cohere&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/LostRuins/koboldcpp&quot;&gt;KoboldCPP&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/BerriAI/litellm&quot;&gt;LiteLLM&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/oobabooga/text-generation-webui&quot;&gt;Text Generation Web UI&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://apipie.ai/&quot;&gt;Apipie&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://x.ai/&quot;&gt;xAI&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://z.ai/model-api&quot;&gt;Z.AI (chat models)&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://novita.ai/model-api/product/llm-api?utm_source=github_anything-llm&amp;amp;utm_medium=github_readme&amp;amp;utm_campaign=link&quot;&gt;Novita AI (chat models)&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://ppinfra.com?utm_source=github_anything-llm&quot;&gt;PPIO&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://ai.gitee.com/&quot;&gt;Gitee AI&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.moonshot.ai/&quot;&gt;Moonshot AI&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/microsoft/Foundry-Local&quot;&gt;Microsoft Foundry Local&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://api.cometapi.com/&quot;&gt;CometAPI (chat models)&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://docs.docker.com/ai/model-runner/&quot;&gt;Docker Model Runner&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://privatemode.ai/&quot;&gt;PrivateModeAI (chat models)&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://cloud.sambanova.ai/&quot;&gt;SambaNova Cloud (chat models)&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://lemonade-server.ai&quot;&gt;Lemonade by AMD&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;&lt;strong&gt;Embedder models:&lt;/strong&gt;&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;/server/storage/models/README.md&quot;&gt;AnythingLLM Native Embedder&lt;/a&gt; (default)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://openai.com&quot;&gt;OpenAI&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://azure.microsoft.com/en-us/products/ai-services/openai-service&quot;&gt;Azure OpenAI&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://localai.io/&quot;&gt;LocalAI (all)&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://ollama.ai/&quot;&gt;Ollama (all)&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://lmstudio.ai&quot;&gt;LM Studio (all)&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://cohere.com/&quot;&gt;Cohere&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;&lt;strong&gt;Audio Transcription models:&lt;/strong&gt;&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/Mintplex-Labs/anything-llm/tree/master/server/storage/models#audiovideo-transcription&quot;&gt;AnythingLLM Built-in&lt;/a&gt; (default)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://openai.com/&quot;&gt;OpenAI&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;&lt;strong&gt;TTS (text-to-speech) support:&lt;/strong&gt;&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Native Browser Built-in (default)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/rhasspy/piper&quot;&gt;PiperTTSLocal - runs in browser&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://platform.openai.com/docs/guides/text-to-speech/voice-options&quot;&gt;OpenAI TTS&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://elevenlabs.io/&quot;&gt;ElevenLabs&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;Any OpenAI Compatible TTS service.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;&lt;strong&gt;STT (speech-to-text) support:&lt;/strong&gt;&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Native Browser Built-in (default)&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;&lt;strong&gt;Vector Databases:&lt;/strong&gt;&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/lancedb/lancedb&quot;&gt;LanceDB&lt;/a&gt; (default)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/pgvector/pgvector&quot;&gt;PGVector&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.datastax.com/products/datastax-astra&quot;&gt;Astra DB&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://pinecone.io&quot;&gt;Pinecone&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://trychroma.com&quot;&gt;Chroma &amp;amp; ChromaCloud&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://weaviate.io&quot;&gt;Weaviate&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://qdrant.tech&quot;&gt;Qdrant&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://milvus.io&quot;&gt;Milvus&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://zilliz.com&quot;&gt;Zilliz&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Technical Overview&lt;/h3&gt; 
&lt;p&gt;This monorepo consists of six main sections:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;code&gt;frontend&lt;/code&gt;: A viteJS + React frontend that you can run to easily create and manage all your content the LLM can use.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;server&lt;/code&gt;: A NodeJS express server to handle all the interactions and do all the vectorDB management and LLM interactions.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;collector&lt;/code&gt;: NodeJS express server that processes and parses documents from the UI.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;docker&lt;/code&gt;: Docker instructions and build process + information for building from source.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;embed&lt;/code&gt;: Submodule for generation &amp;amp; creation of the &lt;a href=&quot;https://github.com/Mintplex-Labs/anythingllm-embed&quot;&gt;web embed widget&lt;/a&gt;.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;browser-extension&lt;/code&gt;: Submodule for the &lt;a href=&quot;https://github.com/Mintplex-Labs/anythingllm-extension&quot;&gt;chrome browser extension&lt;/a&gt;.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;🛳 Self-Hosting&lt;/h2&gt; 
&lt;p&gt;Mintplex Labs &amp;amp; the community maintain a number of deployment methods, scripts, and templates that you can use to run AnythingLLM locally. Refer to the table below to read how to deploy on your preferred environment or to automatically deploy.&lt;br&gt; | Docker | AWS | GCP | Digital Ocean | Render.com |&lt;br&gt; |----------------------------------------|----|-----|---------------|------------|&lt;br&gt; | &lt;a href=&quot;./docker/HOW_TO_USE_DOCKER.md&quot;&gt;&lt;img src=&quot;https://tedneward.github.io/Research/tools/images/deployBtns/docker.png&quot; alt=&quot;Deploy on Docker&quot;&gt;&lt;/a&gt; | &lt;a href=&quot;./cloud-deployments/aws/cloudformation/DEPLOY.md&quot;&gt;&lt;img src=&quot;https://tedneward.github.io/Research/tools/images/deployBtns/aws.png&quot; alt=&quot;Deploy on AWS&quot;&gt;&lt;/a&gt; | &lt;a href=&quot;./cloud-deployments/gcp/deployment/DEPLOY.md&quot;&gt;&lt;img src=&quot;https://deploy.cloud.run/button.svg&quot; alt=&quot;Deploy on GCP&quot;&gt;&lt;/a&gt; | &lt;a href=&quot;./cloud-deployments/digitalocean/terraform/DEPLOY.md&quot;&gt;&lt;img src=&quot;https://www.deploytodo.com/do-btn-blue.svg&quot; alt=&quot;Deploy on DigitalOcean&quot;&gt;&lt;/a&gt; | &lt;a href=&quot;https://render.com/deploy?repo=https://github.com/Mintplex-Labs/anything-llm&amp;amp;branch=render&quot;&gt;&lt;img src=&quot;https://render.com/images/deploy-to-render-button.svg&quot; alt=&quot;Deploy on Render.com&quot;&gt;&lt;/a&gt; |&lt;/p&gt; 
&lt;table&gt; 
 &lt;thead&gt; 
  &lt;tr&gt;
   &lt;th&gt; Railway &lt;/th&gt;
   &lt;th&gt; RepoCloud &lt;/th&gt;
   &lt;th&gt; Elestio &lt;/th&gt;
   &lt;th&gt; Northflank &lt;/th&gt;
  &lt;/tr&gt; 
 &lt;/thead&gt; 
 &lt;tbody&gt; 
  &lt;tr&gt;
   &lt;td&gt; &lt;a href=&quot;https://railway.app/template/HNSCS1?referralCode=WFgJkn&quot;&gt;&lt;img src=&quot;https://railway.app/button.svg&quot; alt=&quot;Deploy on Railway&quot;&gt;&lt;/a&gt; &lt;/td&gt;
   &lt;td&gt; &lt;a href=&quot;https://repocloud.io/details/?app_id=276&quot;&gt;&lt;img src=&quot;https://d16t0pc4846x52.cloudfront.net/deploylobe.svg&quot; alt=&quot;Deploy on RepoCloud&quot;&gt;&lt;/a&gt; &lt;/td&gt;
   &lt;td&gt; &lt;a href=&quot;https://elest.io/open-source/anythingllm&quot;&gt;&lt;img src=&quot;https://elest.io/images/logos/deploy-to-elestio-btn.png&quot; alt=&quot;Deploy on Elestio&quot;&gt;&lt;/a&gt; &lt;/td&gt;
   &lt;td&gt; &lt;a href=&quot;https://northflank.com/stacks/deploy-anythingllm&quot;&gt;&lt;img src=&quot;https://assets.northflank.com/deploy_to_northflank_smm_36700fb050.svg&quot; alt=&quot;Deploy on Northflank&quot;&gt;&lt;/a&gt; &lt;/td&gt;
  &lt;/tr&gt; 
 &lt;/tbody&gt; 
&lt;/table&gt; 
&lt;p&gt;&lt;a href=&quot;./BARE_METAL.md&quot;&gt;or set up a production AnythingLLM instance without Docker →&lt;/a&gt;&lt;/p&gt; 
&lt;h2&gt;How to setup for development&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;code&gt;yarn setup&lt;/code&gt; To fill in the required &lt;code&gt;.env&lt;/code&gt; files you&apos;ll need in each of the application sections (from root of repo).&lt;/li&gt; 
 &lt;li&gt;Go fill those out before proceeding. Ensure &lt;code&gt;server/.env.development&lt;/code&gt; is filled or else things won&apos;t work right.&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;yarn dev:server&lt;/code&gt; To boot the server locally (from root of repo).&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;yarn dev:frontend&lt;/code&gt; To boot the frontend locally (from root of repo).&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;yarn dev:collector&lt;/code&gt; To then run the document collector (from root of repo).&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;&lt;a href=&quot;./server/storage/documents/DOCUMENTS.md&quot;&gt;Learn about documents&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;./server/storage/vector-cache/VECTOR_CACHE.md&quot;&gt;Learn about vector caching&lt;/a&gt;&lt;/p&gt; 
&lt;h2&gt;External Apps &amp;amp; Integrations&lt;/h2&gt; 
&lt;p&gt;&lt;em&gt;These are apps that are not maintained by Mintplex Labs, but are compatible with AnythingLLM. A listing here is not an endorsement.&lt;/em&gt;&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://io.midori-ai.xyz/subsystem/anythingllm/&quot;&gt;Midori AI Subsystem Manager&lt;/a&gt; - A streamlined and efficient way to deploy AI systems using Docker container technology.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://coolify.io/docs/services/anythingllm/&quot;&gt;Coolify&lt;/a&gt; - Deploy AnythingLLM with a single click.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://gptlocalhost.com/demo/&quot;&gt;GPTLocalhost for Microsoft Word&lt;/a&gt; - A local Word Add-in for you to use AnythingLLM in Microsoft Word.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Telemetry &amp;amp; Privacy&lt;/h2&gt; 
&lt;p&gt;AnythingLLM by Mintplex Labs Inc contains a telemetry feature that collects anonymous usage information.&lt;/p&gt; 
&lt;details&gt; &lt;summary&gt;&lt;kbd&gt;More about Telemetry &amp;amp; Privacy for AnythingLLM&lt;/kbd&gt;&lt;/summary&gt; 
 &lt;h3&gt;Why?&lt;/h3&gt; 
 &lt;p&gt;We use this information to help us understand how AnythingLLM is used, to help us prioritize work on new features and bug fixes, and to help us improve AnythingLLM&apos;s performance and stability.&lt;/p&gt; 
 &lt;h3&gt;Opting out&lt;/h3&gt; 
 &lt;p&gt;Set &lt;code&gt;DISABLE_TELEMETRY&lt;/code&gt; in your server or docker .env settings to &quot;true&quot; to opt out of telemetry. You can also do this in-app by going to the sidebar &amp;gt; &lt;code&gt;Privacy&lt;/code&gt; and disabling telemetry.&lt;/p&gt; 
 &lt;h3&gt;What do you explicitly track?&lt;/h3&gt; 
 &lt;p&gt;We will only track usage details that help us make product and roadmap decisions, specifically:&lt;/p&gt; 
 &lt;ul&gt; 
  &lt;li&gt; &lt;p&gt;Type of your installation (Docker or Desktop)&lt;/p&gt; &lt;/li&gt; 
  &lt;li&gt; &lt;p&gt;When a document is added or removed. No information &lt;em&gt;about&lt;/em&gt; the document. Just that the event occurred. This gives us an idea of use.&lt;/p&gt; &lt;/li&gt; 
  &lt;li&gt; &lt;p&gt;Type of vector database in use. This helps us prioritize changes when updates arrive for that provider.&lt;/p&gt; &lt;/li&gt; 
  &lt;li&gt; &lt;p&gt;Type of LLM provider &amp;amp; model tag in use. This helps us prioritize changes when updates arrive for that provider or model, or combination thereof. eg: reasoning vs regular, multi-modal models, etc.&lt;/p&gt; &lt;/li&gt; 
  &lt;li&gt; &lt;p&gt;When a chat is sent. This is the most regular &quot;event&quot; and gives us an idea of the daily-activity of this project across all installations. Again, only the &lt;strong&gt;event&lt;/strong&gt; is sent - we have no information on the nature or content of the chat itself.&lt;/p&gt; &lt;/li&gt; 
 &lt;/ul&gt; 
 &lt;p&gt;You can verify these claims by finding all locations &lt;code&gt;Telemetry.sendTelemetry&lt;/code&gt; is called. Additionally these events are written to the output log so you can also see the specific data which was sent - if enabled. &lt;strong&gt;No IP or other identifying information is collected&lt;/strong&gt;. The Telemetry provider is &lt;a href=&quot;https://posthog.com/&quot;&gt;PostHog&lt;/a&gt; - an open-source telemetry collection service.&lt;/p&gt; 
 &lt;p&gt;We take privacy very seriously, and we hope you understand that we want to learn how our tool is used, without using annoying popup surveys, so we can build something worth using. The anonymous data is &lt;em&gt;never&lt;/em&gt; shared with third parties, ever.&lt;/p&gt; 
 &lt;p&gt;[View all telemetry events in source code](&lt;a href=&quot;https://github.com/search?q=repo%3AMintplex-Labs%2Fanything-llm%20.sendTelemetry(&amp;amp;type=code)&quot;&gt;https://github.com/search?q=repo%3AMintplex-Labs%2Fanything-llm%20.sendTelemetry(&amp;amp;type=code)&lt;/a&gt;&lt;/p&gt; 
&lt;/details&gt; 
&lt;h2&gt;👋 Contributing&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;./CONTRIBUTING.md&quot;&gt;Contributing to AnythingLLM&lt;/a&gt; - How to contribute to AnythingLLM.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;💖 Sponsors&lt;/h2&gt; 
&lt;h3&gt;Premium Sponsors&lt;/h3&gt; &lt;!-- premium-sponsors (reserved for $100/mth sponsors who request to be called out here and/or are non-private sponsors) --&gt; &lt;a href=&quot;https://www.dcsdigital.co.uk&quot; target=&quot;_blank&quot;&gt; &lt;img src=&quot;https://a8cforagenciesportfolio.wordpress.com/wp-content/uploads/2024/08/logo-image-232621379.png&quot; height=&quot;100px&quot; alt=&quot;User avatar: DCS DIGITAL&quot;&gt; &lt;/a&gt; &lt;!-- premium-sponsors --&gt; 
&lt;h3&gt;All Sponsors&lt;/h3&gt; &lt;!-- all-sponsors --&gt;&lt;a href=&quot;https://github.com/jaschadub&quot;&gt;&lt;img src=&quot;https://github.com/jaschadub.png&quot; width=&quot;60px&quot; alt=&quot;User avatar: Jascha&quot;&gt;&lt;/a&gt;&lt;a href=&quot;https://github.com/KickingAss2024&quot;&gt;&lt;img src=&quot;https://github.com/KickingAss2024.png&quot; width=&quot;60px&quot; alt=&quot;User avatar: KickAss&quot;&gt;&lt;/a&gt;&lt;a href=&quot;https://github.com/ShadowArcanist&quot;&gt;&lt;img src=&quot;https://github.com/ShadowArcanist.png&quot; width=&quot;60px&quot; alt=&quot;User avatar: ShadowArcanist&quot;&gt;&lt;/a&gt;&lt;a href=&quot;https://github.com/AtlasVIA&quot;&gt;&lt;img src=&quot;https://github.com/AtlasVIA.png&quot; width=&quot;60px&quot; alt=&quot;User avatar: Atlas&quot;&gt;&lt;/a&gt;&lt;a href=&quot;https://github.com/cope&quot;&gt;&lt;img src=&quot;https://github.com/cope.png&quot; width=&quot;60px&quot; alt=&quot;User avatar: Predrag Stojadinović&quot;&gt;&lt;/a&gt;&lt;a href=&quot;https://github.com/DiegoSpinola&quot;&gt;&lt;img src=&quot;https://github.com/DiegoSpinola.png&quot; width=&quot;60px&quot; alt=&quot;User avatar: Diego Spinola&quot;&gt;&lt;/a&gt;&lt;a href=&quot;https://github.com/PortlandKyGuy&quot;&gt;&lt;img src=&quot;https://github.com/PortlandKyGuy.png&quot; width=&quot;60px&quot; alt=&quot;User avatar: Kyle&quot;&gt;&lt;/a&gt;&lt;a href=&quot;https://github.com/peperunas&quot;&gt;&lt;img src=&quot;https://github.com/peperunas.png&quot; width=&quot;60px&quot; alt=&quot;User avatar: Giulio De Pasquale&quot;&gt;&lt;/a&gt;&lt;a href=&quot;https://github.com/jasoncdavis0&quot;&gt;&lt;img src=&quot;https://github.com/jasoncdavis0.png&quot; width=&quot;60px&quot; alt=&quot;User avatar: &quot;&gt;&lt;/a&gt;&lt;a href=&quot;https://github.com/macstadium&quot;&gt;&lt;img src=&quot;https://github.com/macstadium.png&quot; width=&quot;60px&quot; alt=&quot;User avatar: MacStadium&quot;&gt;&lt;/a&gt;&lt;a href=&quot;https://github.com/armlynobinguar&quot;&gt;&lt;img src=&quot;https://github.com/armlynobinguar.png&quot; width=&quot;60px&quot; alt=&quot;User avatar: &quot;&gt;&lt;/a&gt;&lt;a href=&quot;https://github.com/MikeHago&quot;&gt;&lt;img src=&quot;https://github.com/MikeHago.png&quot; width=&quot;60px&quot; alt=&quot;User avatar: &quot;&gt;&lt;/a&gt;&lt;a href=&quot;https://github.com/maaisde&quot;&gt;&lt;img src=&quot;https://github.com/maaisde.png&quot; width=&quot;60px&quot; alt=&quot;User avatar: &quot;&gt;&lt;/a&gt;&lt;a href=&quot;https://github.com/mhollier117&quot;&gt;&lt;img src=&quot;https://github.com/mhollier117.png&quot; width=&quot;60px&quot; alt=&quot;User avatar: &quot;&gt;&lt;/a&gt;&lt;a href=&quot;https://github.com/pleabargain&quot;&gt;&lt;img src=&quot;https://github.com/pleabargain.png&quot; width=&quot;60px&quot; alt=&quot;User avatar: Dennis&quot;&gt;&lt;/a&gt;&lt;a href=&quot;https://github.com/broichan&quot;&gt;&lt;img src=&quot;https://github.com/broichan.png&quot; width=&quot;60px&quot; alt=&quot;User avatar: Michael Hamilton, Ph.D.&quot;&gt;&lt;/a&gt;&lt;a href=&quot;https://github.com/azim-charaniya&quot;&gt;&lt;img src=&quot;https://github.com/azim-charaniya.png&quot; width=&quot;60px&quot; alt=&quot;User avatar: &quot;&gt;&lt;/a&gt;&lt;a href=&quot;https://github.com/gabriellemon&quot;&gt;&lt;img src=&quot;https://github.com/gabriellemon.png&quot; width=&quot;60px&quot; alt=&quot;User avatar: TernaryLabs&quot;&gt;&lt;/a&gt;&lt;a href=&quot;https://github.com/CelaDaniel&quot;&gt;&lt;img src=&quot;https://github.com/CelaDaniel.png&quot; width=&quot;60px&quot; alt=&quot;User avatar: Daniel Cela&quot;&gt;&lt;/a&gt;&lt;a href=&quot;https://github.com/altrsadmin&quot;&gt;&lt;img src=&quot;https://github.com/altrsadmin.png&quot; width=&quot;60px&quot; alt=&quot;User avatar: Alesso&quot;&gt;&lt;/a&gt;&lt;a href=&quot;https://github.com/bitjungle&quot;&gt;&lt;img src=&quot;https://github.com/bitjungle.png&quot; width=&quot;60px&quot; alt=&quot;User avatar: Rune Mathisen&quot;&gt;&lt;/a&gt;&lt;a href=&quot;https://github.com/pcrossleyAC&quot;&gt;&lt;img src=&quot;https://github.com/pcrossleyAC.png&quot; width=&quot;60px&quot; alt=&quot;User avatar: &quot;&gt;&lt;/a&gt;&lt;a href=&quot;https://github.com/saroj-pattnaik&quot;&gt;&lt;img src=&quot;https://github.com/saroj-pattnaik.png&quot; width=&quot;60px&quot; alt=&quot;User avatar: &quot;&gt;&lt;/a&gt;&lt;a href=&quot;https://github.com/techmedic5&quot;&gt;&lt;img src=&quot;https://github.com/techmedic5.png&quot; width=&quot;60px&quot; alt=&quot;User avatar: Alan&quot;&gt;&lt;/a&gt;&lt;a href=&quot;https://github.com/ddocta&quot;&gt;&lt;img src=&quot;https://github.com/ddocta.png&quot; width=&quot;60px&quot; alt=&quot;User avatar: Damien Peters&quot;&gt;&lt;/a&gt;&lt;a href=&quot;https://github.com/dcsdigital&quot;&gt;&lt;img src=&quot;https://github.com/dcsdigital.png&quot; width=&quot;60px&quot; alt=&quot;User avatar: DCS Digital&quot;&gt;&lt;/a&gt;&lt;a href=&quot;https://github.com/pm7y&quot;&gt;&lt;img src=&quot;https://github.com/pm7y.png&quot; width=&quot;60px&quot; alt=&quot;User avatar: Paul Mcilreavy&quot;&gt;&lt;/a&gt;&lt;a href=&quot;https://github.com/tilwolf&quot;&gt;&lt;img src=&quot;https://github.com/tilwolf.png&quot; width=&quot;60px&quot; alt=&quot;User avatar: Til Wolf&quot;&gt;&lt;/a&gt;&lt;a href=&quot;https://github.com/ozzyoss77&quot;&gt;&lt;img src=&quot;https://github.com/ozzyoss77.png&quot; width=&quot;60px&quot; alt=&quot;User avatar: Leopoldo Crhistian Riverin Gomez&quot;&gt;&lt;/a&gt;&lt;a href=&quot;https://github.com/AlphaEcho11&quot;&gt;&lt;img src=&quot;https://github.com/AlphaEcho11.png&quot; width=&quot;60px&quot; alt=&quot;User avatar: AJEsau&quot;&gt;&lt;/a&gt;&lt;a href=&quot;https://github.com/svanomm&quot;&gt;&lt;img src=&quot;https://github.com/svanomm.png&quot; width=&quot;60px&quot; alt=&quot;User avatar: Steven VanOmmeren&quot;&gt;&lt;/a&gt;&lt;a href=&quot;https://github.com/socketbox&quot;&gt;&lt;img src=&quot;https://github.com/socketbox.png&quot; width=&quot;60px&quot; alt=&quot;User avatar: Casey Boettcher&quot;&gt;&lt;/a&gt;&lt;a href=&quot;https://github.com/zebbern&quot;&gt;&lt;img src=&quot;https://github.com/zebbern.png&quot; width=&quot;60px&quot; alt=&quot;User avatar: &quot;&gt;&lt;/a&gt;&lt;a href=&quot;https://github.com/avineetbespin&quot;&gt;&lt;img src=&quot;https://github.com/avineetbespin.png&quot; width=&quot;60px&quot; alt=&quot;User avatar: Avineet&quot;&gt;&lt;/a&gt;&lt;a href=&quot;https://github.com/invictus-1&quot;&gt;&lt;img src=&quot;https://github.com/invictus-1.png&quot; width=&quot;60px&quot; alt=&quot;User avatar: Chris&quot;&gt;&lt;/a&gt;&lt;a href=&quot;https://github.com/mirbyte&quot;&gt;&lt;img src=&quot;https://github.com/mirbyte.png&quot; width=&quot;60px&quot; alt=&quot;User avatar: mirko&quot;&gt;&lt;/a&gt;&lt;a href=&quot;https://github.com/bisonbet&quot;&gt;&lt;img src=&quot;https://github.com/bisonbet.png&quot; width=&quot;60px&quot; alt=&quot;User avatar: Tim Champ&quot;&gt;&lt;/a&gt;&lt;a href=&quot;https://github.com/Sinkingdev&quot;&gt;&lt;img src=&quot;https://github.com/Sinkingdev.png&quot; width=&quot;60px&quot; alt=&quot;User avatar: Peter Mathisen&quot;&gt;&lt;/a&gt;&lt;a href=&quot;https://github.com/Ed-STEM&quot;&gt;&lt;img src=&quot;https://github.com/Ed-STEM.png&quot; width=&quot;60px&quot; alt=&quot;User avatar: Ed di Girolamo&quot;&gt;&lt;/a&gt;&lt;a href=&quot;https://github.com/milkowski&quot;&gt;&lt;img src=&quot;https://github.com/milkowski.png&quot; width=&quot;60px&quot; alt=&quot;User avatar: Wojciech Miłkowski&quot;&gt;&lt;/a&gt;&lt;a href=&quot;https://github.com/ADS-Fund&quot;&gt;&lt;img src=&quot;https://github.com/ADS-Fund.png&quot; width=&quot;60px&quot; alt=&quot;User avatar: ADS Fund&quot;&gt;&lt;/a&gt;&lt;a href=&quot;https://github.com/arc46-io&quot;&gt;&lt;img src=&quot;https://github.com/arc46-io.png&quot; width=&quot;60px&quot; alt=&quot;User avatar: arc46 GmbH&quot;&gt;&lt;/a&gt;&lt;a href=&quot;https://github.com/liyin2015&quot;&gt;&lt;img src=&quot;https://github.com/liyin2015.png&quot; width=&quot;60px&quot; alt=&quot;User avatar: Li Yin&quot;&gt;&lt;/a&gt;&lt;a href=&quot;https://github.com/SylphAI-Inc&quot;&gt;&lt;img src=&quot;https://github.com/SylphAI-Inc.png&quot; width=&quot;60px&quot; alt=&quot;User avatar: SylphAI&quot;&gt;&lt;/a&gt;&lt;!-- all-sponsors --&gt; 
&lt;h2&gt;🌟 Contributors&lt;/h2&gt; 
&lt;p&gt;&lt;a href=&quot;https://github.com/mintplex-labs/anything-llm/graphs/contributors&quot;&gt;&lt;img src=&quot;https://contrib.rocks/image?repo=mintplex-labs/anything-llm&quot; alt=&quot;anythingllm contributors&quot;&gt;&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://star-history.com/#mintplex-labs/anything-llm&amp;amp;Date&quot;&gt;&lt;img src=&quot;https://api.star-history.com/svg?repos=mintplex-labs/anything-llm&amp;amp;type=Timeline&quot; alt=&quot;Star History Chart&quot;&gt;&lt;/a&gt;&lt;/p&gt; 
&lt;h2&gt;🔗 More Products&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;strong&gt;&lt;a href=&quot;https://github.com/mintplex-labs/vector-admin&quot;&gt;VectorAdmin&lt;/a&gt;:&lt;/strong&gt; An all-in-one GUI &amp;amp; tool-suite for managing vector databases.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;&lt;a href=&quot;https://github.com/Mintplex-Labs/openai-assistant-swarm&quot;&gt;OpenAI Assistant Swarm&lt;/a&gt;:&lt;/strong&gt; Turn your entire library of OpenAI assistants into one single army commanded from a single agent.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;div align=&quot;right&quot;&gt; 
 &lt;p&gt;&lt;a href=&quot;#readme-top&quot;&gt;![][back-to-top]&lt;/a&gt;&lt;/p&gt; 
&lt;/div&gt; 
&lt;hr&gt; 
&lt;p&gt;Copyright © 2026 &lt;a href=&quot;https://github.com/mintplex-labs&quot;&gt;Mintplex Labs&lt;/a&gt;. &lt;br&gt;&lt;br&gt; This project is &lt;a href=&quot;./LICENSE&quot;&gt;MIT&lt;/a&gt; licensed.&lt;/p&gt; &lt;!-- LINK GROUP --&gt;
	</description>
    </item>
    <item>
      <title>Augur</title>
      <link>https://tedneward.github.io/Research/tools/augur/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/augur/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/chaoss/augur&quot;&gt;Source&lt;/a&gt; | &lt;a href=&quot;https://oss-augur.readthedocs.io/en/main/&quot;&gt;Docs&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Features:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;focus on data from GitHub and GitLab platforms, which can scale to tens of thousands of repositories, and use Augur’s relational database as a data engineering tool to write custom queries that explore complex or unanticipated questions while performing in-depth research.&lt;/li&gt; 
 &lt;li&gt;explore data about compliance, security, dependencies, and related software topics to better understand potential risks associated with an open source project in addition to using visualizations to learn about community health.&lt;/li&gt; 
 &lt;li&gt;Data is collected incrementally and includes all messages and commits associated with issues, pull requests, and pull request reviews, including historical data. This high velocity collection has been tested for up to 100,000 repositories, enabling assessment of diverse open source software ecosystems.&lt;/li&gt; 
 &lt;li&gt;Collection and analysis goes beyond the counting of activities to include license coverage and license type information, COCOMO based software complexity and cost of replacement data by project and file, software dependency scanning, measurement of dependency LibYears, and time series persistent OpenSSF Scorecard information.&lt;/li&gt; 
 &lt;li&gt;Understanding of community health is extended through automatically detecting unusual activity by performing computational linguistics machine learning analysis and contribution anomaly detection.&lt;/li&gt; 
 &lt;li&gt;Users can explore complex or unanticipated questions while performing in-depth research using Augur’s relational database or API to write custom queries.&lt;/li&gt; 
 &lt;li&gt;Augur includes data visualizations through an extensible frontend built using tools familiar to data scientists (e.g., Dash and Plotly) upon which 8Knot is developed.&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Bazel</title>
      <link>https://tedneward.github.io/Research/tools/bazel/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/bazel/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://bazel.build/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/bazelbuild/bazel&quot;&gt;Github&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://github.com/jin/awesome-bazel&quot;&gt;Awesome Bazel&lt;/a&gt;: A curated list of Bazel rules, tooling and resources.&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://github.com/spotify/bazel-tools&quot;&gt;bazel-tools&lt;/a&gt;: Tools for dealing with very large Bazel-managed repositories&lt;/p&gt; 
&lt;h4&gt;Links/reading&lt;/h4&gt; 
&lt;p&gt;Bazel How to build at Google scale?&lt;br&gt; - FOSDEM 2017; Klaus Aehlig&lt;br&gt; - &lt;a href=&quot;https://archive.fosdem.org/2017/schedule/event/bazel/&quot;&gt;https://archive.fosdem.org/2017/schedule/event/bazel/&lt;/a&gt;&lt;br&gt; - &lt;a href=&quot;https://www.youtube.com/watch?v=lOUwu0myF8M&quot;&gt;https://www.youtube.com/watch?v=lOUwu0myF8M&lt;/a&gt;&lt;br&gt; External C++ dependency management in Bazel&lt;br&gt; - &lt;a href=&quot;https://medium.com/@htuch/external-c-dependency-management-in-bazel-dd37477422f5&quot;&gt;https://medium.com/@htuch/external-c-dependency-management-in-bazel-dd37477422f5&lt;/a&gt;&lt;br&gt; Faster Bazel builds with remote caching: a benchmark&lt;br&gt; - &lt;a href=&quot;https://nicolovaligi.com/faster-bazel-remote-caching-benchmark.html&quot;&gt;https://nicolovaligi.com/faster-bazel-remote-caching-benchmark.html&lt;/a&gt;&lt;br&gt; Your Build in a Datacenter: Remote Caching and Execution in Bazel&lt;br&gt; - FOSDEM 2018; Jakob Buchgraber&lt;br&gt; - &lt;a href=&quot;https://www.youtube.com/watch?v=PrTun05W5g4&quot;&gt;https://www.youtube.com/watch?v=PrTun05W5g4&lt;/a&gt;&lt;br&gt; - &lt;a href=&quot;https://fosdem.org/2018/schedule/event/datacenter_build/&quot;&gt;https://fosdem.org/2018/schedule/event/datacenter_build/&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>binwalk</title>
      <link>https://tedneward.github.io/Research/tools/binwalk/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/binwalk/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/ReFirmLabs/binwalk&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>BookStack</title>
      <link>https://tedneward.github.io/Research/tools/bookstack/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/bookstack/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.bookstackapp.com/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/BookStackApp/BookStack&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Most who use BookStack enjoy its intuitive philosophy of a shelf being a generic subject or category, a book being a specific part of that shelf, and chapters within the book containing the most specific information.&lt;/p&gt; 
&lt;p&gt;Pros&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Lots of people consider BookStack the &quot;gold standard&quot; of wikis&lt;/li&gt; 
 &lt;li&gt;Divide notes into logical structure, which may not be applicable to all notes.&lt;/li&gt; 
 &lt;li&gt;Example usage: Shelf for servers, book for hardware, and chapters for specific servers.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;Cons&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Could be spending a lot of time figuring out the best way for information to fit this structure.&lt;/li&gt; 
 &lt;li&gt;By default allowable upload file sizes are quite small. Instructions on how to modify this can be found in the documentation.&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Bottles</title>
      <link>https://tedneward.github.io/Research/tools/bottles/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/bottles/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://usebottles.com/&quot;&gt;Website&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Windows prefixes are environments where it is possible to run Windows software using runners. Runners are compatibility layers capable of running Windows applications on Linux systems. In Bottles we call the these environments, bottles.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>buku</title>
      <link>https://tedneward.github.io/Research/tools/buku/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/buku/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/jarun/buku&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Canopy</title>
      <link>https://tedneward.github.io/Research/tools/canopy/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/canopy/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://canopy.jcoglan.com/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/jcoglan/canopy&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Canopy can generate parsers in Java, JavaScript, Python, Ruby&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Checkstyle</title>
      <link>https://tedneward.github.io/Research/tools/checkstyle/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/checkstyle/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://checkstyle.sourceforge.io/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/checkstyle/checkstyle&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>CloudFoundry</title>
      <link>https://tedneward.github.io/Research/tools/cloudfoundry/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/cloudfoundry/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.cloudfoundry.org/&quot;&gt;Website&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Co</title>
      <link>https://tedneward.github.io/Research/tools/co/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/co/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://abhinavsarkar.net/posts/implementing-co-1/&quot;&gt;Part 1&lt;/a&gt; | &lt;a href=&quot;https://abhinavsarkar.net/posts/implementing-co-2/&quot;&gt;Part 2&lt;/a&gt; | &lt;a href=&quot;https://abhinavsarkar.net/posts/implementing-co-3/&quot;&gt;Part 3&lt;/a&gt; | &lt;a href=&quot;https://abhinavsarkar.net/posts/implementing-co-4/&quot;&gt;Part 4&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Co has these basic features that are found in many programming languages:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Dynamic and strong typing.&lt;/li&gt; 
 &lt;li&gt;Null, boolean, string and integer literals, and values.&lt;/li&gt; 
 &lt;li&gt;Addition, subtraction, multiplication and integer division arithmetic operations.&lt;/li&gt; 
 &lt;li&gt;String concatenation operation.&lt;/li&gt; 
 &lt;li&gt;Equality and inequality checks on booleans, strings and numbers.&lt;/li&gt; 
 &lt;li&gt;Less-than and greater-than comparison operations on numbers.&lt;/li&gt; 
 &lt;li&gt;Variable declarations, usage and assignments.&lt;/li&gt; 
 &lt;li&gt;if and while statements.&lt;/li&gt; 
 &lt;li&gt;Function declarations and calls, with support for recursion.&lt;/li&gt; 
 &lt;li&gt;First class functions and anonymous functions.&lt;/li&gt; 
 &lt;li&gt;Mutable closures.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;It also has these special features:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;yield statement to yield the current thread of computation (ToC).&lt;/li&gt; 
 &lt;li&gt;spawn statement to start a new ToC.&lt;/li&gt; 
 &lt;li&gt;First class channels with operators to send and receive values over them.&lt;/li&gt; 
 &lt;li&gt;sleep function to sleep the current ToC for a given number of milliseconds.&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>CodeQL</title>
      <link>https://tedneward.github.io/Research/tools/codeql/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/codeql/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://codeql.github.com/docs/&quot;&gt;Docs&lt;/a&gt;&lt;/p&gt; 
&lt;h2&gt;Reading&lt;/h2&gt; 
&lt;h3&gt;Articles&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://book.martiandefense.org/notes/product-security-engineering/sast-sca/codeql-for-beginners&quot;&gt;CodeQL for Beginners&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.javaadvent.com/2021/12/finding-your-presents-using-codeql.html&quot;&gt;Finding your presents using CodeQL&lt;/a&gt;: &quot;When I was a kid, I could not contain my excitement about Christmas. Meeting my extended family, having a great dinner with lots of laughter and joy. There was a tradition for the kids to search for Christmas presents in the living room. Be it behind the couch, between the Christmas tree branches, or way up on the shelf. Given how much I enjoyed the journey of finding the presents each year, my parents tried to make it a bit more interesting. Sometimes using wrapping paper that matched the wallpaper, sometimes by hiding it inside the chimney. This game reached a point that the stashes were so good that I could not find all the presents anymore and at one point, even my parents forgot where they put all the gifts. Long story short, I found the present eventually…3 months later, tucked away in the bookshelf, wrapped in the book cover. Fast forward to today; let’s get some help using technology to find our presents this year. This year, let’s turn the complexity up a notch and use a whole codebase as a searching ground for our presents. The good thing is that we can hide a lot more gifts in our codebase due to its inherent complexity. We have a lot of actors (our team) that can hide presents – either accidentally or even deliberately 🤫. For the sake of simplicity, let’s assume we’re hosting our code on GitHub, as this offers us an easy way to set up some of the other things we need in our journey to find all the presents.&quot;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Papers&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://codeql.github.com/publications/algebraic-data-types.pdf&quot;&gt;Algebraic Data Types for Object-oriented Datalog&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Getting Started and Guides (along side the &lt;a href=&quot;https://codeql.github.com/docs/&quot;&gt;official docs&lt;/a&gt;)&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://codeql-learning-catalog.github.com/&quot;&gt;CodeQL Learning Catalog&lt;/a&gt; - The CodeQL Learning Catalog is a resource dedicated providing detailed CodeQL learning resources. The Catalog contains workshops, recordings, and learning paths for improving your knowledge and skill in using CodeQL.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://securitylab.github.com/get-involved/&quot;&gt;GitHub Security Lab&lt;/a&gt; - From trying out CodeQL to secure your own code to collecting bug bounties by securing others&apos;, here are a few ways we can keep the world&apos;s software safe, together.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/trailofbits/testing-handbook&quot;&gt;testing-handbook&lt;/a&gt; - The &lt;a href=&quot;https://appsec.guide/docs/static-analysis/codeql/&quot;&gt;Trail of Bits Testing Handbook&lt;/a&gt; is a resource that guides developers and security professionals in configuring, optimizing, and automating many of the static and dynamic analysis tools used at Trail of Bits.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://gist.github.com/bthomas2622/e520926b88ebb93e79b30f7f32ed4849&quot;&gt;Custom Configuration File&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Documentation&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://codeql.github.com/docs/writing-codeql-queries&quot;&gt;How to write CodeQL Queries&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://codeql.github.com/docs/codeql-language-guides&quot;&gt;CodeQL Language Guide&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://codeql.github.com/docs/ql-language-reference&quot;&gt;QL Language reference&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://codeql.github.com/codeql-standard-libraries&quot;&gt;CodeQL Standard Libraries&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://codeql.github.com/codeql-query-help&quot;&gt;CodeQL Query Help&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://codeql.github.com/docs/&quot;&gt;Full CodeQL Documentation&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Blogs&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.blog/developer-skills/github/codeql-zero-to-hero-part-1-the-fundamentals-of-static-analysis-for-vulnerability-research/&quot;&gt;GitHub - CodeQL zero to hero series&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.blog/engineering/how-github-uses-codeql-to-secure-github/&quot;&gt;GitHub - How GitHub uses CodeQL to secure GitHub&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;YouTube learning&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/live/y_-pIbsr7jc?&amp;amp;t=310&quot;&gt;Find bugs in your code with CodeQL&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=pYzfGaLTqC0&quot;&gt;Finding security vulnerabilities in JavaScript with CodeQL&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=nvCd0Ee4FgE&quot;&gt;Finding security vulnerabilities in Java with CodeQL&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=eAjecQrfv3o&amp;amp;t=98s&quot;&gt;Finding security vulnerabilities in C/C++ with CodeQL&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=-bJ2Ioi7Icg&amp;amp;t=8s&quot;&gt;CodeQL as an Audit Oracle&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Software&lt;/h2&gt; 
&lt;h3&gt;Installers&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/github/gh-codeql&quot;&gt;GH CodeQL&lt;/a&gt; - GitHub CLI Extension for CodeQL to help manage installation&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/advanced-security/grab_ql&quot;&gt;grab_ql&lt;/a&gt; - Grab some/all of CodeQL CLI binary, QL library, VSCode starter workspace, VSCode and VSCode QL extension&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/david-wiggs/codeql-anywhere&quot;&gt;codeql-anywhere&lt;/a&gt; - Put the power of CodeQL in your pocket, take it with you to any CI 🚀&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/GitHubSecurityLab/codeql-jupyter-kernel&quot;&gt;codeql-jupyter-kernel&lt;/a&gt; - Jupyter Kernel for CodeQL&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/Homebrew/homebrew-cask/blob/master/Casks/c/codeql.rb&quot;&gt;homebrew-cask&lt;/a&gt; - Homebrew cask to install the CodeQL CLI &lt;code&gt;brew install --cask codeql&lt;/code&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;CLI Tooling&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/github/gh-codeql&quot;&gt;gh-codeql&lt;/a&gt; - GitHub CLI extension for working with CodeQL&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/advanced-security/gh-codeql-scan&quot;&gt;gh-codeql-scan&lt;/a&gt; - GH CLI CodeQL Scan Extension&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/GitHubSecurityLab/gh-mrva&quot;&gt;gh-mrva&lt;/a&gt; - Multi-repo variant analysis CLI support&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Customizations&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/advanced-security/codeql-summarize&quot;&gt;codeql-summarize&lt;/a&gt; - CodeQL Summary Generator to generate Models as Data (MaD) from CodeQL databases.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;&lt;a href=&quot;https://docs.github.com/en/code-security/codeql-cli/using-the-codeql-cli/publishing-and-using-codeql-packs&quot;&gt;Packs&lt;/a&gt;&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/orgs/codeql/packages&quot;&gt;GitHub-maintained packages&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/GitHubSecurityLab/CodeQL-Community-Packs&quot;&gt;GitHub Security Lab community&lt;/a&gt; - Collection of community-driven CodeQL query, library and extension &lt;a href=&quot;https://github.com/orgs/githubsecuritylab/packages&quot;&gt;packages&lt;/a&gt;. Blog: &lt;a href=&quot;https://github.blog/security/vulnerability-research/announcing-codeql-community-packs/&quot;&gt;Announcing CodeQL Community Packs&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;Trail of Bits - &lt;a href=&quot;https://github.com/trailofbits/codeql-queries&quot;&gt;codeql-queries&lt;/a&gt; - CodeQL queries and &lt;a href=&quot;https://github.com/orgs/trailofbits/packages?ecosystem=all&amp;amp;q=repo%3Atrailofbits%2Fcodeql-queries&quot;&gt;packs&lt;/a&gt; developed by Trail of Bits&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/github/codeql-coding-standards&quot;&gt;GitHub codeql-coding-standards&lt;/a&gt; - This repository contains CodeQL queries and libraries which support various Coding Standards. (AUTOSAR C++, CERT-C++,CERT C, MISRA C)&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Tooling (Bundles + Packs)&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/advanced-security/codeql-bundle-action&quot;&gt;codeql-bundle-action&lt;/a&gt; - Action to retrofit a CodeQL bundle with additional queries, libraries, and customizations&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/rvermeulen/codeql-bundle&quot;&gt;codeql-bunldle&lt;/a&gt; - CLI to build a custom CodeQL bundle&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/zbazztian/gh-tailor&quot;&gt;gh-tailor&lt;/a&gt; - A tool for customizing CodeQL packs.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Libraries&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/advanced-security/codeql-qtil&quot;&gt;codeql-qtil&lt;/a&gt; - A library with a wide variety of handy CodeQL utilities, from simple to complex.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Queries/Bundles&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.microsoft.com/en-us/security/blog/2021/02/25/microsoft-open-sources-codeql-queries-used-to-hunt-for-solorigate-activity/&quot;&gt;Microsoft solorigate queries&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/advanced-security/codeql-coding-standards-bundle-releases&quot;&gt;GitHub codeql-coding-standards-bundle-releases&lt;/a&gt; - CodeQL bundles containing the CodeQL Coding Standards queries&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Query Suites&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/zbazztian/only-critical-queries/blob/main/.github/critical-alternative.qls&quot;&gt;Only Critical Queries sample .qls&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/securingdev/codeql-query-suites/blob/main/.github/configurations/owasp-top-10.qls&quot;&gt;OWASP Top 10 CWE Only .qls&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/github/codeql/actions/workflows/query-list.yml?query=branch%3Acodeql-cli%2Flatest&quot;&gt;CodeQL per Suite Query list&lt;/a&gt; - download the attached &lt;code&gt;code-scanning-query-list.csv&lt;/code&gt; artifact.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Troubleshooting&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/advanced-security/advanced-security-material/tree/main/troubleshooting/codeql-builds&quot;&gt;CodeQL Build Failure Troubleshooting&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/advanced-security/advanced-security-material/blob/main/troubleshooting/sarif-upload/troubleshooting.md&quot;&gt;GitHub SARIF Upload Troubleshooting&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/github/codeql-coding-standards/blob/main/docs/user_manual.md#hazard-and-risk-analysis&quot;&gt;CodeQL Coding Standards - Hazard and risk analysis&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Monorepo Actions Samples&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/dassencio/parallel-code-scanning&quot;&gt;parallel-code-scanning&lt;/a&gt; - An example of a GitHub Actions workflow showing how code scanning with CodeQL can be parallelized on monorepos.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/thedave42/multi-lang-monorepo&quot;&gt;multi-lang-monorepo&lt;/a&gt; - A repo that demonstrates using an Actions workflow Job matrix to run parallel CodeQL scans on applications in a monorepo.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/advanced-security/sample-javascript-monorepo&quot;&gt;sample-javascript-monorepo&lt;/a&gt; - Detached fork of babel/babel to use as a TypeScript monorepo sample with 150+ packages using the &lt;a href=&quot;https://github.com/advanced-security/monorepo-code-scanning-action&quot;&gt;monorepo-code-scanning-action&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Actions Helpers&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/advanced-security/set-codeql-language-matrix&quot;&gt;set-codeql-language-matrix&lt;/a&gt; - Automatically set the CodeQL matrix job using the languages in your repository.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/advanced-security/filter-sarif&quot;&gt;filter-sarif&lt;/a&gt; - GitHub Action for filtering Code Scanning alerts by path and id&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/advanced-security/sarif-toolkit/blob/main/submodules/&quot;&gt;sarif-toolkit&lt;/a&gt; - Allows users to split up SARIF files that use submodules into multiple SARIF files that are then published to there appropriate repositories.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/zbazztian/codeql-debug&quot;&gt;codeql-debug&lt;/a&gt; - Add this action to an existing CodeQL analysis workflow to generate an html report&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/advanced-security/dismiss-alerts&quot;&gt;dismiss-alerts&lt;/a&gt; - Dismisses GitHub Code Scanning alerts from &lt;code&gt;//codeql[supress reason]&lt;/code&gt; style comments on the default branch&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/advanced-security/adjust-cvss&quot;&gt;adjust-cvss&lt;/a&gt; - Adjust the severity of the CVSS score assigned to a result in SARIF file&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/advanced-security/codeql-sarif-security-standard-annotator&quot;&gt;codeql-sarif-security-standard-annotator&lt;/a&gt; - Add an &lt;code&gt;owasp-top10-2021&lt;/code&gt; tag to relevant results&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/advanced-security/delombok&quot;&gt;delombok&lt;/a&gt; - Delombok Java Code for analysis with Code Scanning (deprecated - now &lt;a href=&quot;https://github.blog/changelog/2023-09-01-code-scanning-with-codeql-improves-support-for-java-codebases-that-use-project-lombok/&quot;&gt;supported by CodeQL&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/MichaelCurrin/badge-generator&quot;&gt;badge-generator&lt;/a&gt; - &lt;a href=&quot;https://github.com/MichaelCurrin/badge-generator/actions?query=workflow%3ACodeQL&quot; title=&quot;Code quality workflow status&quot;&gt;&lt;img src=&quot;https://github.com/MichaelCurrin/badge-generator/workflows/CodeQL/badge.svg&quot; alt=&quot;CodeQL&quot;&gt;&lt;/a&gt; Magically generate Markdown badges for your docs 🛡️ 🦡 🧙&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/advanced-security/monorepo-code-scanning-action&quot;&gt;monorepo-code-scanning-action&lt;/a&gt; - Focus SAST scans (with CodeQL) on just the changed parts of your monorepo, split up as you define&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/advanced-security/codeql-extractor-action&quot;&gt;codeql-extractor-action&lt;/a&gt; - An Action that allows you to specify a CodeQL extractor to be used in your workflows as an author of an Extractor.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;SARIF&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://marketplace.visualstudio.com/items?itemName=WDGIS.MicrosoftSarifViewer&quot;&gt;Visual Studio SARIF Viewer&lt;/a&gt; - Visual Studio Static Analysis Results Interchange Format (SARIF) log file viewer&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://marketplace.visualstudio.com/items?itemName=MS-SarifVSCode.sarif-viewer&quot;&gt;VSCode SARIF Viewer&lt;/a&gt; - Adds support for viewing SARIF logs in Visual Studio Code&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://plugins.jetbrains.com/plugin/23159-sarif-viewer&quot;&gt;IntelliJ SARIF Viewer&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://microsoft.github.io/sarif-web-component/&quot;&gt;SARIF Viewer Web Component&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/psastras/sarif-rs/tree/main/sarif-fmt&quot;&gt;psastras/sarif-rs-sarif-fmt&lt;/a&gt; - This crate provides a command line tool to pretty print SARIF files to easy human readable output.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Containers&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/advanced-security/codeql-docker&quot;&gt;codeql-docker&lt;/a&gt; - CodeQL Docker image&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/microsoft/codeql-container&quot;&gt;codeql-container&lt;/a&gt; - Prepackaged and precompiled github codeql container for rapid analysis, deployment and development.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/advanced-security/codeql_container_example&quot;&gt;codeql_container_example&lt;/a&gt; - Example showing CodeQL to scan containerized applications in GitHub Actions.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://some-natalie.dev/blog/codeql-container-builds/&quot;&gt;codeql-container-builds&lt;/a&gt; - Blog walking through the complexities of implementing containerized CodeQL workloads sprinkled with bits of Kubernetes wisdom.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Enforcement&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/zkoppert/advanced-security-enforcer&quot;&gt;advanced-security-enforcer&lt;/a&gt; - A GitHub action for organizations that enables advanced security code scanning on all new repos&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/octodemo/codeql-selective-analysis&quot;&gt;codeql-selective-analysis&lt;/a&gt; - Make CodeQL a required status check for Pull Requests, but to skip the analysis in the case that only a certain subset of files are modified&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Extractors&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/advanced-security/codeql-extractor-iac&quot;&gt;codeql-extractor-iac&lt;/a&gt; - CodeQL Extractors, Library, and Queries for Infrastructure as Code ( Terraform / HCL, JSON, YAML, Container files, Bicep )&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/GitHubSecurityLab/codeql-extractor-bicep&quot;&gt;codeql-extractor-bicep&lt;/a&gt; - CodeQL Extractor for Bicep Configurations&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/aibaars/codeql-kaleidoscope/&quot;&gt;codeql-kaleidoscope&lt;/a&gt; - CodeQL for LLVM Kaleidoscope (&lt;a href=&quot;https://github.com/aibaars/codeql-kaleidoscope/commits/main/&quot;&gt;AST/CFG/SSA/Dataflow in separate commits&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/microsoft/codeql/blob/main/powershell/README.md&quot;&gt;Powershell Extractor&lt;/a&gt; - CodeQL extractor, sample queries, and tools for Powershell&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/CoinFabrik/CyScout/tree/main/solidity/codeql&quot;&gt;CyScout Solidity Extractor&lt;/a&gt; - Run queries and detect vulnerabilities in your smart contracts using CodeQL-Solidity&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/krisds/cobol-codeql&quot;&gt;cobol-codeql&lt;/a&gt; - Archive of CodeQL support for COBOL (This is a one-off release of code for supporting analysis of COBOL programs using QL. The release of this code does not imply any intention to support it in the future.)&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Extractor Helpers&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/advanced-security/codeql-extractor-action&quot;&gt;codeql-extractor-action&lt;/a&gt; - specify a CodeQL extractor to be used in your workflows as an author of an Extractor.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Samples&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/advanced-security/sample-codeql-pipeline-config&quot;&gt;sample-pipeline-files&lt;/a&gt; - This repository contains pipeline files for various CI/CD systems (AWS CodeBuild, Azure Devops, CircleCI, DroneCI, Jenkins, Tekton, Travis), illustrating how to integrate the CodeQL CLI Bundle for Automated Code Scanning&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/octodemo/vulnerable-pickle-app/blob/main/custom-queries/python/dangerous-functions.ql&quot;&gt;Python Pickle&lt;/a&gt; - mapping a custom framework in python&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Query Writing&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/readme/guides/custom-codeql-queries&quot;&gt;ReadMe Project&lt;/a&gt; - A beginner’s guide to running and managing custom CodeQL queries&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Conan</title>
      <link>https://tedneward.github.io/Research/tools/conan/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/conan/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://conan.io/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/conan-io/conan&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;macOS: &lt;code&gt;brew install conan&lt;/code&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Thinking in Bets</title>
      <link>https://tedneward.github.io/Research/thinking/thinking-in-bets/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">thinking/thinking-in-bets/index.html</guid>
      	<description>
	&lt;p&gt;&lt;em&gt;(by Annie Duke, Portfolio/Penguin, 2018, ISBN 9780735216365)&lt;/em&gt;&lt;/p&gt; 
&lt;h2&gt;Chapter 1: Life is Poker, not Chess&lt;/h2&gt; 
&lt;p&gt;&lt;strong&gt;The hazards of resulting&lt;/strong&gt;: we link results with decisions even though it is easy to point out indisputable examples where the relationship between decisions and results isn&apos;t so perfectly correlated.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Quick or dead: our brains weren&apos;t built for rationality&lt;/strong&gt;: our brains evolved to create certainty and order. We are uncomfortable with the idea that luck plays a significant role in our lives. We recognize the existence of luck, but we resist the idea that, despite our best efforts, things might not work out the way we want. It feels better for us to imagine the world as an orderly place, where randomness does not wreak havoc and things are perfectly predictable. We evolved to see the world that way. Creating order out of chaos has been necessary for our survival. When we work backwards from results to figure out why those things happened, we are susceptible to a variety of cognitive traps, like assuming causation when there is only correlation, or cherry-picking data to confirm the narrative we prefer. We will pound a lot of square pegs into round holes to maintain the illusion of a tight relationship between our outcomes and our decisions. Kahneman&apos;s System 1&quot; and &quot;System 2&quot; thinking; also called &quot;reflexive mind&quot; and &quot;deliberative mind&quot; by Gary Marcus (Kluge: The Haphazard Evolution of the Human Mind).&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Game theory&lt;/strong&gt;: &quot;the study of mathematical models of conflict and cooperation between intelligent rational decision-makers.&quot;&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Poker vs chess&lt;/strong&gt;: chess contains no hidden information and very little luck. Poker is a game of incomplete information.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;&quot;I&apos;m not sure&quot;: using uncertainty to our advantage&lt;/strong&gt;: admitting that we don&apos;t know has an undeservedly bad reputation. The first step is understanding what we don&apos;t know. Ignorance: How It Drives Science (Stuart Firestein) points out that in science, &quot;I don&apos;t know&quot; is a necessary step toward enlightenment. What makes a decision great is not that it has a great outcome. A great decision is the result of good process, and that process must include an attempt to accurately represent our own state of knowledge. That state of knowledge, in turn, is some variation of &quot;I&apos;m not sure&quot;. Acknowledging uncertainty is the first step in executing on our goal to get closer to what is objectively true. &quot;I&apos;m not sure&quot; is simply a more accurate representation of the world. When we accept that we can&apos;t be sure, we are less likely to fall into the trap of black-and-white thinking. The secret is to make peace with walking around in a world where we recognize that we are not sure and it&apos;s OK.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Redefining wrong&lt;/strong&gt;: When we think in advance about the chances of alternative outcomes and make a decision based on those chances, it doesn&apos;t automatically make us wrong when things don&apos;t work out. It just means that one event in a set of possible futures occurred. Any prediction that isn&apos;t 0% or 100% can&apos;t be wrong solely because the most likely future doesn&apos;t unfold.&lt;/p&gt; 
&lt;h2&gt;Chapter 2: Wanna Bet?&lt;/h2&gt; 
&lt;p&gt;&lt;strong&gt;We&apos;ve all been to Des Moines&lt;/strong&gt;: hiring an employee is not a riskless choice. By treating decisions as bets, poker players explicitly recognize that they are deciding on alternative futures, each with benefits and risks. They also recognize that there are no simple answers. If we follow the example of poker players by making explicit that our decisions are bets, we can make better decisions and anticipate (and take protective measures) when irrationality is likely to keep us from acting in our best interest.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;All decisions are bets&lt;/strong&gt;: &quot;bet&quot;: &quot;a choice made by thinking about what will probably happen&quot;; &quot;to risk losing (something) when you try to do or achieve something&quot;; &quot;to make decisions that are based on the belief that something will happen or is true&quot;. Every decision commits us to some course of action that, by definition, eliminates acting on other alternatives.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Most bets are against ourselves&lt;/strong&gt;: One of the reasons we don&apos;t naturally think of decisions as bets is because we get hung up on the zero-sum nature of the betting that occurs in the gambling world. In most of our decisions, we are not betting against another person; we are betting against all the future versions of ourselves that we are not choosing. Whenever we make a choice, we are betting on a potential future; we are betting that the future version of us that results from the decisions we make will be better off. Ignoring the risk and uncertainty in every decision might make us feel better in the short run, but the cost to the quality of our decision-making can be immense. If we can find ways to become more comfortable with uncertainty, we can see the world more accurately and be better for it.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Our bets are only as good as our beliefs&lt;/strong&gt;: we bet based on what we believe about the world. Part of the skill in life comes from learning to be a better calibrator, using experience and information to more objectively update our beliefs to more accurately represent the world. The more accurate our beliefs, the better the foundation of the bets we make. There is also skill in identifying when our thinking patterns might lead us astray, no matter what our beliefs are, and in developing strategies to work with (and sometimes around) those thinking patterns.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Hearing is believing&lt;/strong&gt;: we form beliefs in a haphazard way, believing all sorts of things based just on what we hear out in the world but haven&apos;t researched for ourselves. (How to determine a man will go bald; how you calculate a dog&apos;s age in human years. Both are common misperceptions -- Google &quot;common misconceptions&quot;.) How we think we form abstract beliefs: (1) We hear something; (2) We think about it and vet it, determining whether it is true or false; (3) We form our belief. How we actually form abstract beliefs: (1) We hear something; (2) We believe it to be true; (3) Only sometimes, later, if we have the time or inclination, we think about it and vet it, determining whether it is, in fact, true or false. Daniel Gilbert (Stumbling on Happiness) is responsible for pioneering work on belief formation: &quot;People are credulous creatures who find it very easy to believe and very difficult to doubt.&quot; How we form beliefs was shaped by the evolutionary push towards efficiency rather than accuracy. Truthseeking, the desire to know truth regardless of whether the truth aligns with the beliefs we currently hold, is not naturally supported by the way we process information. We might think of ourselves as open-minded and capable of updating our beliefs based on new information, but the research conclusively shows otherwise. Instead of altering our beliefs to fit new information, we do the opposite, altering our interpretation of that information to fit our beliefs.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;They saw a game&lt;/strong&gt;: our pre-existing beliefs influence the way we experience the world. That those beliefs aren&apos;t formed in a particularly orderly way leads to all sorts of mischief in our decision-making.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;The stubbornness of beliefs&lt;/strong&gt;: once a belief is lodged, it becomes difficult to dislodge, leading us to notice and seek out evidence confirming our belief, rarely challenging the validity of confirming evidence and ignore or work hard to actively discredit information contradicting the belief. This is called motivated reasoning.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Being smart makes it worse&lt;/strong&gt;: the smarter you are, the better you are at constructing a narrative that supports your beliefs, rationalizing and framing the data to fit your argument or point of view. The better you are with numbers, the better you are at spinning those numbers to conform to and support your beliefs.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Wanna bet?&lt;/strong&gt;: when someone challenges us on a belief, signaling their confidence that our belief is inaccurate in some way, ideally it triggers us to vet the belief, taking an inventory of the evidence that informed us. Being asked if we are willing to bet money on it makes it much more likely that we will examine our information in a less-biased way, be more honest with ourselves about how sure we are of our beliefs, and be more open to updating and calibrating our beliefs. Offering a wager brings the risk out in the open, making explicit what is already implicit (and frequently overlooked).&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Redefining confidence&lt;/strong&gt;: The Half-Life of Facts is a great read about how practically every fact we&apos;ve ever known has been subject to revision or reversal. We are in a perpetual state of learning, and that can make any prior fact obsolete. We would all be well-advised to take a good hard look at our beliefs; we would be better served as communicators and decision-makers if we thought less about whether we are confident in our beliefs and more about how confident (scale of zero to ten) we are; capture the shades of grey. When we work toward belief calibration, we become less judgmental of ourselves. Incorporating percentages or ranges of alternatives into the expression of our beliefs means that our personal narrative no longer hinges on whether we were right or wrong but on how well we incorporate new information to adjust the estimate of how accurate our beliefs are. Declaring our uncertainty in our beliefs to others makes us more credible communicators. Expressing our level of confidence also invites other people to be our collaborators. When we declare something as 100% fact, others might be reluctant to offer up new and relevant information that would inform our beliefs for two reasons: first, they might be afraid they are wrong and so won&apos;t speak up; second, even if they are very confident their information is high quality, they might be afraid of making us feel bad or judged. Expressing our beliefs this way also serves our listeners, by signaling that the belief needs further vetting.&lt;/p&gt; 
&lt;h2&gt;Chapter 3: Bet to Learn: Fielding the Unfolding Future&lt;/h2&gt; 
&lt;p&gt;&lt;strong&gt;Outcomes are feedback&lt;/strong&gt;: &quot;Experience is not what happens to a man; it is what a man does with what happens to him.&quot; --Aldous Huxley. The difference between getting experience and becoming an expert lies in the ability to identify when the outcomes of our decisions have something to teach us and what that lesson might be. The challenge is that any single outcome can happen for multiple reasons; the unfolding future is a big data dump that we have to sort and interpret, and the world doesn&apos;t connect the dots for us between outcomes and causes. To reach our long-term goals, we have to improve at sorting out when the unfolding future has something to teach us, when to close the feedback loop. The first step to doing this well is in recognizing that things sometimes happen because of the other form of uncertainty: luck.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Luck vs skill: fielding outcomes&lt;/strong&gt;: The way our lives turn out is the result of two things: the influence of skill and the influence of luck. Chalk up an outcome to skill, and we take credit for the result; chalk up an outcome to luck and it wasn&apos;t in our control. It is hard to get this right.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Working backward is hard: the SnackWell&apos;s Phenomenon&lt;/strong&gt;: betting on low fat instead of sugar. Working backwards from the way things turn out isn&apos;t easy. We can get to the same outcome by different routes. Outcomes don&apos;t tell us what&apos;s our fault and what isn&apos;t, what we should take credit for and what we shouldn&apos;t. We can&apos;t simply work backward from the quality of the outcome to determine the quality of our beliefs or decisions. Rats get tripped up by uncertainty as well: when rats are trained on a fixed reward schedule, they learn pretty fast; when you remove the reward, the behave is quickly extinguished; when rats are trained on a variable/intermittent reinforcement schedule, that introduces uncertainty; when you remove the reward, the behavior extinguishes only after a very long time of fruitless behavior, sometimes thousands of tries. Worse, outcomes are rarely all skill or all luck.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;&quot;If it weren&apos;t for luck, I&apos;d win every one&quot;&lt;/strong&gt;: the way we field outcomes is predictably patterned: we take credit for the good stuff, and blame the bad stuff on luck so it won&apos;t be our fault. Stanford law professor Robert MacCoun found that in 75% of accidents, the victims blamed someone else for their injuries. In single-vehicle accidents, 37% of drivers still found a way to pin the blame on someone else. Self-serving bias has immediate and obvious consequences for our ability to learn from experience.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;People watching&lt;/strong&gt;: watching is an established learning method. Unfortunately, learning from watching is just as fraught with bias. We field the outcomes of our peers predictably; where we blame the bad outcomes on bad luck, when it comes to our peers, bad outcomes are clearly their fault. While our own good outcomes are due to our awesome decision-making, when it comes to other people, good outcomes are because they got lucky.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Other people&apos;s outcomes reflect on us&lt;/strong&gt;: Blaming others for their bad results and failing to give them credit for their good ones is under the influence of ego; knocking down a peer by finding them at fault for a loss lifts our personal narrative. Schadenfreude. We feel it&apos;s a zero-sum game. Our genes are competitive; natural selection proceeds by competition among the phenotypes of genes so we literally evolved to compete, a drive that allowed our species to survive. We think we know the ingredients for happiness; Sonja Lyubomirsky (psych prof at UCR) summarized several reviews of the literature on the elements we commonly consider: &quot;a comfortable income, robust health, a supportive marriage, and lack of tragedy or trauma&quot;, however, &quot;the general conclusion from almost a century of research on the determinants of well-being is that objective circumstances, demographic variables and life events are correlated with happiness less than intuition and everyday experience tells they out to be. By several estimates, all of these variables put together account for no more than 8% to 15% of the variance in happiness.&quot; What accounts for most of the variance in happiness is how we&apos;re doing comparatively. Would You Rather… earn $70k in 1900 or $70k now, most choose 1900, even though 1900 has no novocaine, air-conditioning, refrigeration or computers; we&apos;d rather lap the field in 1900 with an average life expectancy of only forty-seven years than life in the middle of the pack with an average life expectancy of seventy-six years. A lot of the way we feel about ourselves comes from how we think we compare with others. We can learn better and be more open-minded if we work toward a positive narrative driven by engagement in truthseeking and striving toward accuracy and objectivity: giving others credit when it&apos;s due, admitting when our decisions could have been better, and acknowledging that almost nothing is black and white.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Reshaping habit&lt;/strong&gt;: habits operate in a neurological loop consisting of three parts: the cue, the routine and the reward. To change a habit, you must keep the old cue, and deliver the old reward, but insert a new routine. We can work to change the habit of mind by substituting what makes us feel good. The golden rule of habit change says we don&apos;t have to give up the reward of a positive update to our narrative: we can work to get the reward of feeling good from being a good credit-giver, a good learner, and (as a result) a good decision-maker. Instead of feeling bad when we have to admit a mistake, what if the bad feeling came from the thought that we might be missing a learning opportunity just to avoid blame?&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Wanna bet? Redux&lt;/strong&gt;: The key is that in explicitly recognizing the way we field an outcome is a bet, we consider a greater number of alternative causes more seriously than we otherwise would have. The prospect of a bet makes us examine and refine our beliefs, in this case the belief about whether luck or skill was the main influence in the way things turned out. When we treat outcome fielding as a bet, it pushes us to field outcomes more objectively into the appropriate buckets because that is how bets are won. Thinking in bets triggers a more open-minded exploration of alternative hypotheses, of reasons supporting conclusions opposite to the routine of self-serving bias; we are more likely to explore the opposite side of an argument more often and more seriously--and that will move us closer to the truth of the matter. Thinking in bets also triggers perspective taking, leveraging the difference between how we field our own outcomes versus others&apos; outcomes to get closer to the objective truth.&lt;/p&gt; 
&lt;h2&gt;Chapter 4: The Buddy System&lt;/h2&gt; 
&lt;p&gt;&lt;strong&gt;&quot;Maybe you&apos;re the problem, do you think?&quot;&lt;/strong&gt;: Not all situations are appropriate for truthseeking, nor are all people interested in the pursuit. Any of us who wants to get better at thinking in bets would benefit from having more David Lettermans in our lives; Lettermaning needs agreement by both parties to be effective.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;The red pill or the blue pill?&lt;/strong&gt;: Our brains have evolved make our version of the world more comfortable: our beliefs are nearly always correct; favorable outcomes are the result of our skill; there are plausible reasons why unfavorable outcomes are beyond our control; we compare favorably with our peers; we deny or at least dilute the most painful parts of the message. Giving that up is not the easiest choice; by choosing to exit the matrix, we are asserting that striving for a more objective representation of the world, even if it is uncomfortable at times, will make us happier and more successful in the long run.&lt;/p&gt; 
&lt;p&gt;Thinking in bets is easier if you have other people to help you. A good decision group is a grown-up version of the buddy system. If we can find a few people to choose to form a truthseeking pod with us and help us to do the hard work connected with it, it will move the needle--just a little bit, but with improvements that accumulate and compound over time. We will be more successful in fighting bias, seeing the world more objectively, and, as a result, we will make better decisions. As long as there are three people in the group (two to disagree and one to referee), the truthseeking group can be stable and productive.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Not all groups are created equal&lt;/strong&gt;: a well-chartered group can be particularly useful for habits that are difficult to break or change. But while a group can function to be better than the sum of the individuals, it doesn&apos;t automatically turn out that way. Being in a group can improve our decision quality by exploring alternatives and recognize where our thinking might be biased, but a group can also exacerbate our tendency to confirm what we already believe (echo chamber). Confirmatory thought amplifies bias; promotes a love and celebration of one&apos;s own beliefs. Exploratory thought encourages an open-minded and objective consideration of alternative hypotheses and a tolerance of dissent to combat bias. Exploratory thought helps the members of a group reason toward a more accurate representation of the world. Without an explicit charter for exploratory thought and accountability to that charter, our tendency when we interact with others follows our individual tendency. &quot;Complex and open-minded thought is most likely to be activated when decision makers learn prior to forming any opinions that they will be accountable to an audience (a) whose views are unknown, (b) who is interested in accuracy, (c) who is reasonably well-informed, and (d) who has a legitimate reason for inquiring into the reasons behind participants&apos; judgments/choices.&quot; (Lerner, Tetlock) Groups can improve the thinking of individual decision-makers when the individuals are accountable to a group whose interest is in accuracy; charter should also encourage and celebrate a diversity of perspectives to challenge biased thinking by individual members. Jonathan Haidt (The Righteous Mind: Why Good People Are Divided by Politics and Religion): &quot;If you put individuals together in the right way, such that some individuals can use their reasoning powers to disconfirm the claims of others, and all individuals feel some common bond or shared fate that allows them to interact civilly, you can create a group that ends up producing good reasoning as an emergent property of the social system. This is why it&apos;s so important to have intellectual and ideological diversity within any group or institution whose goal is to find truth.&quot; In combination, the advice of these experts in group interaction adds up to a blueprint for a truthseeking charter: (1) A focus on accuracy (over confirmation), which includes rewarding truthseeking, objectivity, and open-mindedness within the group; (2) Accountability, for which members have advance notice, and (3) Openness to a diversity of ideas.&lt;/p&gt; 
&lt;p&gt;The group rewards focus on accuracy -- a productive decision group can harness the desire for approval by rewarding accuracy and intellectual honesty with social approval.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;&quot;One Hundred White Castles... and a large chocolate shake&quot;&lt;/strong&gt;: how accountability improves decision-making -- accountability is a willingness or obligation to answer for our actions or beliefs to others. A bet is a form of accountability. After spending time in that (poker players) kind of environment, you become hypervigilant about your level of confidence in your beliefs; it is truly putting your money where your mouth is. Accountability also improves our decision-making and information processing when we are away from the group because we know in advance that we will have to answer to the group for our decisions: imagining how the discussion will go helps us to spot more errors on our own and catch them more quickly.&lt;/p&gt; 
&lt;p&gt;The group ideally exposes us to a diversity of viewpoints -- diversity and dissent are not only checks on fallibility, but the only means of testing the ultimate truth of an opinion. If we take a bunch of people with that limitation [being a human and thus having only one point of view] and put them together into a group, we get exposed to diverse opinions, can test alternative hypotheses, and move toward accuracy. To get a more objective view of the world, we need an environment that exposes us to alternate hypotheses and different perspectives. To view ourselves in a more realistic way, we need other people to fill in our blind spots. A group with diverse viewpoints can help us by sharing the work to combat motivated reasoning and biased outcome fielding; by thinking in bets, we run through a series of questions to examine the accuracy of our beliefs, for example:&lt;br&gt; * Why might my belief not be true?&lt;br&gt; * What other evidence might be out there bearing on my belief?&lt;br&gt; * Are there similar areas I can look toward to gauge whether similar beliefs to mine are true?&lt;br&gt; * What sources of information could I have missed or minimized on the way to reaching my belief?&lt;br&gt; * What are the reasons someone else could have a different belief, what&apos;s their support, and why might they be right instead of me?&lt;br&gt; * What other perspectives are there as to why things turned out the way that they did?&lt;/p&gt; 
&lt;p&gt;By asking these questions, we are taking a big step toward calibration, but there is only so much we can do to answer these questions on our own. It is a lot easier to have someone else offer their perspective than for you to imagine you&apos;re another person and think about what their perspective might be. A diverse group can do some of the heavy lifting of de-biasing for us. Dissent channels and red teams are a beautiful implementation of John Stuart Mill&apos;s bedrock principle that we can&apos;t know the truth of a matter without hearing the other side. Diversity is the foundation of productive group decision-making, but we can&apos;t underestimate how hard it is to maintain.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Federal judges: drift happens&lt;/strong&gt;: Cass Sunstein (Harvard law professor) conducted massive study on ideological diversity in federal judicial panels; when there was political diversity on the panels, that diversity improved the panel&apos;s work--a single panelist from the other party had &quot;a large disciplining effect&quot;. The more homogeneous we get, the more the group will promote and amplify confirmatory thought.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Social psychologists: confirmatory drift and Heterodox Academy&lt;/strong&gt;: First, there is a natural drift toward homogeneity and confirmatory thought; we all experience this gravitation toward people who think like we do. Second, groups with diverse viewpoints are the best protection against confirmatory thought; the opinions of the group members aren&apos;t much help if it is a group of clones.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Wanna bet (on science)?&lt;/strong&gt;: Experts engaging in traditional peer review, providing their opinion on whether an experimental result would replicate, were right 58% of the time. A betting market in which the traders were the exact same experts and those experts had money on the line predicted correctly 71% of the time.&lt;/p&gt; 
&lt;h2&gt;Chapter 5: Dissent to Win&lt;/h2&gt; 
&lt;p&gt;&lt;strong&gt;CUDOS to a magician&lt;/strong&gt;: CUDOS stands for Communism (data belonging to the group), Universalism (apply uniform standards to claims and evidence, regardless of where they came from), Disinterestedness (vigilance against personal conflicts that can influence the group&apos;s evaluation) and Organized Skepticism (discussion among the group to encourage engagement and dissent).&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Mertonian communism: more is more&lt;/strong&gt;: the communal ownership of data within groups. Any attempt at accuracy is bound to fall short if the truthseeking group has only limited access to potentially pertinent information; without all the facts, accuracy suffers. As a rule of thumb, if we have an urge to leave out a detail because it makes us uncomfortable or requires even more clarification to explain away, those are exactly the details we must share. The mere fact of our hesitation and discomfort is a signal that such information may be critical to providing a complete and balanced account. We are naturally reluctant to share information that could encourage others to find fault in our decision-making. Group(s) [can] make this easier by making [one] feel good about commiting [oneself] to improvement.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Universalism: don&apos;t shoot the message&lt;/strong&gt;: &quot;Truth-claims, whatever their source, are to be subjected to preestablished impersonal criteria.&quot; (Merton) Acceptance/rejection of an idea must not &quot;depend on the personal or social attributes of their protagonist.&quot; Don&apos;t disparage or ignore an idea just because you don&apos;t like who or where it came from. The accuracy of the statement should be evaluated independent of its source. Nearly any group can create an exercise to develop and reinforce the open-mindedness universalism requires.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Disinterestedness: we all have a conflict of interest, and it&apos;s contagious&lt;/strong&gt;: Conflicts of interest come in many flavors; our brains have built-in conflicts of interest, interpreting the world around us to confirm our beliefs (and more). We are not naturally disinterested. A group is less likely to succumb to ideological conflicts of interest when they don&apos;t know what the interest is. Another way a group can de-bias members is to reward them for skill in debating opposing points of view and finding merit in opposing positions. The group&apos;s reinforcement ought to discourage us from creating a straw-man argument when we&apos;re arguing against our beliefs, and encourage us to feel good about winning the debate. This is one of the reasons it&apos;s good for a group to have at least three members, two to disagree and one to referee.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Organized skepticism: real skeptics make arguments and friends&lt;/strong&gt;: True skepticism is consistent with good manners, civil discourse, and friendly communications. Skepticism is about approaching the world by asking why things might not be true rather than why they are true. Thinking in bets embodies skepticism by encouraging us to examine what we do and don&apos;t know and what our level of confidence is in our beliefs and predictions. This moves us closer to what is objectively true. Without embracing uncertainty, we can&apos;t rationally bet on our beliefs, and we need to be particularly skeptical of information that agrees with us because we know that we are biased to just accept and applaud confirming evidence. When we implement the norm of skepticism, we naturally modulate expression of dissent with others. Organized skepticism invites people into a cooperative exploration. Skepticism should be encouraged and, where possible, operationalized.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Communicating with the world beyond our group&lt;/strong&gt;: we have to take the most constructive, civil elements of truthseeking communication and introduce them carefully. First, express uncertainty. Second, lead with assent; listen for things you agree with, state those and be specific, and then follow with an &quot;and&quot; instead of &quot;but&quot;. Third, ask for a temporary agreement to engage in truthseeking; if someone is offloading emotion to us, we can ask them if they are just looking to vent or if they are looking for advice. Finally, focus on the future; rather than rehashing what has already happened, try instead to engage about what the person might do so that things will turn out better going forward.&lt;/p&gt; 
&lt;h2&gt;Chapter 6: Adventures in Mental Time Travel&lt;/h2&gt; 
&lt;p&gt;&lt;strong&gt;Let Marty McFly run into Marty McFly&lt;/strong&gt;: in real-life decision-making, when we bring our past- or future-self into the equation, the space-time continuum doesn&apos;t unravel; a visit from past- or future-us helps present-us make better bets.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Night Jerry&lt;/strong&gt;: &quot;Night Guy always screws Morning Guy.&quot; When we make in-the-moment decisions (and don&apos;t ponder the past or future) we are more likely to be irrational and impulsive. This is called temporal discounting; we are willing to take an irrationally large discount to get a reward now instead of waiting for a bigger reward later.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Moving regret in front of our decisions&lt;/strong&gt;: Regret is one of the most intense emotions we feel, but it&apos;s arguable about whether it&apos;s productive or useful. The problem isn&apos;t so much whether regret is an unproductive emotion; it&apos;s that regret occurs after the fact, instead of before. Suzy Welch developed 10-10-10: &quot;What are the consequences of each of my options in ten minutes? Ten months? Ten years?&quot; We can build on Welch&apos;s tool by asking the question through the frame of the past: &quot;How would I feel today if I had made this decision ten minutes ago? Ten months ago? Ten years ago?&quot; Moving regret in front of a decision has numerous benefits. First it can influence us to make a better decision. Second, it helps us treat ourselves (regardless of the actual decision) more compassionately after the fact. We can anticipate and prepare for negative outcomes; we can devise a plan to respond to a negative outcome instead of just reacting to it; we can also familiarize ourselves with the likelihood of a negative outcome and how it will feel.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;A flat tire, the ticker, and a zoom lens&lt;/strong&gt;: Flat tire in a downpour--how does it feel? Likely, like the worst moment of your life. But if the flat tire had happened a year ago, do you think it would have an effect on your happiness today, or your overall happiness over the past year? Not likely; it likely wouldn&apos;t cause your overall happiness to tick up or down. In our decision-making lives, we aren&apos;t that good at taking this kind of perspective; it just feels how it feels in the moment and we react to it.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;&quot;Yeah, but what have you done for me lately?&quot;&lt;/strong&gt;: the way we field outcomes is path dependent; it doesn&apos;t matter so much where we end up as how we got there. What has happened in the recent past drives our emotional response much more than how we are doing overall. Our in-the-moment emotions affect the quality of the decisions we make in those moments, and we are very willing to make decisions when we are not emotionally fit to do so.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Tilt&lt;/strong&gt;: from pinball machines; when the emotional center of the brain starts pinging, the limbic system (specifically the amygdala) shuts down the prefrontal cortex. We light up, then we shut down our cognitive control center. By recognizing in advance these verbal and physiological signs that ticker watching is making us tilt, we can commit to develop certain habit routines at those moments. We can precommit to walk away from the situation when we feel the signs of tilt, take some space until we calm down and get some perspective, recognizing that when are on tilt we aren&apos;t decision-fit.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Ulysses contracts&lt;/strong&gt;: time traveling to precommit -- past-us preventing present-us from doing something stupid has become known as a Ulysses contract (Ulysses/Odysseus filling his sailors&apos; ears with wax and tying himself to the mast so he could hear the Sirens). It&apos;s the perfect interaction between past-you, present-you and future-you. Ulysses contracts can be barrier-raising (against irrational or undesirable behavior) or barrier-reducing (to increase the ease of making the desirable decision).&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Decision swear jar&lt;/strong&gt;: a simple kind of precommitment contract to implement accountability.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Reconnaissance&lt;/strong&gt;: mapping the future -- for us to make better decisions, we need to perform reconnaissance on the future. If a decision is a bet on a particular future based on our beliefs, then before we place a bet we should consider in detail what those possible futures might look like. Figure out the possibilities, then take a stab at the probabilities. Scenario planning: consider a broad range of possibilities for how the future might unfold to help guide long-term planning and preparation. After identifying as many of the possible outcomes as we can, we want to make our best guess at the probability of each of those futures occurring. The reason we do reconnaissance is because we are uncertain; we don&apos;t (and likely can&apos;t) know how often things will turn out a certain way with exact precision. It&apos;s not about approaching our future predictions from a point of perfection; it&apos;s about acknowledging that we&apos;re already making a prediction about the future every time we make a decision, so we&apos;re better off if we make that explicit. If we&apos;re worried about guessing, we&apos;re already guessing. By at least trying to assign probabilities, we will naturally move away from the default of 0% or 100%, away from being sure it will turn out one way and not another. Scouting various futures has numerous additional benefits. First, scenario planning reminds us that the future is inherently uncertain; by making that explicit in our decision-making process, we have a more realistic view of the world. Second, we are better prepared for how we are going to respond to different outcomes that might result from our initial decision. We can anticipate positive or negative developments and plan our strategy, rather than being reactive. If our reconnaissance has identified situations where we are susceptible to irrationality, we can try to bind our hands with a Ulysses contract. Third, anticipating the range of outcomes also keeps us from unproductive regret (or undeserved euphoria) when a particular future happens. Finally, by mapping out the potential futures and probabilities, we are less likely to fall prey to resulting or hindsight bias.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Backcasting&lt;/strong&gt;: working backward from a positive future -- If we were contemplating a thousand-mile walk, we&apos;d be better off imagining ourselves looking back from the destination and figuring how we got there. When it comes to advance thinking, standing at the end and looking backward is much more effective than looking forward from the beginning. Imagining a successful future and backcasting from there is a useful time-travel exercise for identifying necessary steps for reaching our goals; working backward helps even more when we give ourselves the freedom to imagine an unfavorable future.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Premortems&lt;/strong&gt;: working backward from a negative future -- A premortem is where we check our positive attitude at the door and imagine not achieving our goals. Despite the popular wisdom that we achieve success through positive visualization, it turns out that incorporating negative visualization makes us more likely to achieve our goals. Gabriele Oettingen (Rethinking Positive Thinking: Inside the New Science of Motivation) has conducted over twenty years of research, consistently finding that people who imagine obstacles in the way of reaching their goals are more likely to achieve success, a process she has called &quot;mental contrasting&quot;. We need to have positive goals, but we are more likely to execute on those goals if we think about negative futures. We start a premortem by imagining why we failed to reach our goal; then we imagine why. All those reasons why we didn&apos;t achieve our goal help us anticipate potential obstacles and improve our likelihood of succeeding. The key to a successful premortem is that everyone feels free to look for the most creative, relevant and actionable reasons why things didn&apos;t work out, and they are motivated to scour everything--personal experience, company experience, historical precedent, sports analogies, etc--to come up with ways a decision or plan can go bad, so the team can anticipate and account for them.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Dendrology and hindsight bias&lt;/strong&gt; (or, Give the chainsaw a rest): think about time as a tree. The trunk is the past. A tree has only one, growing trunk, just as we have only one, accumulating past. Branches are the potential futures. Thicker branches are the equivalent of more probable futures, thinner branches are less probable ones. As the future becomes the past, what happens to all those branches? The ever-advancing present acts like a chainsaw; when one of those many branches happens to be the way things turn out, present-us cuts off all those other branches that didn&apos;t materialize and obliterates them. When we look into the past and see the only thing that happened, it seems to have been inevitable. Why wouldn&apos;t it? That&apos;s hindsight bias, an enemy of probabilistic thinking. By keeping an accurate representation of what could have happened (and not a version edited by hindsight), memorializing the scenario plans and decision trees we create through good planning process, we can be better calibrators going forward.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Thinking in Systems</title>
      <link>https://tedneward.github.io/Research/thinking/thinking-in-systems/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">thinking/thinking-in-systems/index.html</guid>
      	<description>
	&lt;p&gt;&lt;em&gt;(Donella H. Meadows; ISBN ...)&lt;/em&gt;&lt;/p&gt; 
&lt;h3&gt;Part 1: System Structure and Behavior&lt;/h3&gt; 
&lt;h4&gt;Ch 1: The Basics&lt;/h4&gt; 
&lt;h5&gt;More Than the Sum of Its Parts&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;A system is an interconnected set of elements that is coherently organized in a way that achieves something. It consists of three kinds of things: elements, interconnections, and a function or purpose.&lt;/li&gt; 
 &lt;li&gt;There is an integrity or wholeness about a system and an active set of mechanisms to maintain that integrity.&lt;/li&gt; 
 &lt;li&gt;The system is more than the sum of its parts. It may exhibit adaptive, dynamic, goal-seeking, self-preserving, and sometimes evolutionary behavior.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;Look Beyond the Players to the Rules of the Game&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;The elements of a system are often the easiest parts to notice, because many of them are visible, tangible things. But intangibles can also be elements.&lt;/li&gt; 
 &lt;li&gt;Many interconnections in a system are flows of information, or signals that go to decision or action points. Information holds systems together and greatly determines how they operate.&lt;/li&gt; 
 &lt;li&gt;The purpose of a system is deduced from its behavior, not from rhetoric or stated goals. One important purpose of almost every system is to ensure its own perpetuation.&lt;/li&gt; 
 &lt;li&gt;Keeping sub-purposes and overall system purposes in harmony is an essential function of successful systems.&lt;/li&gt; 
 &lt;li&gt;A system generally goes on being itself, changing only slowly if at all, even with complete substitutions of its elements –&amp;nbsp;as long as its interconnections and purposes remain intact.&lt;/li&gt; 
 &lt;li&gt;The elements are often the least important in defining the unique characteristics of the system, unless changing an element also changes relationships or purpose.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;Bathtubs 101 – Understanding System Behavior over Time&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;Stocks are the elements of a system that you can see, feel, count, or measure. They are a store, quantity, or accumulation of material or information that has built up over time.&lt;/li&gt; 
 &lt;li&gt;Stocks change over time through the actions flows. A stock is therefore a memory of the history of changing flows within the system.&lt;/li&gt; 
 &lt;li&gt;Understanding the dynamics of stocks and flows reveals much about a complex system&apos;s behavior. In a state of dynamic equilibrium, a stock does not change.&lt;/li&gt; 
 &lt;li&gt;We focus more on inflows than outflows, but a stock can be increased by decreasing its outflow rate as well as increasing its inflow rate.&lt;/li&gt; 
 &lt;li&gt;A stock takes time to change, even when the flows into our out of them change suddenly. Stocks therefore act as delays or buffers or shock absorbers in a system.&lt;/li&gt; 
 &lt;li&gt;The time lags that come from slowly changing stocks can cause problems, but also provide stability. They allow room to maneuver, to experiment, and to revise policies that aren&apos;t working.&lt;/li&gt; 
 &lt;li&gt;Stocks allow inflows and outflows to be decoupled and to be independent and temporarily out of balance with one another.&lt;/li&gt; 
 &lt;li&gt;Most individual and institutional decisions are designed to regulate the levels of stocks. System thinkers see the world as stocks with the mechanisms for regulating their levels by manipulating flows.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;How the System Runs Itself – Feedback&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;Feedback loops permit behaviors that persist over time. Such a loop is formed when a change in stock affects the flows into our out of that same stock.&lt;/li&gt; 
 &lt;li&gt;Feedback loops can cause stocks to maintain their levels within a range or grow or decline.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;Stabilizing Loops – Balancing Feedback&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;Balancing feedback loops are goal-seeking or stability-seeking. They keep a stock at a given value or range of values. They oppose whatever change is imposed on the system.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;Runaway Loops – Reinforcing Feedback&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;A reinforcing feedback loop enhances whatever direction of change is imposed on it, thereby creating a virtuous or vicious cycle of healthy growth or runaway destruction.&lt;/li&gt; 
 &lt;li&gt;Reinforcing loops are found wherever a system element can reproduce itself or grow as a constant fraction of itself. It leads to exponential growth or to runaway collapses over time.&lt;/li&gt; 
 &lt;li&gt;Ask yourself: &quot;If A causes B, is it possible that B also causes A?&quot; Feedback opens up the idea that a system can cause its own behavior.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Ch 2: A Brief Visit to the Systems Zoo&lt;/h4&gt; 
&lt;h5&gt;One-Stock Systems&lt;/h5&gt; 
&lt;p&gt;&lt;em&gt;A Stock with Two Competing Balancing Loops – a Thermostat&lt;/em&gt;&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;A furnace cannot heat a room to a target temperature because heat leaks to the outside. This leak drains away some heat even as the furnace is getting the signal to put it back.&lt;/li&gt; 
 &lt;li&gt;The information delivered by a feedback loop can only affect future behavior; it can&apos;t deliver a signal fast enough to correct behavior that drove the current feedback.&lt;/li&gt; 
 &lt;li&gt;This means that a flow can&apos;t react instantly to a flow. It can only react to a change in stock, and only after a slight delay to register the incoming information.&lt;/li&gt; 
 &lt;li&gt;A stock-maintaining balancing feedback loop must have its goal set to compensate for draining or inflowing processes that affect the stock. Otherwise the process will fall short or exceed the target.&lt;/li&gt; 
 &lt;li&gt;Every feedback loop has its breakdown point, where other loops pull the stock away from its goal more strongly than it can pull back.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;&lt;em&gt;A Stock with One Reinforcing Loop and One Balancing Loop – Population and Industrial Economy&lt;/em&gt;&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Because systems often have several competing feedback loops operating simultaneously, those loops that dominate the system will determine its behavior.&lt;/li&gt; 
 &lt;li&gt;Complex behaviors of systems often arise as the relative strengths of feedback loops shift, causing first one loop and then another to dominate the behavior.&lt;/li&gt; 
 &lt;li&gt;To test the value of a model, ask: Are the driving factors likely to unfold this way? If they did, would the system react this way? What is driving the driving factors?&lt;/li&gt; 
 &lt;li&gt;Model utility depends on not whether its driving scenarios are realistic (since no one can know that for sure), but on whether it responds with a realistic pattern of behavior.&lt;/li&gt; 
 &lt;li&gt;Population has a reinforcing loop of births and a balancing loop of deaths. Capital has a reinforcing loop of investment of output and a balancing loop of depreciation.&lt;/li&gt; 
 &lt;li&gt;A central question of economic development is how to keep the reinforcing loop of capital accumulation growing more slowly than the reinforcing loop of population growth, so that people are getting richer instead of poorer.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;&lt;em&gt;A System with Delays – Business Inventory&lt;/em&gt;&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;A delay in a balancing feedback loop makes a system likely to oscillate.&lt;/li&gt; 
 &lt;li&gt;Changes in stock while waiting for a flow to change can lead us to overreact. If the change in flow is more than expected then we can overreact again and change the flow too much in the other direction.&lt;/li&gt; 
 &lt;li&gt;Delays are strong determinants of behavior, and so we can&apos;t begin to understand the dynamic behavior of systems unless we know where and how long the delays are.&lt;/li&gt; 
 &lt;li&gt;Economies are extremely complex systems; they are full of balancing feedback loops with delays, and they are inherently oscillatory.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;Two-Stock Systems&lt;/h5&gt; 
&lt;p&gt;&lt;em&gt;A Renewable Stock Constrained by a Nonrenewable Stock – an Oil Company&lt;/em&gt;&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Any real physical entity is always exchanging things with its environment, and so any physical, growing system is going to eventually run into some sort of constraint.&lt;/li&gt; 
 &lt;li&gt;This constraint takes the form of a balancing loop that shifts the dominance of the reinforcing loop driving the growth, either by strengthening the outflow or weakening the inflow.&lt;/li&gt; 
 &lt;li&gt;Growth in a constrained environment is called the &quot;limits-to-growth&quot; archetype.&lt;/li&gt; 
 &lt;li&gt;The more capital, the higher the extraction rate, the lower the resource stock, the lower the yield per unit of capital, the lower the profit, the lower the investment rate, and so the lower growth rate of capital.&lt;/li&gt; 
 &lt;li&gt;When you&apos;re building a capital stock dependent on a nonrenewable resource, the higher and faster you grow, the farther and faster you fall.&lt;/li&gt; 
 &lt;li&gt;The real choice in the management of a nonrenewable resource is whether to get rich very fast or to get less rich but stay that way longer.&lt;/li&gt; 
 &lt;li&gt;Raising the price of the resource gives the industry higher profits, so investment goes up, capital stock continues rising, and the more costly resources can be extracted.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;&lt;em&gt;Renewable Stock Constrained by a Renewable Stock – a Fishing Economy&lt;/em&gt;&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;A simplified model is affected by three non-linear relationships: price (scarcer fish cost more), regeneration rate (scarcer fish breed less), and yield per unit of capital (efficiency of fishing).&lt;/li&gt; 
 &lt;li&gt;Nonrenewable resources are stock-limited: The entire stock is available at once and can be extracted at any rate, and so the faster you extract, the shorter its lifetime.&lt;/li&gt; 
 &lt;li&gt;Renewable resources are flow-limited: The stock supports indefinite extraction at a rate equal to its regeneration rate, or else the resource may be driven below a threshold and become non-renewable.&lt;/li&gt; 
 &lt;li&gt;More and more, increases in technology and harvest efficiency have the ability to drive resource populations to extinction.&lt;/li&gt; 
 &lt;li&gt;If the balancing feedback loop is weak, so that capital grows even as the resource dips below its threshold ability to regenerate itself, the resource and industry both collapse.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Part 2: Systems and Us&lt;/h3&gt; 
&lt;h4&gt;Ch 3: Why Systems Work So Well&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;When a system works well, chances are good that you may have observed one of three characteristics: resilience, self-organization, or hierarchy.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;Resilience&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;Resilience is a measure of a system&apos;s ability to survive and persist within a variable environment. The opposite is brittleness or rigidity.&lt;/li&gt; 
 &lt;li&gt;Resilience arises from a rich structure of many feedback loops that can work in different ways to restore a system even after a large perturbation.&lt;/li&gt; 
 &lt;li&gt;It can be very hard to see, unless you exceed its limits, overwhelm and damage the balancing loops, and the system structure breaks down.&lt;/li&gt; 
 &lt;li&gt;Think of resilience as a plateau upon which the system can play, performing its normal functions in safety.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;Self-Organization&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;The capacity of a system to make its own structure more complex is called self-organization.&lt;/li&gt; 
 &lt;li&gt;If we weren&apos;t so blind to the property of self-organization, we&apos;d do a better job of encouraging rather than destroying the self-organizing capacities of systems of which we&apos;re a part.&lt;/li&gt; 
 &lt;li&gt;Self-organization produces heterogeneity and unpredictability, yielding whole new structures or ways of doing things. It requires freedom of experimentation and a certain amount of disorder.&lt;/li&gt; 
 &lt;li&gt;Out of simple rules of self-organization can grow enormous, diversifying crystals of technology, physical structures, organizations, and cultures.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;Hierarchy&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;Complex systems can evolve from simple systems only if there are stable intermediate forms. The resulting complex forms will be naturally hierarchic.&lt;/li&gt; 
 &lt;li&gt;Hierarchies not only give a system stability and resilience, but they reduce the amount of information that any part of the system has to keep track of.&lt;/li&gt; 
 &lt;li&gt;Hierarchies evolve from the lowest level up, and the original purpose of a hierarchy is always to help its originating subsystems do their jobs better.&lt;/li&gt; 
 &lt;li&gt;When a subsystem&apos;s goals dominate at the expense of the total system&apos;s goals, the resulting behavior is called sub-optimization. But just as damaging is too much central control.&lt;/li&gt; 
 &lt;li&gt;To be a highly functional system, hierarchy must balance the welfare, freedoms, and responsibilities of the subsystems and the total system. It must balance autonomy and central control.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Ch 4: Why Systems Surprise Us&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;Everything we think we know about the world is a model. Our models have a strong congruence with the world, but fall far short of representing the real world fully.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;Beguiling Events&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;It&apos;s engrossing to see the world as a series of events, and constantly surprising, because that way of seeing the world has almost no predictive or explanatory value.&lt;/li&gt; 
 &lt;li&gt;We are less likely to be surprised if we can see how events accumulate into dynamic patterns of behavior.&lt;/li&gt; 
 &lt;li&gt;System structure, or the stocks and flows and feedback loops, reveals itself as a series of events over time. It&apos;s the key to understanding not just what is happening, but why.&lt;/li&gt; 
 &lt;li&gt;All systems surprise us because we focus too little on their history, and we are insufficiently skilled at seeing in this history clues to the structures from which behavior and events flow.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;Linear Minds in a Nonlinear World&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;We often are not very skilled in understanding the nature of relationships, especially nonlinear ones, where a cause does not produce a proportional effect.&lt;/li&gt; 
 &lt;li&gt;Nonlinearities foil the reasonable expectation that if a little of some cure did a little good, then a lot of it will do a lot of good. Similarly for destructive actions and harm.&lt;/li&gt; 
 &lt;li&gt;Nonlinearities change the relative strengths of feedback loops, flipping a system from one mode of behavior to another. They are the chief cause of shifting dominance.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;Nonexistent Boundaries&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;The greatest complexities of a system exist at its boundaries, or sources or sinks as stocks that are ignored for the purposes of simplifying a system.&lt;/li&gt; 
 &lt;li&gt;Disorderly, mixed-up borders are sources of diversity and creativity.&lt;/li&gt; 
 &lt;li&gt;We have to invent boundaries for clarity and sanity, and boundaries can produce problems when we forget that we&apos;ve artificially created them.&lt;/li&gt; 
 &lt;li&gt;There are no separate systems. The world is a continuum. Where to draw a boundary around a system depends on the purpose of the discussion –&amp;nbsp;the questions we want to ask.&lt;/li&gt; 
 &lt;li&gt;We are attached to the boundaries that our minds happen to be accustomed to, but boundaries can and should be reconsidered for each new discussion, problem, or purpose.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;Layers of Limits&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;We live in a world where multiple inputs come together to produce multiple outputs, and virtually all of the inputs, and therefore all of the outputs, are limited.&lt;/li&gt; 
 &lt;li&gt;At any given time, the input that is the most important to a system is the one that is the most limiting.&lt;/li&gt; 
 &lt;li&gt;Whenever one factor ceases to be limiting, growth occurs, which itself changes the relative scarcity of factors until another becomes limiting.&lt;/li&gt; 
 &lt;li&gt;To shift attention from the abundant factors to the next potential limiting factor is to gain real understanding of, and control over, the growth process.&lt;/li&gt; 
 &lt;li&gt;Any physical entity with multiple inputs and outputs is surrounded by layers of limits. The choice is not to grow forever, but to decide what limits to live within.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;Ubiquitous Delays&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;Delays are often sensitive leverage points for policy, if they can be made shorter or longer.&lt;/li&gt; 
 &lt;li&gt;Delays determine how fast systems can react, how accurately they hit their targets, and how timely is the information that is passed around. Overshoots, oscillations, and collapses are all caused by delays.&lt;/li&gt; 
 &lt;li&gt;When there are long delays in feedback loops, some sort of foresight is essential. To act only when a problem becomes obvious is to miss an important opportunity to solve a problem.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;Bounded Rationality&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;Bounded rationality means people make reasonable decisions based on the information they have, but they don&apos;t have perfect information, especially about distant parts of the system.&lt;/li&gt; 
 &lt;li&gt;Instead of finding a long-term optimum, we are blundering &quot;satisficers,&quot; discovering within our limited purview a choice we can live with for now, and sticking to it until we are forced to change.&lt;/li&gt; 
 &lt;li&gt;We don&apos;t make decisions that optimize our individual good, much less the good of the system as a whole. We imperfectly interpret our imperfect information.&lt;/li&gt; 
 &lt;li&gt;Seeing how individual decisions are rational within the bounds of the information available does not excuse narrow-minded behavior, but it illuminates why that behavior arises.&lt;/li&gt; 
 &lt;li&gt;If the bounded rationality of each actor does not lead to decisions that furthers the welfare of a system, we must redesign the system to improve the information, incentives, disincentives, goals, stresses, and constraints that affect each actor.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Ch 5: System Traps... and Opportunities&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;We call the system structures that produce common patterns of problematic behavior archetypes.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;Policy Resistance –&amp;nbsp;Fixes that Fail&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;Policy resistance is when balancing loops persist undesirable behaviors despite efforts to invent technological or policy fixes.&lt;/li&gt; 
 &lt;li&gt;Policy resistance comes from the bounded rationalities of the actors in a system, where each actor has goals that are inconsistent with the goals of others.&lt;/li&gt; 
 &lt;li&gt;In such a system, each actor has to put great effort into keeping a system where no one wants to be, because if any actor gives up then the others will drag the system closer to their goals.&lt;/li&gt; 
 &lt;li&gt;The way out: Find a way of aligning the various goals of the subsystems, usually by providing an overarching goal that allows all actors to break out of their bounded rationality.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;The Tragedy of the Commons&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;For a system to be subject to tragedy, the resource must not only be limited, but erodable. Beyond some threshold it cannot regenerate itself and is more likely to be destroyed.&lt;/li&gt; 
 &lt;li&gt;A commons system also needs users of the resource, which have good reasons to increase, and which increase at a rate that is not influenced by the conditions of the commons.&lt;/li&gt; 
 &lt;li&gt;The tragedy of the commons arises from missing (or too long delayed) feedback from the resource to the growth of the users of that resource.&lt;/li&gt; 
 &lt;li&gt;The structure of a commons system makes selfish behavior much more convenient and responsible than behavior that is responsible to the whole community and to the future.&lt;/li&gt; 
 &lt;li&gt;The way out: Educate and exhort, privatize the commons (divide it up so that each person reaps the consequences of his or her own actions), or regulate the commons (enforced by policing and penalties).&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;Drift to Low Performance&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;Drift to low performance happens when a system not only resists policy and stays in a normal bad state, but it keeps getting worse.&lt;/li&gt; 
 &lt;li&gt;The actor believes bad news more than good news, and so the actor thinks things are worse than they are. Standards aren&apos;t absolute, and so as perceived performance slips, the goal is allowed to slip.&lt;/li&gt; 
 &lt;li&gt;The lower the perceived system state, the lower the desired state, and so the less the discrepancy, and so the less the corrective action, and so the lower the system state.&lt;/li&gt; 
 &lt;li&gt;The way out: Keep standards absolute, regardless of performance. And make goals sensitive to the best performances of the past, instead of the worst.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;Escalation&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;Escalation comes from a reinforcing loop set up by competing actors trying to get ahead of each other.&lt;/li&gt; 
 &lt;li&gt;If nothing is done to break the loop, the process usually ends with one or both of the competitors breaking down.&lt;/li&gt; 
 &lt;li&gt;The way out: Unilateral disarmament, thereby refusing to compete and interrupting the reinforcing loop. Or negotiate a new system with balancing loops to control the escalation.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;Success to the Successful –&amp;nbsp;Competitive Exclusion&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;This is a reinforcing feedback loop where winners in a competition receive, in the reward, a means to compete even more effectively in the future. And so winners go on winning, while losers go on losing.&lt;/li&gt; 
 &lt;li&gt;If everything the winner wins is extracted from the losers, then the losers are gradually bankrupted, or forced out, or starved.&lt;/li&gt; 
 &lt;li&gt;The &quot;competitive exclusion principle&quot; says given two species competing for the same resource, one will reproduce faster or use the resource more efficiently, and so it reproduces faster and drives the other to extinction.&lt;/li&gt; 
 &lt;li&gt;One way out is diversification (or exploiting new resources), but this is not a strategy for the poor when the monopolizing firm can crush or buy up all offshoots.&lt;/li&gt; 
 &lt;li&gt;Other ways out: Add a feedback loop to stop any competitor from taking over entirely, or by periodically &quot;leveling the playing field.&quot;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;Shifting the Burden to the Intervenor –&amp;nbsp;Addiction&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;An intervenor may step in to bring a system to a desirable state, but the original problem will reappear since no one has fixed whatever feedback process is not maintaining the state of the system.&lt;/li&gt; 
 &lt;li&gt;The trap is formed if an intervention undermines the capacity of the system to maintain itself. Increased intervention only weakens the capacity of the original system, creating a vicious cycle.&lt;/li&gt; 
 &lt;li&gt;Addiction is finding a quick and dirty solution to the symptom of the problem, which distracts one from the harder and longer-term task of solving the real problem.&lt;/li&gt; 
 &lt;li&gt;The way out: Intervene in a way that strengthens the ability to shoulder its own burdens, which can be cheaper and easier than taking over and running the system. Then remove yourself.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;Rule Beating&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;Rule beating is evasive action to get around the intent of a system&apos;s rules&amp;nbsp;– abiding by the letter, and not the spirit, of the law.&lt;/li&gt; 
 &lt;li&gt;Rule beating becomes a problem when it leads a system into large distortions, unnatural behaviors that would make no sense at all in the absence of the rules.&lt;/li&gt; 
 &lt;li&gt;Rule beating is usually a response of the lower levels in a hierarchy to over-rigid, unworkable, or ill-defined rules from above.&lt;/li&gt; 
 &lt;li&gt;The way out: Better explain the rules, or re-design the rules to release creativity not in the direction of beating the rules, but in the direction of achieving their purpose.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;Seeking the Wrong Goal&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;If the goal of a system is designed badly, if it doesn&apos;t measure what it&apos;s supposed to measure, if it doesn&apos;t reflect the real welfare of the system, then the system can&apos;t produce a desirable result.&lt;/li&gt; 
 &lt;li&gt;Confusing effort with results is one of the most common mistakes in designing systems around a wrong goal.&lt;/li&gt; 
 &lt;li&gt;You have the problem of wrong goals when something stupid happening &quot;because it&apos;s the rule.&quot; You have the problem of rule beating when something stupid happens as a way around the rule.&lt;/li&gt; 
 &lt;li&gt;The way out: Specify indicators and goals that reflect the real welfare of the system.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Part 3: Creating Change –&amp;nbsp;in Systems and in Our Philosophy&lt;/h3&gt; 
&lt;h4&gt;Ch 6: Leverage Points –&amp;nbsp;Places to Intervene in a System&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;Leverage points are frequently not intuitive because as systems become more complex, their behavior becomes more surprising.&lt;/li&gt; 
 &lt;li&gt;In the end, it seems that mastery has less to do with pushing leverage points than it does with strategically, profoundly, madly, letting go and dancing with the system.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;12. Numbers –&amp;nbsp;Constants and parameters such as subsidies, taxes, standards&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;Different hands on the faucets may change the rate at which they turn, but they&apos;re still the same faucets plumbed into the same system, turned according to the same information and goals and rules.&lt;/li&gt; 
 &lt;li&gt;Parameters become leverage points when they go into ranges that kick off one of the higher items on this list.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;11. Buffers -&amp;nbsp;The sizes of stabilizing stocks relative to their flows&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;You can often stabilize a system by increasing a buffer. But if a buffer is too big, the system gets inflexible, and it reacts too slowly.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;10. Stock-and-Flow Structures –&amp;nbsp;Physical systems and their nodes of intersection&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;After a structures is built, the leverage is in understanding its limitations and bottlenecks, using it with maximum efficiency, and refraining from fluctuations or expansions that strain its capacity.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;9. Delays –&amp;nbsp;The lengths of time relative to the rates of system changes&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;Delays that are too short cause over-reaction, oscillations amplified by the jumpiness of the response. Delays that are too long cause damped, sustained, or exploding oscillations, depending on how much too long.&lt;/li&gt; 
 &lt;li&gt;Delay length would be a high leverage point, except for the fact that delays are not often easily changeable.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;8. Balancing Feedback Loops –&amp;nbsp;The strength of the feedbacks relative to the impacts they are trying to correct&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;The strength of a balancing feedback loop is important relative to the impact it is trying to correct. If the impact increases in strength, so must the feedbacks.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;7. Reinforcing Feedback Loops –&amp;nbsp;The strength of the gain of driving loops&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;A system with an unchecked reinforcing loop will ultimately destroy itself.&lt;/li&gt; 
 &lt;li&gt;Slowing down the growth of the reinforcing loop is usually a more powerful leverage point than strengthening balancing loops.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;6. Information Flows –&amp;nbsp;The structure of who does and does not have access to information&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;Given missing information flows, adding or restoring information is usually much easier and cheaper than rebuilding physical infrastructure.&lt;/li&gt; 
 &lt;li&gt;There are so many missing feedback loops because we tend to avoid accountability for our own decisions.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;5. Rules – Incentives, punishments, constraints&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;The rules of a system determine its scope, its boundaries, its degrees of freedom.&lt;/li&gt; 
 &lt;li&gt;Power over the rules is real power. If you want to understand the deepest malfunctions of systems, pay attention to the rules and who has power over them.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;4. Self-Organization – The power to add, change, or evolve system structure&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;Self-organization means changing any aspect of a system lower on this list –&amp;nbsp;adding new balancing or reinforcing loops, or new rules. It is the strongest form of system resilience.&lt;/li&gt; 
 &lt;li&gt;It is basically a matter of an evolutionary raw material –&amp;nbsp;a highly variable stock of information – and a means for experimentation, for selecting and testing new patterns.&lt;/li&gt; 
 &lt;li&gt;This intervention is unpopular, as encouraging variability and experimentation and diversity means &quot;losing control.&quot;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;3. Goals&amp;nbsp;– The purpose or function of the system&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;Even people within systems don&apos;t often recognize what whole-goal system they are serving.&lt;/li&gt; 
 &lt;li&gt;Changing the person at the top of a system can change its goals and therefore radically change its behavior.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;2. Paradigms –&amp;nbsp;The mind-set out of which the system (its goals, structures, rules, delays, parameters) arises&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;The shared idea in the minds of society, the great big unstated assumptions, constitute that society&apos;s paradigm, or deepest set of beliefs about how the world works.&lt;/li&gt; 
 &lt;li&gt;Paradigms are the sources of systems. From them, from shared social agreements about the nature or reality, come system goals and information flows, feedbacks, stocks, flows, and everything else.&lt;/li&gt; 
 &lt;li&gt;There&apos;s nothing physical or expensive or slow in the process of paradigm change. In a single individual it can happen in a millisecond.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;1. Transcending Paradigms&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;Every paradigm, including the ones you hold dear, is a tremendously limited understanding of an immense and amazing universe that is far beyond human comprehension.&lt;/li&gt; 
 &lt;li&gt;If you think no paradigm is right, you can choose whatever one will help to achieve your purpose.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Ch 7: Living in a World of Systems&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;Seeing the future exactly and preparing for it perfectly is unrealizable. Making a complex system do just what you want it to do can be achieved only temporarily, at best.&lt;/li&gt; 
 &lt;li&gt;For any objective other than the most trivial, we can&apos;t optimize. We don&apos;t even know what to optimize.&lt;/li&gt; 
 &lt;li&gt;But we can listen to what the system tells us, and discover how its properties and our values can work together to create something much better than could ever be produced by our will alone.&lt;/li&gt; 
 &lt;li&gt;Living successfully in a world of systems requires our full humanity – our rationality, our ability to sort out truth from falsehood, our intuition, our compassion, our vision, and our morality.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Get the Beat of the System&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;Starting with the behavior of a system forces you to focus on facts, not theories, and helps you avoid any beliefs or misconceptions.&lt;/li&gt; 
 &lt;li&gt;Moreover starting with the history of a system discourages us from defining a problem not by its actual behavior, but by the lack of our favorite solution.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Expose Your Mental Models to the Light of Day&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;Everything you know, and everything everyone knows, is only a mental model.&lt;/li&gt; 
 &lt;li&gt;Exposing your mental models, making them rigorous, testing them against the evidence, and scuttling them if they are no longer supported is simply practicing the scientific method.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Honor, Respect, and Distribute Information&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;Most of what goes wrong in a system is from biased, late, or missing information. So do not distort, delay, or withhold information.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Use Language with Care and Enrich It with Systems Concepts&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;The language and information systems of an organization are not an objective means of describing an outside reality&amp;nbsp;–&amp;nbsp;they structure the perceptions and actions of its members.&lt;/li&gt; 
 &lt;li&gt;Keep language as concrete, meaningful, and truthful as possible. And then enlarge language to make it consistent with our enlarged understanding of systems.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Pay Attention to What Is Important, Not Just What Is Quantifiable&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;Our culture is obsessed with numbers, and has therefore given us the idea that what we can measure is more important than what we can&apos;t measure.&lt;/li&gt; 
 &lt;li&gt;We have been endowed not only with the ability to count, but also with the ability to assess quality. Be a quality detector.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Make Feedback Policies for Feedback Systems&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;The best policies contain meta-feedback loops –&amp;nbsp;or loops that alter, correct, and expand loops. They design learning into the management process.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Go for the Good of the Whole&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;Don&apos;t maximize parts of the system while ignoring the whole. Don&apos;t go to great trouble to optimize something that never should be done at all.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Listen to the Wisdom of the System&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;Before you charge in to make things better, pay attention to the value of what&apos;s already there. Don&apos;t destroy the system&apos;s own self-maintenance policies.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Locate Responsibility in the System&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;This means looking for the ways the system creates its own behavior.&lt;/li&gt; 
 &lt;li&gt;&quot;Intrinsic responsibility&quot; means that the system is designed to send feedback about the consequences of decision making directly, quickly, and compellingly to decision makers.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Stay Humble – Stay a Learner&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;When you&apos;re learning take small steps, constantly monitor, and change course as you find out more about where it&apos;s leading.&lt;/li&gt; 
 &lt;li&gt;Error-embracing is the condition for learning. It means seeking and using –&amp;nbsp;and sharing – information about what went wrong with what you expected or hoped would go right.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Expand Time Horizons&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;In a systems sense, there is no long-term or short-term distinction. Phenomena at different time scales are nested within each other.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;Defy the Discipline&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;Interdisciplinary communication works only if there is a real problem to be solved, and if its representatives are more committed to solving the problem than being academically correct.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;Don&apos;t Erode the Goal of Goodness&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;The most damaging example of the systems archetype &quot;drift to low performance&quot; is the process by which modern industrial culture has eroded the goal of morality.&lt;/li&gt; 
 &lt;li&gt;Don&apos;t weigh the bad news more heavily than the good. And keep standards absolute.&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Untools</title>
      <link>https://tedneward.github.io/Research/thinking/untools/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">thinking/untools/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://untools.co/&quot;&gt;Website&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>4coder</title>
      <link>https://tedneward.github.io/Research/tools/4coder/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">tools/4coder/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;http://4coder.net/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://mr-4th.itch.io/4coder&quot;&gt;Website (Itch)&lt;/a&gt; |&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Simplexity</title>
      <link>https://tedneward.github.io/Research/thinking/simplexity/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">thinking/simplexity/index.html</guid>
      	<description>
	&lt;p&gt;&lt;em&gt;(by Jeffrey Kluger, Hyperion, ISBN 978-1-4013-0301-3)&lt;/em&gt;&lt;/p&gt; 
&lt;h1&gt;Prologue&lt;/h1&gt; 
&lt;p&gt;Cholera outbreak in London; John Snow (physician/investigator) knew there was a source to the outbreak, but needed the data to prove it; canvassed the neighborhood, tracked it to a pump on Broad Street. Knew two things: Plagues were fantastically complex things--with the illness working myriad horrors in the body and spreading across the landscape in myriad ways. But diseases moved through simple choke points too--one person&apos;s handkerchief, one person&apos;s handshake, one handle on one foiled pump--all of them bottlenecks in the pathogen&apos;s flow. Seal off one, stop the disease. The complex illness could collide hard with the simple fix.&lt;/p&gt; 
&lt;p&gt;M.Coy bookshop (Michael Coy and Michael Brasky) in Seattle vs Amazon in the complex art/science of book recommendations. The machines aren&apos;t parsing data as much as steam-shoveling it, digging up vast masses of information; the likes of Brasky and Coy do the very same thing, but finely/instantly using human clues. It&apos;s easy to say that one of the two approaches is more complex than the other; it&apos;s a lot harder to say which one.&lt;/p&gt; 
&lt;p&gt;Complexity is a slipper idea, one that defies almost any effort to hold it down and pin it in place. Things that seem complicated can be preposterously simple; things that seem simple can be dizzyingly cpmlex. Manufacturing plant vs houseplant. Colony of garden ants vs community of people. Sentence vs book, couplet vs song, hobby shop vs corporation. &quot;Human beings are not wired to look at matters that way; we&apos;re suckers for scale. Things that last for a long time impress us more than things that don&apos;t, things that scare us by their sheer size strike us more than things we dwarf. Star vs guppy. Consider a pencil: cedar (wood for the dowel), bauxite (aluminum sleeve), coal (graphite), polymers (eraser); who feeds Paris?&lt;/p&gt; 
&lt;p&gt;Psych is waking up to complexity too. Six-child family vs one-child family, complex in different ways. Political science plays simplicty-complexity, too; equally complex the stock market, crowds, geology, biology, even politics.&lt;/p&gt; 
&lt;p&gt;Trying to distill this down to a working definition of complexity and simplicity is hard.&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Simple things are those things that create order in their environments, the way, say, modern design strips the clutter from a building; but complex things create order too, the way cogs and springs and flywheels of a watch yield a single, simple piece of data--the time--which in turn runs the world.&lt;/li&gt; 
 &lt;li&gt;Simple things create disorder, then, the way an underregulated economy can let markets and monopolies run wild; but complex things overrgulate human affairs can produce a Byzantine mess like the tax code.&lt;/li&gt; 
 &lt;li&gt;We call some software simple because it&apos;s easy to use, never mind that it relies on elaborate complex ancient code; we call older computers complex because they were hard to use, never mind the fact that by today&apos;s standards they&apos;re crude.&lt;/li&gt; 
 &lt;li&gt;Is free-form dance comparatively simple thanks to its lack of rigid rules? Or does that liquidity make it much harder to learn?&lt;/li&gt; 
 &lt;li&gt;Does a committee struggling over a problem lack the straightforward insight of a single wise mind, or is the wise mind blinkered by its biases, while the committee--with its clarifying tensions--is a better, ultimately less coplex arbiter?&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;Brain is a real-time machine, constantly scanning for input and assembling into impressions and actions; that was useful for survival, but it can mislead us now, causing us to overfocus on the most conspicuous features of a thing and be struck--or confused--by that quality. Thus we are confused by beauty, by speed, by big numbers, by small numbers, by our small fear, ....&lt;/p&gt; 
&lt;h1&gt;1: Why is the stock market so hard to predict?&lt;/h1&gt; 
&lt;p&gt;&lt;em&gt;(Confused by Everyone Else)&lt;/em&gt;&lt;/p&gt; 
&lt;h3&gt;Markets react to Baker&apos;s comments on Germany&lt;/h3&gt; 
&lt;p&gt;Treasury Secretary James Baker III, trip to Bonn to discuss Germany lower their interest rates and juice the mark, German finance minister did not agree, and Baker was unhappy: &quot;not particularly pleased&quot;. This spooked the stock market, which triggered the crash of 87. Nothing smart or sensible had taken place that day--but smart and sensible forces had not ben at work, market forces had been. For every market analyst who sees traders as the informed and educated people they surely can be, there are scientists who see them another way: as unthinking actors who obey not so much the laws of economics as the laws of physics. Investors react not so much to variables that are in their interests, but to those that are in everyone else&apos;s interests. When the tide of the market shifts, most of us shift with it; when it flows back the other way, we do the same. We like to think we&apos;re informed by trends, but often as not, we&apos;re simply fooled by them--snookered by what everyone else is doing into concluding that we ought to do the same. &quot;Economic models begin with the assumption of perfect rationality, of a universe of logical people all doing what they can to master their utility; physicists studying economics begin with the assumption that people can&apos;t think.&quot; (J. Doyne Farmer, Santa Fe Institute in New Mexico). &quot;The term we use is zero-intelligence investors&quot; (John Miller, economist at Carnegie Mellon University)&lt;/p&gt; 
&lt;h3&gt;How do we tell if something is simple or complex?&lt;/h3&gt; 
&lt;p&gt;One of Murray Gell-Mann&apos;s favorite ways of deciding whether something is simple or complex is to ask a decidedly unscientific question: How hard is it to describe the thing you&apos;re trying to understand? &quot;Start with the minimum description length as your first inquiry. The shorter it is, the simpler the thing is likely to be. In most cases, you don&apos;t even have to take your language from scientific discourse. It can come from ordinary speech.&quot; But description depends on context, and context changes everything. &quot;Imagine an anthropologist approaching a civilization with which he shares a common language, but which is naive of any culture outside of its own. Now imagine trying to explain to that community a tax-managed mutual fund. What do you think the preamble to that explanation would be?&quot; Description length has its limits; the problem is that it begins with an assumption of a clean and consistent line, with simplicity and short descriptions at one end and complexity and long descriptions at the other. A clean line, however, doesn&apos;t really capture things as much as a somewhat messier arc does.&lt;/p&gt; 
&lt;p&gt;Complexity scientists like to talk about hte ideas of pure chaos and pure robustness--and both are exceedingly simple things. Either extreme is uninteresting. Where you&apos;d find rea complexity would be somewhere between those two states, the point at which the molecules begin to climb from disorder, sorting themselves into something interesting and organized, but catching themselves before they descend down the other side of the complexity hill. The more precisely the object can balanc at the pinnacle of that arc, the more complex it is. &quot;It&apos;s the region between order and disorder that gives you complexity, not the order and disorder at the ends.&quot;&lt;/p&gt; 
&lt;p&gt;Things are not even that straightforward as even that explanation suggests, since any one system is not necessarily composed of just one point on the arc. Many different points come into play and the question of complexity turns on which one you choose. A foot-long copper pipe might be nearly as static as frozen carbon, but take in the vast array of skyscraper plumbing (of which it is just a part) and things look a lot more complicated.&lt;/p&gt; 
&lt;h3&gt;Handshakes&lt;/h3&gt; 
&lt;p&gt;Same holds true for human behavior. Consider all that goes into a handshake.&lt;/p&gt; 
&lt;p&gt;Any system (chemical, physical, cultural, fiscal) must be seen at all levels before you can begin to make a real determination about whether it can truly be called complex. &quot;Ask me why I forgot my keys this morning and the answer might be simply that my mind was on something else. Ask me about the calcium channels in my brain that drive remembering or forgetting and you&apos;re asking a much harder question.&quot;&lt;/p&gt; 
&lt;h3&gt;Markets&lt;/h3&gt; 
&lt;p&gt;Blake LeBaron (Brandeis University) has an entire (virtual) stock exchange of his own. Over the years he&apos;s developed algorithms that allow him to simulate any kind of market--bull, bear, static, active, mixed--and then release simulated investors into that environment to see how they behave. On the whole, artificial traders behave precisely like the real ones, which is to say that they never show much imagination. &quot;At the beginning of a run, all the traders just wobble around a bit, looking for guidance. Then someone will try a new strategy and do quite well at it and the others will notice. Pretty soon, a few more are trying it and it starts to get popular, like a clothing fad. Ultimately everyone starts to converge on that strategy and it dominates the market, precisely the way real markets behave.&quot; But it only goes so long--if everyone is chasing the same dollar in the same way, it takes only a few players to cash out before all of the other shares start to lose value. This is the classic bubble-popping phenomenon, one that&apos;s familiar to all investors. &quot;The market first becomes too stable, too robust, then it collapses into instability.&lt;/p&gt; 
&lt;h3&gt;Fish schools&lt;/h3&gt; 
&lt;p&gt;Fishkeepers (aquarist) can learn a lot about chemistry, botany, animal behavior by watching what takes place on the other side. Study how schools of fish manage their fluid movements without any evident alpha fish leading. (Bird flocking, too?) In order for a traveling fish school to remain cohesive, all of the individuals must maintain a position no more or no less than about a single body length from every individual around them. Get too close, and you collide and compete. Drift too far apart, and you begin to stand out--never a good idea when predators lurk. The most important thing the fish thus keep in mind is not where they&apos;re going or who&apos;s leading them there, but making sure they don&apos;t fall out of ranks along the way.&lt;/p&gt; 
&lt;p&gt;But who&apos;s in charge of the motion? Schools do require at least a few leaders (&quot;informed individuals&quot;), but not many. In an average-sized school, it takes only about 5% of the members to know the proper route and set out in that direction. What&apos;s more, as the school grows, that leadership share actually shrinks, so that as few as one in a hundred need have any idea what the goal is and yet they still lead all the others.&lt;/p&gt; 
&lt;h3&gt;Power of combined brainpower&lt;/h3&gt; 
&lt;p&gt;The jellybean contest: The average of everybody&apos;s guess will come signficantly closer than any one person&apos;s guess. &quot;It happens virtually every time; it&apos;s freakish and it still amazes me.&quot; (Brooke Harrington, professor of public policy, Brown University) More than just laws of probability here--we could all guess high or guess low. Instead, we all guess in such a precise distribution around the target that together we practically hit it. The greater the number of people participating, the closer the collaborative guess becomes.&lt;/p&gt; 
&lt;p&gt;Harrington wanted to pursue this more-is-more finding further; examined investment clubs (bringing largely inexperienced traders together in the hopes that they will collaboratively choose better). Confirmation: In general, the average group did better than the average individual; and larger, more diverse groups did better than smaller, more homogeneous ones.&lt;/p&gt; 
&lt;h3&gt;The fallacy of the &quot;jumpy market&quot;&lt;/h3&gt; 
&lt;p&gt;One of the great bits of stock market wisdom is that investors of all kinds are jumpy and esily frightened by bad headlines. In 1989, economists selected the 49 most newsmaking events from 1941 to 1987 (including Pearl Harbor, JFK&apos;s assassination, Reagan&apos;s assassination attempt, Chernobyl). Did the news shake the market? Using the Standard &amp;amp; Poor&apos;s Index as their yardstick, what they found was that even on the S&amp;amp;P, bad news in the papers did not have to mean bad news on Wall Street. Biggest drop of all 49 days was a 6.62% drop in 1955 when President Eisenhower had a hard attack. (Compare: 23% loss in 1929 and 1987.) Next biggest drops were 5.38% when North Korea invaded in 1950, and 4.37% loss after Pearl Harbor. Study next looked the other way, examining biggest drops and looking for the news of that day. In only nine of the cases did a nonfinancial news story like international tensions or a political shake-up sem to account for the market movement.&lt;/p&gt; 
&lt;h3&gt;Fairness&lt;/h3&gt; 
&lt;p&gt;One other exceedingly complex and uniquely emotional variable individual traders bring to the table: fairness; what it looks like or feels like when something looks like a square deal or when the bad guys are about to get away with omething. Researchers long wondered just how powerful the human fairness impulse is. Samuel Bowles (professor economics, University of Siena (Italy)) conducted a fairness test: Two volunteers, V1 and V2, are given a quantity of money to share which they get to keep if they can agree on how to divide it. V1 proposes the split, V2 accepts it. Perfectly rational actors will accept any split, since it&apos;s by definition more than what they had when they came in, but the average accepted bid is 57%/43%. &quot;When you ask them why they reject a 20% share, they answer, &apos;Because that son of a bitch was getting 80%.&apos; So people are willing to pay 20% just to punish a son of a bitch.&quot;&lt;/p&gt; 
&lt;h3&gt;Conclusion&lt;/h3&gt; 
&lt;p&gt;The key in all of these situations is to recognize that there is indeed great wisdom in what everyone else knows. But there is sometimes greater wisdom in knowing what only you know. There may be no such thing as mastering the perfect balance of those skills, but there is such a thing as becoming powerfully--and in the case of the markets, profitably--good at it.&lt;/p&gt; 
&lt;h1&gt;2: Why is it so hard to leave a burning building or an endangered city&lt;/h1&gt; 
&lt;p&gt;&lt;em&gt;(Confused by Instincts)&lt;/em&gt;&lt;/p&gt; 
&lt;p&gt;(9/11, Ed Schmitt, and his decision to leave the building (Tower One) when the first plane struck Tower Two, when so many others stayed.) Ultimately, we are misled by our most basic instincts--the belief that we know where the danger is and how best to respond to keep ourselves alive, whenin fact we sometimes have no idea at all. It&apos;s the job of the people who think about such matters to tease all these things apart and put them back together in buildings and vehicles that keep their occupants alive; it&apos;s the job of those occupants to learn enough about the systems so that they have the sense to use them.&lt;/p&gt; 
&lt;h3&gt;Buildings&lt;/h3&gt; 
&lt;p&gt;20,000 people in a building or 1/2 million in a coastal city occupy the same spot on the complexity spectrum as air molecules filling a room--moving randomly and chaotically in all directions, filling all the available space more or less uniformly. Very active, but also very simple and disordered. Send the same people on a stampede down stairways or highways and things quickly grow overloaded and grind to a halt, jumping to the other end of the complexity arc--robust, unchanging, frozen in place, but every bit as simple as the ever-shifting air molecules. It&apos;s in the middle of the arc, where the molecules just begin to take some shape (or the people just begin to move to the exits) that true complexity begins to emerge.&lt;/p&gt; 
&lt;h3&gt;Water&lt;/h3&gt; 
&lt;p&gt;Best way to understand the manner in which people move &lt;em&gt;en masse&lt;/em&gt; may be to understand the way water does the same, particularly how it navigates around obstacles or breakwaters. A foundered boat or tumbled boulder creates turbulence; a non-sensical post in the middle of the floor does the same. That turbulence staggers their arrival slightly, allowing them to stream through the opening in a reasonably controlled flow, rather than colliding there at once and causing a pileup. The obstacle keeps you at the top of the complexity arc, preventing you from reaching the frozen end. &quot;By adding a little noise to the system you produce coherence in the flow.&quot;&lt;/p&gt; 
&lt;p&gt;This, of course, assumes people behave sensibly. For one thing, people have different levels of decision-making skills, with some behaving more rationally than others. For another, all of us have a tendency to believe that the rest of the group knows what it&apos;s doing, and thus will gravitate toward a popular exit simply because other people have chosen it, even if the alternative is perfectly safe and much less congested. Finally, information tends to get distributed unevenly, with some people learning about an emergency first and acting before the others.&lt;/p&gt; 
&lt;h3&gt;Stairs&lt;/h3&gt; 
&lt;p&gt;Simulations and models can&apos;t simulate emotion/fear; for example, the only thing that ought to count in stairways is pure speed; anything short of a stampede should get the building emptied in a hurry. But pure speed is hard to maintain. It doesn&apos;t take much for a smooth stream of downward-flowing evacuees to turn turbulent. For one thing, people from middle floors who enter the stairwell somewhere in mid-current can cause things to slow or stop. The delay flows back along the queue like a ripple through water or cars entering a highway. Sequential evacuation is the best way to handle this problem, with people on lower floors leaving first and each high floor following successively; but nobody pretends that people fearing for their lives would wait patiently at their desks until their floor is called. The design of the stairways themselves must provide the extra margin of speed. (Guiderails; lighting; fluorescent tape.) But stairways were too narrow, not taking into account that two-thirds of 2001 Americans are overweight or obese.&lt;/p&gt; 
&lt;h3&gt;Social parts of an evacuation&lt;/h3&gt; 
&lt;p&gt;Social norms about who&apos;s making decisions change during the day-to-day, and all these norms are broken in an emergency. What appears in a time of emergency is something complexity researchers call the emergent norm--that is a whole new set of rules.&lt;/p&gt; 
&lt;h1&gt;3: How does a single bullet start a world war?&lt;/h1&gt; 
&lt;p&gt;&lt;em&gt;(Confused by Social Structure)&lt;/em&gt;&lt;/p&gt; 
&lt;h1&gt;4: Why do the jobs that require the greatest skills pay the least? Why do companies with the least to sell often earn the most?&lt;/h1&gt; 
&lt;p&gt;&lt;em&gt;(Confused by Payoffs)&lt;/em&gt;&lt;/p&gt; 
&lt;h1&gt;5: Why do people, mice, and worlds die when they do?&lt;/h1&gt; 
&lt;p&gt;&lt;em&gt;(Confused by Scale)&lt;/em&gt;&lt;/p&gt; 
&lt;h1&gt;6: Why do bad teams win so many games, and good teams lose so many?&lt;/h1&gt; 
&lt;p&gt;&lt;em&gt;(Confused by Objective)&lt;/em&gt;&lt;/p&gt; 
&lt;h1&gt;7: Why do we always worry about the wrong things?&lt;/h1&gt; 
&lt;p&gt;&lt;em&gt;(Confused by Fear)&lt;/em&gt;&lt;/p&gt; 
&lt;h1&gt;8: Why is a baby the best linguist in the room?&lt;/h1&gt; 
&lt;p&gt;&lt;em&gt;(Confused by Silence)&lt;/em&gt;&lt;/p&gt; 
&lt;h1&gt;9: Why are your cellphone and camera so absurdly complicated?&lt;/h1&gt; 
&lt;p&gt;&lt;em&gt;(Confused by Flexibility)&lt;/em&gt;&lt;/p&gt; 
&lt;h1&gt;10: Why are only 10% of the world&apos;s medical resources used to treat 90% of its ills?&lt;/h1&gt; 
&lt;p&gt;&lt;em&gt;(Confused by False Targets)&lt;/em&gt;&lt;/p&gt; 
&lt;h1&gt;11: Why does complexity science fall into the arts?&lt;/h1&gt; 
&lt;p&gt;&lt;em&gt;(Confused by Loveliness)&lt;/em&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Systems Thinking</title>
      <link>https://tedneward.github.io/Research/thinking/systems-thinking/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">thinking/systems-thinking/index.html</guid>
      	<description>
	&lt;h2&gt;Articles/Blog posts&lt;/h2&gt; 
&lt;p&gt;&lt;a href=&quot;https://alexdanco.com/2021/08/21/dancoland/&quot;&gt;Dancoland&lt;/a&gt;: A &lt;em&gt;great&lt;/em&gt; webcomic about how to learn systems thinking analysis. Stocks, flows, etc.&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://apenwarr.ca/log/20201227&quot;&gt;Systems design explains the world: volume 1&lt;/a&gt; | &lt;a href=&quot;https://apenwarr.ca/log/?m=202304&quot;&gt;Systems design 2: What we hope we know&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://apenwarr.ca/log/20180724&quot;&gt;Books that explain (parts of) how the world really works&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Quit</title>
      <link>https://tedneward.github.io/Research/thinking/quit/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">thinking/quit/index.html</guid>
      	<description>
	&lt;p&gt;&lt;em&gt;(by Annie Duke, Penguin Random House, ISBN 9780593544020)&lt;/em&gt;&lt;/p&gt; 
&lt;h1&gt;Prologue: The Gaffed Scale&lt;/h1&gt; 
&lt;p&gt;Muhammad Ali: GOAT, and yet didn&apos;t know when to quit&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Grid vs Quit&lt;/strong&gt; We view grit and quit as opposing forces. While grit is a virtue, quit is a vice. Some goals are just not reachable, no matter how hard you continue. We ought not to confuse hindsight with foresight, which is what these aphorisms do. &lt;em&gt;(Survivor bias)&lt;/em&gt; Success does not lie in sticking to things; it lies in picking the right thing to stick to and quitting the rest.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Wrapped in Euphemism.&lt;/strong&gt; Lindsey Vonn: quit, but then said &quot;I&apos;m not giving up! I&apos;m just starting a new chapter.&quot; The idea of quitting is such a bitter pill to swallow that we have to take it with a spoonful of sugar, or in this case, a spoonful of euphemism, the most famous of which is &quot;pivot.&quot; We ought to stop thinking that we need to wrap the idea of quitting in bubble wrap. When it comes to quitting, the scale is gaffed (butcher&apos;s thumb on the scale to cheat customers).&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Science Says.&lt;/strong&gt; The book &lt;em&gt;Grit&lt;/em&gt; is interpreted to mean &quot;Never quit&quot; but that&apos;s misinterpretation. She has herself written about the importance of trying lots of things (which requires that you quit lots of other things) to find the thing you want to stick with. There is a rich universe of science studying the human tendency to persevere &lt;em&gt;too long&lt;/em&gt;, particularly in the face of bad news. Sunk cost, status quo bias, loss aversion, escalation of commitment, and so on. Kahneman&apos;s and Thaler&apos;s work. Science is telling us every day, we tend to stick to things too long in the face of signals that we ought to quit.&lt;/p&gt; 
&lt;h1&gt;Section I: The Case for Quitting&lt;/h1&gt; 
&lt;h2&gt;Ch 1: The Opposite of a Great Virtue is Also a Great Virtue&lt;/h2&gt; 
&lt;p&gt;&lt;strong&gt;The Invisible Men at the Top of the World.&lt;/strong&gt; Mt Everest: a place where people really should learn to quit sooner. Three climbers: Dr Stuart Hutchison, Dr John Taske, Lou Kasischke. Part of a commercial guided expedition of Everest. Expedition leader stressed importance of having strictly-observed turnaround times (return to camp if you&apos;ve not yet reached your destination) for each day&apos;s climb up the mountain. (Eight times more people die on Everest on the way down than on the way up.) Turnaround times are there to prevent people from making poor decisions to keep going when they&apos;re in the shadow of the summit, building into a climbing plan three critical concepts:&lt;/p&gt; 
&lt;ol&gt; 
 &lt;li&gt;persistence is not always a virtue&lt;/li&gt; 
 &lt;li&gt;making a plan for when to quit should be done long before you are facing the quitting decision&lt;/li&gt; 
 &lt;li&gt;the turnaround time is a reminder that the real goal in climbing Everst is not to reach the summit, but to return safely to the base of the mountain&lt;/li&gt; 
&lt;/ol&gt; 
&lt;p&gt;&lt;em&gt;(Simple Rules!)&lt;/em&gt;&lt;/p&gt; 
&lt;p&gt;Hutchison, Taske, Kasischke were part of one of three expeditions, making the climb too crowded. Trio got stuck, with expedition leader, behind a group of incompetent climbers. At 11:30am, Hutchison called a meeting, realized that turnaround time was 1pm, and they wouldn&apos;t make it. Turned around. Made it safely back to the camp. Rest of the group was well-documented (book &lt;em&gt;Into Thin Air&lt;/em&gt;, documentary &lt;em&gt;Everest&lt;/em&gt;, 2015 film &lt;em&gt;Everest&lt;/em&gt;), expedition leader Hall (who set the turnaround time!) and four others who reached the summit died on various parts of their descent back. But we don&apos;t know the Hutchison/Taske/Kasischke trio, because we tend to think about only one side of the human response to adversity (the ones who go for it). Even in this life-or-death situation, where quitting is the right decision, we don&apos;t remember the quitters at all.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Quitting is a Decision-Making Tool.&lt;/strong&gt; Grit and quit are two sides of the same exact decision; you can&apos;t decide one thing without deciding the other. Grit is what gets you up the mountain, but quit is what tells you when to come down. &lt;strong&gt;&lt;em&gt;&quot;If I had to skill somebody up to get them to be a better decision-maker, quitting is the primary skill I would choose, because the option to quit is what allows you to react to a changing landscape.&quot;&lt;/em&gt;&lt;/strong&gt; Any decision is made under some degree of uncertainty, stemming from two sources:&lt;/p&gt; 
&lt;ol&gt; 
 &lt;li&gt;The world is stochastic: luck makes it difficult to predict exactly how things will turn out, at least in the short run. We operate not with certainties but with probabilities.&lt;/li&gt; 
 &lt;li&gt;When we make decisions, we don&apos;t have all the facts.&lt;/li&gt; 
&lt;/ol&gt; 
&lt;p&gt;When you take all these aspects of uncertainty together, it makes decision-making hard. But, after you&apos;ve set out on a particular course of action, &lt;strong&gt;&lt;em&gt;new information will reveal itself to you&lt;/em&gt;&lt;/strong&gt;. Feedback. Quitting is the tool that allows you to keep from being paralyzed by uncertainty or stuck forever in every decision you make. Quitting is what allows companies to maximize speed, experimentation, and effectiveness in highly uncertain environments.&lt;/p&gt; 
&lt;p&gt;Richard Pryor--greatest comedian ever--would routinely do shows at the Comedy Store on Sunset Strip with nothing prepared beyond &quot;a couple of ideas&quot; or &quot;one or two jokes at the most&quot; and bomb. The next night, he&apos;d drop everything that didn&apos;t work--nearly the whole set--and expand on whatever got a titter. At the end of 30 days, he had 40 minutes of incredible material. &lt;em&gt;(OODA! He had a freakin 24-hour OODA loop!)&lt;/em&gt;&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;The Siren Song of Certainty.&lt;/strong&gt; Uncertainty is an impediment to making good decisions about quitting. Only one choice--the choice to persevere--lets you (eventually) find out the answer. The desire for certainty is the siren song calling us to persevere, because perseverance is the only path to avoiding the ambiguity of not knowing how it all turned out.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;The Super Bowl is a Corporate Graveyard.&lt;/strong&gt; The list of Super Bowl advertisers in Tom Brady&apos;s football career who&apos;ve failed is long and impressive: AOL, Blockbuster, Circuit City, CompUSA, Gateway, Radio Shack, Sears. Super Bowl ads are big and expensive--if you could afford one, you were a big, successful company. Each couldn&apos;t maintain their success--the scale must be gaffed against quitting not just for individuals but for businesses as well. &lt;strong&gt;&lt;em&gt;The road to sustained profitability for a business is not only about sticking to a strategy or business model, it is also about surveying and reacting to the changing landscape.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;&quot;Know When to Hold &apos;Em, Know When to Fold &apos;Em&quot;: But Mostly, Fold &apos;Em.&lt;/strong&gt; Three of the four things from Kenny Rogers&apos; lyric are about quitting. When it comes to cutting your losses at the poker table, he &quot;got it&quot;. Optimal quitting might be the most important skill separating great poker players from amateurs. Top poker players are know when to fold &apos;em: Pros play a mere 15% to 25% of the two-card starting combinations they are dealt in Texas Hold &apos;Em. Amateurs stick with over half. &lt;strong&gt;&lt;em&gt;To be good at the game you ahve to learn to live with the idea that you folded some hands that might&apos;ve won.&lt;/em&gt;&lt;/strong&gt; Quitting a game is a decision fraught with uncertainty because it is never clear exactly why you are losing--you could be playing really well but losing because of an unlucky run of cards. In other words, if you want to glame your losses on luck and keep playing, you can always find a way to do that. Quitting a game when you&apos;re losing is the only way to guarantee you won&apos;t get those chips back in that game, which makes quitting when you are losing difficult. &lt;em&gt;(Again, here&apos;s the power of a stopping rule: Take the emotion and ego out of the decision by creating the stopping rule before it becomes an issue.)&lt;/em&gt;&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Summary:&lt;/strong&gt;&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;We tend to celebrate people who respond to adversity by soldiering on. The quitters, in comparison, are invisible.&lt;/li&gt; 
 &lt;li&gt;If we don&apos;t notice the decision-making of the quitters, it&apos;s hard to learn from them.&lt;/li&gt; 
 &lt;li&gt;Quitting a course of actio is sometimes the best way to win in the long run, whether you&apos;re cutting your losses at the poker table or getting to climb another day.&lt;/li&gt; 
 &lt;li&gt;Quit and grit are two sides of the exact same decision.&lt;/li&gt; 
 &lt;li&gt;Decision-making in the real world requires action without complete information. Quitting is the tool that allows us to react to new information that is revealed &lt;em&gt;after&lt;/em&gt; we make a decision.&lt;/li&gt; 
 &lt;li&gt;Sticking with a course of action is the only way to find out for sure how it will turn out. Quitting requires being okday with not knowing what might have been.&lt;/li&gt; 
 &lt;li&gt;Having the option to quit helps you to explore more, learn more, and ultimately find the right things to stick with.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Ch 2: Quitting on Time Usually Feels Like Quitting Too Early&lt;/h2&gt; 
&lt;p&gt;In 2002 Stuart Butterfield built &lt;em&gt;Game Neverending&lt;/em&gt;, a cooperative game, and in 2004 it failed due to lack of funding in post-dot-com-crash environment. They salvaged one feature, an inventory of objects the players accumulated, represented by a shoebox of photos, which became Flickr, which within a year they sold to Yahoo for $25m. Butterfield left Yahoo in 2008 and created a new game, &lt;em&gt;Glitch&lt;/em&gt;, secured a bunch of funding (due to Flickr&apos;s rep) and released it in 2011; it looked amazing, and by Nov 2012, it had a devoted following of 5,000 users playing 20+ hrs/week. Problem: paid users were less than 5% of the user base, the rest having done the free sign-up; over 95% of new users played &lt;em&gt;Glitch&lt;/em&gt; for less than seven minutes and never returned. Made a major PR push, yet after a particularly good push, Nov 12, Butterfield sent an email to investors: &quot;I woke up this morning with the dead certainty that Glitch was over.&quot; He was able to peek into the future, and saw that in the range of possible outcomes, the probability was too high that the game would end up being a money pit. The math of the conversion rate just didn&apos;t work. &quot;I think I knew this six weeks ago and I mistook denial for prudence (in the sense of making sure that we didn&apos;t give up too early). But there are just too many things in the &apos;against&apos; column.&quot; This freed him and the company to work on a different product: the &quot;Searchable Log of All Conversation and Knowledge&quot;, aka Slack.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Quit While You Still Have a Choice.&lt;/strong&gt; &lt;strong&gt;&lt;em&gt;Quitting on time wil usually feel like quitting too early.&lt;/em&gt;&lt;/strong&gt; Making good decisions about quitting requires mental time travel since the worst time to make a decision is when you&apos;re in it. That&apos;s when you are in the present, facing down the decision whether or not to cut your losses, unable to see past what is happening right now. When we do think about the future, we are often considering our hopes, our goals, our ambitions, and that optimism means that too often we allow a disastrous future to hurtle toward us, noticing it only as it&apos;s arriving on our doorstep. There is a well-known heuristic in management consulting that &quot;the right time to fire someone is the first time it crosses your mind&quot;. But since this is a decision made under uncertainty, we tend to persist too long.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Thinking in Expected Value.&lt;/strong&gt; To get the stick-or-quit decision right, you need to make an educated guess at the probability that things will go your way and the probability that things will go against you in order to figure out if the good stuff will occur enough of the time to warrant continuing on the same path. You need to think in Expected Value (EV). EV helps you answer two questions:&lt;/p&gt; 
&lt;ol&gt; 
 &lt;li&gt;it tells you whether any option you are considering is going to be, on balance, positive or negative for you in the long run.&lt;/li&gt; 
 &lt;li&gt;it allows you to compare different options to figure out which is the better choice, where &quot;better choice&quot; is the one that carries the highest expected value.&lt;/li&gt; 
&lt;/ol&gt; 
&lt;p&gt;To determine the EV for any course of action, you start with identifying the range of reasonably possible outcomes, each of which will have some probability of occurring. If you multiply the probability of the outcome (p) with the outcome&apos;s good-or-bad (o), and add that all together, you get the EV. Example: fair coin flip (.5 heads, .5 tails) where heads = +$100, tails = -$50. Heads &lt;code&gt;p * o&lt;/code&gt; is +$100 * .5 = +$50, Tails &lt;code&gt;p * o&lt;/code&gt; is -$50 * .5 = -$25, EV is (+$50 + -$25), or +$25, or a positive EV. Example 2: Unfair coin flip, heads +$50 at p 0.9 (+$45) vs tails -$100 at p 0.1 (-$10), EV is +$35. Example 3: heads +$100,000 at p 0.01 (+$1,000), tails -$100 at p 0.99 (-$99), EV = +$901. &lt;em&gt;(All of this assumes we get 100 coin flips, though--if it&apos;s only one flip, then the decision-making changes here somewhat, I would think? I think Duke makes a subtle allowance for this: &quot;Of course, that&apos;s a much riskier bet than the other two bets. Managing risk is the subject of many other books, but not this one.&quot;)&lt;/em&gt;&lt;/p&gt; 
&lt;p&gt;Next, compare the EV for each option you might be considering. &quot;If I were to switch and do something else, would that have a higher EV than the thing I&apos;m currently doing?&quot; Winning poker players aren&apos;t thinking about trying to win a single hand, come what may--they know while any two cards can win, only some hands can win enough of the time to make them worth pursuing. They are making decisions based on whether playing or folding will have the greater EV.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Quitting Decisions are Expected-Value Decisions.&lt;/strong&gt; 2001: Duke gets an email from a reader who wanted help working through a decision about whether to quit her job. Duke asks, &quot;A year from now, if you stay, what&apos;s the probability that you&apos;re going to be unhappy at the end of that year?&quot; 100%. &quot;A year from now, if you take the new job, what&apos;s the probability that you&apos;re going to be unhappy?&quot; &quot;Not sure&quot; &quot;Is it 100%?&quot; &quot;Definitely not.&quot; Enlightenment. Duke reframed the question as an EV problem.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Time Travelers from the Past.&lt;/strong&gt; Thinking in expected value is a kind of mental time travel, propelling yourself into the future to glimpse the range of possible outcomes and take some reasonable guess at how likely each of them is. As a means to becoming a better quitter, this works in both directions: You can get the benefit of listening to a message &lt;em&gt;from the past&lt;/em&gt;. Adm William McRaven, one of the world&apos;s most respected figures on military strategy, US foreign policy, and counterterrorism ops, is a longtime student of military history: &quot;Probably three quarters of the books behind me (on his wall of bookshelves) are history books about battles that went well and battles that went wrong.&quot; When you are making a decision about whether to quit, you need to listen to those people from the past who are giving you important advice, whether its others or yourself.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Flipping Coins.&lt;/strong&gt; 2013: Steven Levitt (author, &lt;em&gt;Freakonomics&lt;/em&gt;) put up a website inviting visotrs to flip a virtual coin to help them decide quit-or-stick. They would register what they were stuggling with, among a variety of types of decisions, like &quot;Should I quit my job or stay?&quot; or &quot;Should I leave my relationship?&quot; or &quot;Should I stay in college?&quot;. The site would assign one side of the decision to Heads, the other to Tails, and then randomly flip the coin. 20,000 people over the course of a year did this. Obviously, these people must have felt that the choice of quit-or-stick was so close, so 50-50, that flipping a coin to help them decide seemed like a reasonable option. Theoretically, they would be equally likely to be happier with either heads or tails, stick or quit. But this isn&apos;t what Levitt found. When he followed up with the coin flippers at 2 months and 6 months later, he discovered that for the big life decisions, people who quit were happier on average than people who stuck, whether they quit on their own or after the coin flip suggested quitting. &lt;strong&gt;&lt;em&gt;While the decisions may have felt close to the people making them, they were actually not close at all. As judged by the participants&apos; happiness, quitting was the clear winner.&lt;/em&gt;&lt;/strong&gt; Because people were much happier when they quit what they considered a close decision, that shows that people are generally quitting too late. Levitt concluded, &quot;The results of this paper suggest that people may be excessively caution when facing life-changing choices.&quot; Corollary: &lt;strong&gt;&lt;em&gt;When people quit on time, it will usually feel like they are quitting too early, because it will be long before they experience the choice as a close call.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Jumping the Shark.&lt;/strong&gt; (&lt;em&gt;Happy Days&lt;/em&gt; pop-culture reference.) We have an expectation that people ought to have seen in foresight what we can so easily see in hindsight. And when they don&apos;t, we can&apos;t believe how obtuse they are. That&apos;s the point of jumping the shark: It&apos;s mocking someone who doesn&apos;t quit on time, no matter that it&apos;s much harder to see the shark in foresight. But the sad thing is that as much as we make fun of people who quit too late, when someone does manage to quit on time, we mock them for quitting too early. That&apos;s the &quot;quitting bind&quot;.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;The Quitting Bind.&lt;/strong&gt; Dave Chappelle quits &lt;em&gt;Chappelle&apos;s Show&lt;/em&gt; in season 3, at the top of his game. Rumors swirled why. He quit because he could see two things: (1) he was unhappy in a future where he continued the show, and (2) he could see the shark: he was close to crossing the line between his audience laughing with him, and his audience laughing at him. Similar disappointment around Phoebe Waller-Bridge (2019) ending &lt;em&gt;Fleabag&lt;/em&gt;, which in two seasons (2016, 2019) earned massive worldwide acclaim. Fans beg for more, despite Waller-Bridge&apos;s explanation that ending the series was consistent with the arc of the title character.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Sunmmary:&lt;/strong&gt;&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Quitting on time usually feels like quitting too early.&lt;/li&gt; 
 &lt;li&gt;The hardest time to make a quitting decision is when you&apos;re in it.&lt;/li&gt; 
 &lt;li&gt;Our intuition is that quitting will slow down our progress. The reverse is actually true. If you walk away from something that is no longer worthwhile, that frees you up to switch to something that is more likely to help you achieve your goals--and you&apos;ll get there faster.&lt;/li&gt; 
 &lt;li&gt;When the time is objectively right to quit, nothing particularly dire will be happening right at that moment. Getting the timing right means looking into the future and seeing that the chances things will go your way are too slim.&lt;/li&gt; 
 &lt;li&gt;Thinking in expected value (EV) helps you figure out if the path you are on is worth sticking to. EV is not just about money. It can be measured in health, well-being, happiness, time, self-fulfillment, satisfaction in relationships, or anything else that affects you.&lt;/li&gt; 
 &lt;li&gt;If you feel like the choice between persevering and walking away is a close call, it&apos;s likely that quitting is the better choice.&lt;/li&gt; 
 &lt;li&gt;In hindsight, we can see when someone has waited too long to quit, and we tend ot be harsh in our judgment of those people. But when smoeone quits before it seems obvious to others, we mock them for quitting too early. That&apos;s the quitting bind.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Ch 3: Should I Stay or Should I Go?&lt;/h2&gt; 
&lt;p&gt;&lt;strong&gt;Summary:&lt;/strong&gt;&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;A key finding of prospect theory is &lt;em&gt;loss aversion&lt;/em&gt;, the phenomenon whereby the emotional impact of a loss is greater than the corresponding impact of an equivalent gain.&lt;/li&gt; 
 &lt;li&gt;Loss aversion creates a preference for options associated with a lower chance of incurring a loss. It makes us risk averse.&lt;/li&gt; 
 &lt;li&gt;When we are in the gains, we have a tendency to quit too early in order to avoid the risk of giving those gains back. In other words, we like to quit while we&apos;re ahead.&lt;/li&gt; 
 &lt;li&gt;When we are in the losses, we become risk seekers. We want to keep going, hoping we can avoid ever having to realize the loss. Kahneman characterizes this as &lt;em&gt;sure-loss aversion&lt;/em&gt;. In other words, we like to stick when we&apos;re behind.&lt;/li&gt; 
 &lt;li&gt;Quitting on time usually feels like quitting too early, and the &lt;em&gt;usually&lt;/em&gt; part is &lt;em&gt;specifically when you&apos;re in the losses&lt;/em&gt;.&lt;/li&gt; 
 &lt;li&gt;Retail investors show this pattern of quitting when they&apos;re ahead and sticking when they&apos;re behind.&lt;/li&gt; 
 &lt;li&gt;Even expert investors don&apos;t get their quitting decisions just right. They outperform on their buying decisions but underperform on their selling decisions.&lt;/li&gt; 
 &lt;li&gt;We naturally track and get feedback on the things we are doing. But once we quit something, we also quit keeping track of that course of action. This creates a problem with getting high-quality feedback, which in turn makes it hard to hone our quitting skills.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h1&gt;Interlude I: Quitting When the World is Watching&lt;/h1&gt; 
&lt;p&gt;2016: Alex Honnold prepares to free-solo-climb El Cap and a group of friends document the climb (which is them risking their lives, too). He quits. Comes back next June, crew reassembles, he successfully summits, free solo, and the documentary &lt;em&gt;Free Solo&lt;/em&gt; is released in 2018, winning the Oscar for Best Documentary Feature. Had he not quit, he could easily have died, and the pressure was to stick.&lt;/p&gt; 
&lt;h1&gt;Section II: In the Losses&lt;/h1&gt; 
&lt;h2&gt;Ch 4: Escalating Commitment&lt;/h2&gt; 
&lt;p&gt;Harold Staw, his rise, his refusal to sell off his babies (his stores), and how he lost most of his money doing so. The mystery of it all is why: What blinded such a nimble, flexible decision-maker to the clear signals right in front of him? How could some of the same behavior that helped him thrive (through grit, determination, and stick-to-itiveness) end up causing his failure (through inflexibility, intractability, and maybe even some hubris)?&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Knee-Deep in the Big Muddy.&lt;/strong&gt; The very first sentence of one of the earliest and most influential academic papers identifying our tendency to persist in losing endeavors, even in the face of strong signals that we ought to quit, states very simply why such behavior is so confounding: “Intuitively, one would expect individuals to reverse decisions or to change behaviors which result in negative consequences.” The author of that seminal 1976 paper, “Knee-Deep in the Big Muddy: A Study of Escalating Commitment to a Chosen Course of Action,” is Harold and Shirley’s son, Barry Staw. He saw the US involvement in the Vietnam War as a living, breathing, high-stakes, slow-motion train wreck of an example of our inability to quit. Staw pointed to the revelation from the Pentagon Papers, a secret Department of Defense history of that war published over government objection by The New York Times and The Washington Post, that Undersecretary of State George Ball warned LBJ in 1965 of the inevitable entrapment in the conflict, “Once we suffer large casualties, we will have started a well-nigh irreversible process. Our involvement will be so great that we cannot—without national humiliation—stop short of achieving our complete objectives. Of the two possibilities I think humiliation would be more likely than the achievement of our objectives—even after we have paid terrible costs.” Staw’s central insight about escalation of commitment is that the phenomenon is not confined to matters like the Vietnam War, a complex geopolitical conflict with national pride wrapped up in it. His laboratory and field experiments show that whether it is on the level of an individual, an organization, or a governmental entity, when we’re getting bad news, when we are getting strong signals that we’re losing—signals that others plainly see—we don’t merely refuse to quit. We will double and triple down, making additional decisions to commit more time and money (and other resources) toward the losing cause, and we will strengthen our belief that we are on the right path.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Waiting Until It Hurts.&lt;/strong&gt; Psychologists Jeffrey Rubin and Joel Brockner conducted an amusing experiment to answer two questions: How long will people wait for something that never arrives, and what price will they pay to continue waiting? It turns out people will wait a surprisingly long amount of time, and they will pay an amount that clearly exceeds the value of what they were waiting for. Escalation of commitment is costly. If the participants had walked away sooner, they would have made more. It may feel like quitting slows us down, but Rubin and Brockner show that it is persistence that is often the culprit. The work on escalation of commitment over the last forty-five years--in different laboratory experiments, field experiments, and explanations of commonly observed behavior--has shown that this type of entrapment in losing causes occurs across a variety of settings and circumstances.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Summary:&lt;/strong&gt;&lt;br&gt; * When we are in the losses, we are not only more likely to stick to a losing course of action, but also to double down. This tendency is called escalation of commitment.&lt;br&gt; * Escalation of commitment is robust and universal, occurring in individuals, organizations, and governmental entities. All of us tend to get stuck in courses of action once started, especially in the face of bad news.&lt;br&gt; * Escalation of commitment doesn’t just occur in high-stakes situations. It also happens when the stakes are low, demonstrating the pervasiveness of the error.&lt;/p&gt; 
&lt;h2&gt;Ch 5: Sunk Cost and the Fear of Waste&lt;/h2&gt; 
&lt;p&gt;2008 approval of bond measure for a high-speed rail system connecting LA and SF. Estimated completion in 2020, at a cost of $33b, generating yearly revenue of $1.3b by 2020, with an operating surplus of $370m, making it self-supporting and profitable thereafter. As of now, no part of that line is operational. Given the accuracy of the Authority’s past projections, there is no basis for believing that the revised estimates of 2029 (for initial service) or 2033 (for completion) are reasonably achievable. This shouldn’t be too surprising since they approved building the first segment in 2010 (twenty-five miles between Madera and Fresno), but they didn’t break ground for another five years. Why is this all taking so long? It turns out there are two titanic engineering obstacles to connecting the central, interior part of the planned route with the key metropolitan areas at either end of the state. First, they have to figure out a way to build track over or blast through the Tehachapi Mountains, which is necessary to connect Bakersfield with Los Angeles to its south. That issue pales in comparison to a second bottleneck, a portion of the Diablo Range known as the Pacheco Pass that stands between the Central Valley and the Bay Area to its north. Given where the project stands now, it’s a good bet that if the decision-makers had known then what they know now about how much the bullet train would cost and how long it would take, it wouldn’t have been approved in the first place. But having started the project, the Authority seems unwilling to quit and cut their losses.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;The Sunk Cost Effect.&lt;/strong&gt; Richard Thaler, in 1980, was the first to point to the sunk cost effect as a general phenomenon, describing it as a systematic cognitive error in which people take into account money, time, effort, or any other resources they have previously sunk into an endeavor when making decisions about whether to continue and spend more. A perfectly rational decision-maker would consider only the future costs and benefits in deciding whether to continue with a course of action. In other words, if continuing on has a positive expected value, a rational actor would persevere. If it has a negative expected value, they would quit. Forty years of experiments and fieldwork across a variety of domains show that people behave as Thaler hypothesized regarding sunk costs. In decisions about whether to move forward, they do take into account what they’ve already spent. They do this because they irrationally think that the only way to recover or justify the costs is if they continue on. &lt;strong&gt;&lt;em&gt;Put simply, the sunk cost effect causes people to stick in situations that they ought to be quitting.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;There’s a simple elegance to Kahneman and Tversky’s proposition. You can see the decision error, free of complicating factors like how the participants got into the losing position or whether they realized their expected value was negative. In these experiments and those that followed, the math is made clear and transparent to the participants. &lt;strong&gt;&lt;em&gt;This is not an error of calculation. This is an error of cognition.&lt;/em&gt;&lt;/strong&gt; In a simple hypothetical like the concert, you can also see the error pretty clearly. It likely makes sense that a choice of how much you want to see the band versus how much you don’t want to spend hours in the cold and freezing rain shouldn’t depend on whether or how much you paid for the ticket. But this cognitive illusion is very strong. Just because you know it’s an error in theory doesn’t mean that you won’t fall for it when you are facing down these kinds of decisions.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;When &quot;Public Works&quot; Is an Oxymoron.&lt;/strong&gt; The sunk cost error’s fingerprints are all over the California bullet train. If most anyone were asked to start the project today as a new endeavor—knowing about the exploding costs, currently as much as $105 billion but likely to increase significantly, and how hard it will be to blast through those two mountain ranges—it seems obvious that the answer would be a hard no. In addition to the direct costs of the project, there is the issue of opportunity costs. Every dollar that California sinks into the project is a dollar that could otherwise be allocated to something that would create more value and a greater public good for the taxpayers whose money is funding the endeavor. But imagine how gutsy a politician would have to be to abandon the project, knowing they’re going to have to defend themselves against charges of having “wasted” more than $8 billion on a train that was never completed. The pressure to keep going to “recover” those costs is enormous. When it comes to these types of public works projects, sunk cost is a familiar refrain.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Katamari.&lt;/strong&gt; There was a popular video game that came out in 2004 named &lt;em&gt;Katamari Damacy&lt;/em&gt;. It was a silly game, strangely addictive, with a grandiose but simple plot. You control the actions of a tiny prince, whose father, the King of All Cosmos, gives him a katamari (Japanese for “clump”), a sticky ball you roll around different locations, picking up trash and debris off the floor, the ball growing bigger and bigger as it accumulates more stuff. Why are you on this mission? The king had gotten drunk and accidentally destroyed a bunch of stars and constellations. You have to grow the ball until it’s big enough to become a star to replace the ones the king destroyed. It’s a goofy plot, but no goofier than whatever is supposed to be motivating you to eat dots and fruit in Pac-Man or fit together block formations in Tetris. The katamari can’t roll over anything bigger than itself. If it does, the impact knocks some things off, making your ball even smaller. At the beginning, your katamari is only big enough to pick up things like ants, thumbtacks, and buttons. Running into a mouse can be a catastrophe. But as you successfully pick up debris, the ball gets bigger. Then you’re terrorizing the mouse. You’re rolling over batteries, plates of food, radios, shoes, pets. Cows, bears, sumo wrestlers, cars, monsters, buildings, islands, mountains. As one reviewer put it after listing some of the mundane little items, “25 minutes later the bloody thing is ripping rainbows out of the ground.” &lt;strong&gt;&lt;em&gt;Like the katamari, rolling around collecting debris, which makes it grow in mass and collect more and even bigger debris, there is a self-reinforcing aspect to the sunk cost fallacy that we really need to watch out for.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;A relationship that’s not working out turns into a game of Katamari. Your friend complains about being in a bad relationship. If you ask, “Why don’t you just break up?” they’ll frequently say, “Because I’ve put so much time into trying to make this relationship work.” Sometimes, they’ll even say, “I put my heart and soul into it.” The more time they put in, the less likely they are to break it off, which leads to them investing more time to get it to work. That makes them even less likely to break up. And so on. No wonder that once you have this talk with a friend, you end up having it over and over again. Their dysfunctional relationship keeps rolling up mass—living arrangements, friends, pets, consumer purchases, property—until they’re ripping rainbows out of the ground.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;How Big Does the Katamari Grow?&lt;/strong&gt; In Barry Staw’s classic 1976 experiment, “Knee-Deep in the Big Muddy: A Study of Escalating Commitment to a Chosen Course of Action,” he set out to ask how much prior commitment to a course of action influences future decisions about whether to stick or quit. He discovered that the answer is a lot. Staw recruited groups of business school students who were tasked with individually deciding how a corporation should allocate certain R&amp;amp;D funds between two of its divisions. To help with the choice, the students were given ten years of historical financial performance about the company and the two divisions under consideration. The participants each had to make an all-or-nothing decision about which department should receive the $10 million in R&amp;amp;D funds, meaning they only had two options: allocate the entire $10 million to one division and give no funds to the other or vice versa. Given the data provided to the students, there were reasonable arguments for allocating the funds to either of the two divisions. While one division was more profitable, the other was growing more quickly. Indeed, the participants, who were all coming into this decision fresh, split about 50-50 on which division they chose. What Staw wanted to find out was whether this initial decision about which division got the funds would affect future allocation decisions, particularly once the participants learned their first choice turned out poorly. In other words, Staw was exploring whether people who carry a loss into a new allocation decision would be more likely to persist, continuing to direct funds to the same division they had previously sunk resources into. To answer that question, he gave all the students a simulation of the next five years of financial results for the company. Regardless of which option they directed the funds to, the additional data showed that the division they chose suffered from half a decade of stagnant sales and deepening losses, significantly underperforming the division they passed over. After being shown this performance data, the participants were then given a new budget of $20 million, which they could now allocate &lt;em&gt;proportionally&lt;/em&gt; across the two divisions. Staw hypothesized that students receiving negative feedback on their first decision would &lt;em&gt;increase&lt;/em&gt; their commitment to their original cause, favoring that same division in the second allocation. Indeed, that is what he found. The participants allocated, on average, over $13 million of the $20 million to the division that they originally directed the R&amp;amp;D funds to, and just under $7 million to the one they did not initially choose. To really hit the point home, he also had a separate group of participants come to the $20 million allocation fresh, as a new decision. They were shown the same financial results and informed of a $10 million R&amp;amp;D allocation five years earlier (by a since-departed financial officer) to the division that subsequently underperformed. In this case, they were not the ones who initially made the decision to sink the R&amp;amp;D funds into one division or the other. When these fresh participants allocated the $20 million proportionally across the two divisions, they gave an average of just $9 million to the division that received the prior funds, much less than the $13 million allocation by the participants carrying with them the sunk cost debris of having personally incurred the prior losses. Putting it into sharp focus, the participants responsible for the first, money-losing decision &lt;em&gt;directed nearly 50%&lt;/em&gt; more of the $20 million to that same division, compared with others with the identical information and corporate history but no personal responsibility for prior policy.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Mental Accounting.&lt;/strong&gt; There’s a saying among top poker players that poker is one long game. It’s a reminder that the particular hand they’re playing is not the last hand they’ll ever play or that any particular day that they’re playing is not the last day they’ll ever play. A poker player will play thousands upon thousands of hands over their lifetime, so in the grand scheme of things whether or not they lose one single hand of poker matters very little. What matters is that they’re maximizing their expected value over all those days and all those hands. That’s what they mean by one long game. This mantra is meant to help expert players overcome the sunk cost fallacy, expressed in poker as wanting to protect the money you’ve already invested in a single hand by not folding, or not wanting to quit a game when you’re in the losses. Of course, what applies to poker applies to life as well. &lt;strong&gt;&lt;em&gt;We all need this kind of reminder because of a quirk in our mental accounting.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;When we start something, whether it’s putting money into the pot in a hand of poker, or starting a relationship or a job, or buying a stock, we open up a mental account. When we exit that thing, whether it’s folding a hand, or leaving a relationship or job, or selling the stock, we close that mental account. It turns out that we just don’t like to close mental accounts in the losses. If we’re losing in a hand of poker, we don’t want to fold because that means we have to realize the loss of the money we put in the pot. If we’re losing in a poker game, we don’t want to quit because it means that we have to leave with less money than we started with. If we’re in a relationship or a job, we don’t want to walk away because we’ll feel like we will have wasted or lost all the time and effort that we put in. Of course, that’s irrational. What really matters is maximizing your expected value across all the things you start, across all of your mental accounts. If you’re investing in a number of stocks, some are going to win and some are going to lose. What matters is whether you’re winning across your whole portfolio not whether any one investment is up or down. But that’s not how we naturally think. We don’t think about the whole portfolio of stocks we own. Each is associated with its own mental account that we don’t want to close out unless we are in the gains.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;The Hardest Cost to Bear.&lt;/strong&gt; &lt;strong&gt;&lt;em&gt;The greater the sunk costs, the harder it becomes to quit.&lt;/em&gt;&lt;/strong&gt; And the greatest cost is, of course, the loss of human life. That makes decisions about whether or when to exit a war heartbreakingly difficult. Retired four-star general Tony Thomas, commander of U.S. Special Operations Command (USSOCOM), served in Afghanistan on missions between 2001 and 2013 (except for a year when he served in the Iraq War). He attended many military funerals and gave an American flag to many gold star families. He described to me those humbling experiences and how those tragic losses amplify the types of sunk cost problems we all face, making it particularly difficult for a country to extricate itself from a war once it has started to incur those losses. On one occasion, a gold star mother, having just lost her son, gripped his hand and said, “Stay on this and finish it.” The general’s knees almost buckled. At that moment, he wanted to run through a wall for her. The unspoken message, never expressed at these funerals but which he felt was on the minds of all those grieving parents, was, “Tell me my child didn’t die in vain.”&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;The Difference between Knowing and Doing.&lt;/strong&gt; &lt;em&gt;There are lots of intuitions people have about cognitive biases, including the sunk cost fallacy. One of the most common is that if you are educated on the topic and know about it, that will stop you from committing the error.&lt;/em&gt; Jebbrey Rubin climbed 99 of the 100 highest peaks in New England, and was climbing the last one, Fort Mountain, in Maine. When the weather turned bad and a fog came in, his climbing partner decided to turn around. Jeffrey R. disagreed and continued climbing alone. His body was found several days later. He apparently fell to his death. Why am I telling you this story, so similar to some of the others? One person turns around. The other continues to go on, with tragic consequences. The Jeffrey R. in this story is Jeffrey Rubin, the same Jeffrey Rubin who, with Joel Brockner, studied the behavior of people waiting for a crossword puzzle dictionary that never came, and followed it up with an impressive and influential body of work on escalation of commitment right up to his death in 1995. If anybody understood the problem of being entrapped in a course of action, unable to cut your losses even in the face of clear signals that you ought to be quitting, it would have been him. Yet he became entrapped that day. This should be a warning to all of us. Don’t think that, just because you’ve read up to this point in the book or understand the sunk cost fallacy, this knowledge alone is going to help you overcome it. If Rubin was unable to quit, that should open our eyes to how hard it is for the rest of us. &lt;strong&gt;&lt;em&gt;Knowing is not the same as doing.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;You Can&apos;t Jedi Mind Trick Being Fresh to a Decision.&lt;/strong&gt; A lot of people who know about the sunk cost fallacy tell me they’ve come up with a solution. Essentially, regardless of the history they have with the decision, they ask themselves, “If I were approaching this decision fresh, would I want to enter into this course of action?” Does this Jedi mind trick actually work? We can, once again, look to Barry Staw for the answer. In one of the follow-ups to the “Big Muddy” experiment, Itamar Simonson and Staw asked participants to make a corporate decision about allocating marketing funds to two products, a nonalcoholic beer and a lite beer. The first decision was, again, an all-or-nothing choice of which product should receive an additional $3 million in marketing support. After making their choice and receiving a simulation of three years of results based on that choice, the participants made a second decision as to how to split another $10 million marketing budget between the two products. The investigators tested several possible ways of mitigating escalation of commitment to the product that received the initial $3 million in marketing funds. One of those ways was the Jedi mind trick, where they asked some of the participants to approach the decision fresh, specifically instructing them to do an analysis listing the pros and cons of allocating funds to each product going forward. Despite the instruction to look forward rather than backward when making this new decision, the participants made a similar allocation ($5.1 million) to the product they earmarked the original funds to as compared to those who made the same prior, losing decision but were not given instruction to just look forward. In contrast, participants who actually came to the second allocation fresh gave just $3.7 million to the product that lost money after receiving the earlier addition of marketing funds. The instruction to treat it as a new decision did practically nothing to reduce escalation of commitment. Just knowing about the sunk cost effect doesn’t help. &lt;strong&gt;&lt;em&gt;The Jedi mind trick doesn’t help.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Summary:&lt;/strong&gt;&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;The sunk cost effect is a cognitive illusion where people take into account resources they have previously sunk into an endeavor when making decisions about whether to continue and spend more.&lt;/li&gt; 
 &lt;li&gt;The sunk cost effect causes people to stick in situations that they ought to be quitting.&lt;/li&gt; 
 &lt;li&gt;When deciding whether to stick or quit, we are worried that if we walk away, we will have wasted the resources we have spent in the trying.&lt;/li&gt; 
 &lt;li&gt;You might be experiencing the sunk cost fallacy if you hear yourself thinking “If I don’t make this work I will have wasted years of my life!” or “We can’t fire her now, she’s been here for decades!”&lt;/li&gt; 
 &lt;li&gt;Sunk costs snowball, like a katamari. The resources you have already spent make it less likely you will quit, which makes it more likely you will accumulate additional sunk costs, which makes it again less likely you will quit, and so on. The growing debris of your prior commitment makes it increasingly harder to walk away.&lt;/li&gt; 
 &lt;li&gt;We don’t like to close mental accounts in the losses.&lt;/li&gt; 
 &lt;li&gt;Knowing about the sunk cost effect doesn’t keep you from falling prey to it.&lt;/li&gt; 
 &lt;li&gt;You can’t trick yourself into not taking sunk costs into account by trying to view the situation as a new choice. Asking whether or not you would continue if the decision were a fresh one doesn’t mitigate the sunk cost effect the way you might intuitively think it would.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Ch 6: Monkeys and Pedestals&lt;/h2&gt; 
&lt;p&gt;Eric Teller is CEO of &quot;X&quot;, an innovation labs subsidiary of Alphabet, though his actual job title is &quot;Captain of Moonshots.&quot; X has become a famous incubator and developer of ideas in the nontraditional tradition of Bell Labs, Xerox PARC, and Thomas Edison’s laboratories. X’s mission is to build and launch technologies to “improve the lives of millions, even billions of people.” They’re specifically in the business of identifying and accelerating world-changing ideas. That means they reject plenty of good ideas because the change those ideas create would be too incremental for their mission. One of X’s slogans is “10x impact on the world’s most intractable problems, not just 10% improvement.” X takes a lot of big swings, knowing that most will be whiffs. Teller looks at each project as buying an option on the future. Like most options, you have to keep paying to hold it, in increasing amounts. To help X-ers become better quitters, Astro Teller has come up with a unique mental model that has been woven into the fabric of X: monkeys and pedestals.&lt;/p&gt; 
&lt;p&gt;Imagine that you’re trying to train a monkey to juggle flaming torches while standing on a pedestal in a public park. If you can achieve such an impressive spectacle, you’ve got a moneymaking act on your hands. Teller recognizes that there are two pieces to becoming successful at this endeavor: training the monkey and building the pedestal. One piece of the puzzle presents a possibly intractable obstacle in the way of success. And the other is building the pedestal. People have been building pedestals since ancient Greece and probably before. Over two-plus millennia, pedestals have been thoroughly figured out. You can buy one at a furniture store or a hardware store, or turn a milk crate upside down. The bottleneck, the hard thing, is training a monkey to juggle flaming torches. The point of this mental model is to remind you that there is no point building the pedestal if you can’t train the monkey. &lt;strong&gt;&lt;em&gt;In other words, you ought to tackle the hardest part of the problem first.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Getting the Monkey Off Your Back.&lt;/strong&gt; Project Foghorn, X’s initiative to develop technology to convert seawater into fuel, offers an example of how the monkeys-and-pedestals mental model works. The first monkey would be proof of concept, but they already had that from the scientists they were partnering with whose recent work attracted their attention to the innovation. The second monkey was commercial viability. They would have to produce the fuel at a cost that was significantly lower than the current price per gallon for gasoline to get broad adoption in the market.&lt;/p&gt; 
&lt;p&gt;One of the beautiful things about the monkeys-and-pedestals mental model is that sometimes it helps you quit before you start. Years ago, X looked into developing what’s now known as a hyperloop, an experimental high-speed rail system. The concept was fine. Building the physical infrastructure wouldn’t be very hard from an engineering standpoint. The monkeys for the hyperloop to be viable were things like whether you could safely load and unload passengers or cargo, and whether you could get the system up to speed and get it to brake without incident. A couple hundred yards of track wouldn’t tell you anything about whether you could conquer those challenges. In fact, Teller and the team at X figured out that you would have to build practically the whole thing before you knew whether it worked. You would have to build a bunch of pedestals before you could find out if the monkeys were intractable. They quickly decided not to pursue it.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;&lt;em&gt;One of Teller’s valuable insights is that pedestal-building creates the illusion of progress rather than actual progress itself.&lt;/em&gt;&lt;/strong&gt; When you are doing something that you already know you can accomplish, you’re not learning anything important about whether the endeavor is worth pursuing. You already know you can build the pedestal. The problem is whether you can train the monkey.&lt;/p&gt; 
&lt;p&gt;On top of that, Teller realizes that &lt;strong&gt;&lt;em&gt;when you’re building pedestals, you are also accumulating sunk costs that make it hard to quit even as you find out that you may not be able to train the monkey to juggle those torches&lt;/em&gt;&lt;/strong&gt;. By focusing on the monkey first, you naturally reduce the debris you accumulate solving for something that’s, in reality, already solved.&lt;/p&gt; 
&lt;p&gt;Teller also understands a subtler but no less important point, that &lt;strong&gt;&lt;em&gt;we have a tendency, when we butt up against a monkey that is proving difficult to solve, to turn our attention to building pedestals rather than giving up&lt;/em&gt;&lt;/strong&gt;. We prefer that illusion of progress to having to quit and admit defeat.&lt;/p&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;Figure out the hard thing first. Try to solve that as quickly as possible. Beware of false progress.&lt;/p&gt; 
&lt;/blockquote&gt; 
&lt;p&gt;&lt;strong&gt;Kill Criteria.&lt;/strong&gt; If we can identify in advance what the signals are that we should pay attention to and make a plan for how we will react to them, we can increase the chances that we’ll cut our losses when we ought to. Ask yourself, “What are the signs that, if I see them in the future, will cause me to exit the road I’m on? What could I learn about the state of the world or the state of myself that would change my commitment to this decision?” That list offers you a set of &lt;em&gt;kill criteria&lt;/em&gt;, literally criteria for killing a project or changing your mind or cutting your losses. It’s one of the best tools for helping you figure out when to quit closer to on time. &lt;em&gt;(Stopping rules!)&lt;/em&gt; Essentially, kill criteria create a precommitment contract to quit.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Funnel Vision.&lt;/strong&gt; You can likely imagine lots of applications of kill criteria in your personal life. When you start dating someone, think ahead. What could be happening that would make you think that it was time to end the relationship? Or, in the case of a single date, what would make you want to end the date? You could do that with going to a particular college, picking a major, starting a career, or taking a job. An obvious and high-value application of kill criteria has to do with funnel management for a business’s sales function. A big problem for sellers is managing all the opportunities at the top of the funnel: Which do you pursue? And, once you’ve started pursuing a lead, when do you give up on it? It’s in a company’s interest to make sure its sellers are spending their time pursuing the highest-value opportunities, based on a combination of the probability of closing and the potential size of the contract.&lt;/p&gt; 
&lt;p&gt;(Story about creating kill criteria to help avoid spending sales time/resources on low-expected-value leads.) We tend to associate the idea of funnel management with sellers or investors. But every one of us has a funnel we are managing: the interests we can pursue, the classes we can take, the projects we can do at work, the jobs we can apply for, the people we can date. We all have to make these choices about which opportunities to pursue and which to skip or quit. As we’re making those choices, we want to spend as little time as possible on the things that aren’t worthwhile and as much time as possible on the things that are.&lt;/p&gt; 
&lt;p&gt;The good news about kill criteria is that you haven’t missed your chance to set them once you have already started an endeavor. At any point, no matter whether it comes to someone you are dating or a house you already own or an investment you are in or a college you are attending, you can think about some time frame in the future, imagine you are unhappy with your situation, and identify the benchmarks you will have missed or the signals you will be seeing that will tell you that you ought to walk away. You may not have set a stop-loss or take-gain when you bought a stock but you can set one now. After all, the present is always in advance of something.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;States and Dates.&lt;/strong&gt; The best quitting criteria combine two things: a state and a date. A state is just what it sounds like, an objective, measurable condition you or your project is in, a benchmark that you have hit or missed. A date is the when. Kill criteria, generally, include both states and dates, in the form of “If I am (or am not) in a particular state at a particular date or at a particular time, then I have to quit.” Or “If I haven’t done X by Y (time), I’ll quit.” Or “If I haven’t achieved X by the time I’ve spent Y (amount in money, effort, time, or other resources), I should quit.”&lt;/p&gt; 
&lt;p&gt;Admiral McRaven offered a unique, high-stakes application of this concept of states and dates when describing the planning for Operation Neptune Spear, the raid on Osama bin Laden. The operation was broken down into 162 phases. Each phase told you what state you would have to achieve to continue, and what state you might be in that would cause you to quit during that phase. Because this was all planned out in advance, it left McRaven, as he told me, with only about five command decisions he might have to make on the fly once the mission had commenced and they were already in it. He gave two examples of the criteria that would cause them to kill the mission. If at any point they fell an hour behind schedule, they would abort. Or, if they discovered that, at any time up to 50% of the way to bin Laden’s compound, they had been detected and compromised by the Pakistani government, they would turn around. If they were compromised beyond the 50% mark, that would be a command decision McRaven would have to make on the fly.&lt;/p&gt; 
&lt;p&gt;You can apply states and dates to relationships. If your goal is marriage (or an equivalent long-term commitment), then if your relationship partner hasn’t proposed (or accepted your proposal or otherwise demonstrated a long-term commitment) by a certain date, you should move on and find someone who is as excited about committing to you as you are to them.&lt;/p&gt; 
&lt;p&gt;You can do the same for career advancement. If you’re working at an entry-level position that has some prospect for advancement, figure out as early as you can the interim milestones for those who succeed, whether it’s raises, or initial promotions, or additional responsibilities, or whatever is specific in that company or practice. Get information about when others who’ve succeeded got those signals on the way up and include those states and dates in your kill criteria.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Better, Not Perfect.&lt;/strong&gt; When I was playing poker, I applied a bunch of kill criteria that helped me be a better quitter (of hands and of games). One example was a stop-loss. If I lost a certain amount, I would quit. This was especially important at the start of my career, because novice players are particularly poor at judging whether they’re losing due to their poor play or because of bad luck. (Take-gains don’t make sense in poker, so I didn’t employ that tool.) After turning pro, I still maintained a stop-loss. Elite poker players are still going to be worse at making quitting decisions when they’re in it, especially if they’re in it and losing. So, even after I gained experience and got a better understanding of the quality of my play and the short-term swings of luck, I still set loss limits. I also realized that I played better in sessions of six to eight hours or less, so I committed to quitting after I played that long. Because I was more aware of the importance of game conditions, I also committed to quit if the quality of the players in the game drastically changed in an unfavorable way as some players cashed out and new ones took their seats. Those kill criteria helped me to become better at quitting games. But was I perfect? Not even close.&lt;/p&gt; 
&lt;p&gt;Taken together, the monkeys-and-pedestals mental model and kill criteria help us overcome our aversion to closing accounts in the losses. First, they both get you to no faster, which naturally limits the losses that you have to absorb when you quit. And the less you are down, the easier it is to walk away. Second, when you set out clear kill criteria in advance and make a precommitment to walk away when you see those signals, you are just more likely to follow through, even when you are losing. Anytime you can make a decision about cutting your losses in advance, you’ll do better at closing those mental accounts.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Summary:&lt;/strong&gt;&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Monkeys and pedestals is a mental model that helps you quit sooner.&lt;/li&gt; 
 &lt;li&gt;Pedestals are the part of the problem you know you can already solve, like designing the perfect business card or logo. The hardest thing is training the monkey.&lt;/li&gt; 
 &lt;li&gt;When faced with a complex, ambitious goal, (a) identify the hard thing first; (b) try to solve for that as quickly as possible; and (c) beware of false progress.&lt;/li&gt; 
 &lt;li&gt;Building pedestals creates the illusion that you are making progress toward your goal, but doing the easy stuff is a waste of time if the hard stuff is actually impossible.&lt;/li&gt; 
 &lt;li&gt;Tackling the monkey first gets you to no faster, limiting the time, effort, and money you sink into a project, making it easier to walk away.&lt;/li&gt; 
 &lt;li&gt;When we butt up against a hard problem we can’t solve, we have a tendency to turn to pedestal-building rather than choosing to quit.&lt;/li&gt; 
 &lt;li&gt;Advance planning and precommitment contracts increase the chances you will quit sooner.&lt;/li&gt; 
 &lt;li&gt;When you enter into a course of action, create a set of kill criteria. This is a list of signals you might see in the future that would tell you it’s time to quit.&lt;/li&gt; 
 &lt;li&gt;Kill criteria will help inoculate you against bad decision-making when you’re “in it” by limiting the number of decisions you’ll have to make once you’re already in the gains or in the losses.&lt;/li&gt; 
 &lt;li&gt;In organizations, kill criteria allow people a different way to get rewarded beyond dogged and blind pursuit of a project until the bitter end.&lt;/li&gt; 
 &lt;li&gt;A common, simple way to develop kill criteria is with “states and dates:” “If by (date), I have/haven’t (reached a particular state), I’ll quit.”&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h1&gt;Interlude II: Gold or Nothing&lt;/h1&gt; 
&lt;p&gt;Sasha Cohen&apos;s figure-skating career and the idea that quitting on something is quitting on ourselves, as in, our identity of ourselves.&lt;/p&gt; 
&lt;h1&gt;Section III: Identity and Other Impediments&lt;/h1&gt; 
&lt;h2&gt;Ch 7: You Own What You&apos;ve Bought and What You&apos;ve Thought: Endowment and Status Quo Bias&lt;/h2&gt; 
&lt;p&gt;&lt;strong&gt;Summary:&lt;/strong&gt;&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;The endowment effect is a cognitive bias where we value something we own more than we would if we didn’t own it.&lt;/li&gt; 
 &lt;li&gt;We can be endowed to objects but also to our own ideas and beliefs.&lt;/li&gt; 
 &lt;li&gt;Endowment is an obstacle to quitting because when we irrationally value things we own, we miscalculate their expected value. We might think the company we started or the project we devised or the belief we have is worth more than it actually is.&lt;/li&gt; 
 &lt;li&gt;We prefer to stick with the status quo.&lt;/li&gt; 
 &lt;li&gt;We are more tolerant of bad outcomes that come from sticking with what we are already doing than bad outcomes that come from switching to something new. This phenomenon is part of omission-commission bias.&lt;/li&gt; 
 &lt;li&gt;When you say, “I’m just not ready to decide yet,” what you are really saying is, “For now, I am choosing the status quo.”&lt;/li&gt; 
 &lt;li&gt;Even in highly data-rich environments like professional sports, sunk cost, endowment, and status quo bias distort decision-making.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Ch 8: The Hardest Thing to Quit is Who You Are: Identity and Dissonance&lt;/h2&gt; 
&lt;p&gt;&lt;strong&gt;Summary:&lt;/strong&gt;&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;When it comes to quitting, the most painful thing to quit is who you are. Our ideas, beliefs, and actions are part of our identity.&lt;/li&gt; 
 &lt;li&gt;When new information conflicts with a belief, we experience cognitive dissonance.&lt;/li&gt; 
 &lt;li&gt;To resolve the conflict, we can either change the belief or rationalize away the new information. Too often, we choose the latter.&lt;/li&gt; 
 &lt;li&gt;Dissonance can also result from new information coming into conflict with our past actions.&lt;/li&gt; 
 &lt;li&gt;We have a desire to maintain internal consistency, where our past beliefs and actions line up with our present beliefs and actions.&lt;/li&gt; 
 &lt;li&gt;We also want others to view us as consistent. We worry that if others see inconsistency between our present and past decisions, beliefs, or actions, they will judge us as being wrong, irrational, capricious, and prone to mistakes.&lt;/li&gt; 
 &lt;li&gt;When we know or believe our decisions are being evaluated by others, our intuition is that we will be more rational, but the opposite is true. External validity &lt;em&gt;increases&lt;/em&gt; escalation of commitment.&lt;/li&gt; 
 &lt;li&gt;The more extreme a position is, the more cognitive gymnastics we’ll do to defend it. The facts are more likely to persuade you away from the consensus opinion than a fringe view.&lt;/li&gt; 
 &lt;li&gt;Fears about how others will view us if we quit are usually overblown.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Ch 9: Find Someone Who Loves You but Doesn&apos;t Care About Hurt Feelings&lt;/h2&gt; 
&lt;p&gt;&lt;strong&gt;Summary:&lt;/strong&gt;&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Optimism makes you less likely to walk away while not actually increasing your chances of success. That means that being overly optimistic will make you stick to things longer that aren’t worthwhile. Better to be well calibrated.&lt;/li&gt; 
 &lt;li&gt;Life’s too short to spend your time on opportunities that are no longer worthwhile.&lt;/li&gt; 
 &lt;li&gt;When someone is on the outside looking in, they can usually see your situation more rationally than you can.&lt;/li&gt; 
 &lt;li&gt;The best quitting coach is a person who loves you enough to look out for your long-term well-being. They are willing to tell you the hard truth even if it means risking hurt feelings in the short term.&lt;/li&gt; 
 &lt;li&gt;Decisions about when to quit improve when the people who make the decisions to start things are different from the people who make the decisions to stop those things.&lt;/li&gt; 
 &lt;li&gt;Getting the most out of a quitting coach requires permission to speak the truth.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h1&gt;Interlude III: The Ants Go Marching... Mostly&lt;/h1&gt; 
&lt;h1&gt;Section IV: Opportunity Cost&lt;/h1&gt; 
&lt;h2&gt;Ch 10: Lessons from Forced Quitting&lt;/h2&gt; 
&lt;p&gt;&lt;strong&gt;Summary:&lt;/strong&gt;&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Being forced to quit forces you to start exploring new options and opportunities. But you should start exploring before you’re forced to.&lt;/li&gt; 
 &lt;li&gt;Even after you have found a path that you want to stick to, keep doing some exploration. Things change, and whatever you are doing now may not be the best path for you to pursue in the future. Having more options gives you something to switch to when the time is right.&lt;/li&gt; 
 &lt;li&gt;Exploration helps you to diversify your portfolio of skills, interests, and opportunities.&lt;/li&gt; 
 &lt;li&gt;A diversified portfolio helps to protect you against uncertainty.&lt;/li&gt; 
 &lt;li&gt;Backup plans are good to have especially because some backup plans can turn out to be better than what we’re already pursuing.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Ch 11: The Myopia of Goals&lt;/h2&gt; 
&lt;p&gt;&lt;strong&gt;Summary:&lt;/strong&gt;&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Goals can make it possible to achieve worthwhile things, but goals can also increase the chances that we will escalate commitment when we should quit.&lt;/li&gt; 
 &lt;li&gt;Goals are pass-fail in nature. You either reach the finish line or you don’t, and progress along the way matters very little.&lt;/li&gt; 
 &lt;li&gt;Don’t just measure whether you hit the goal, ask what you have achieved and learned along the way.&lt;/li&gt; 
 &lt;li&gt;Set intermediate goals and prioritize goals that allow you to recognize progress along the way or acquire something valuable even if you don’t reach the goal.&lt;/li&gt; 
 &lt;li&gt;Goals, when set, are a proxy for an expected-value equation, balancing the benefits that you’re trying to gain against the costs you’re willing to bear.&lt;/li&gt; 
 &lt;li&gt;Inflexible goals aren’t a good fit for a flexible world.&lt;/li&gt; 
 &lt;li&gt;With better advance planning (like identifying monkeys and pedestals and kill criteria) and the help of a good quitting coach, you can make goals more flexible, setting at least one “unless” and planning regular check-ins on the analysis that initially led to setting the goal.&lt;/li&gt; 
 &lt;li&gt;In general, when we quit, we fear two things: that we’ve failed and that we’ve wasted our time, effort, or money.&lt;/li&gt; 
 &lt;li&gt;Waste is a forward-looking problem, not a backward-looking one.&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>The Subtle Art of Not Giving a F*ck</title>
      <link>https://tedneward.github.io/Research/thinking/subtle-art-not-giving-a-fck/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">thinking/subtle-art-not-giving-a-fck/index.html</guid>
      	<description>
	&lt;p&gt;&lt;em&gt;(by Mark Manson)&lt;/em&gt;&lt;/p&gt; 
&lt;h3&gt;Chapter 1: Don&apos;t Try&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;Conventional life advice, or all the positive stuff and happy self-help stuff we hear all the time, fixates on what you lack.&lt;/li&gt; 
 &lt;li&gt;If you&apos;re dreaming of something all the time, then you&apos;re reinforcing the same unconscious reality over and over: that you are &lt;em&gt;not that&lt;/em&gt;.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;The Feedback Loop from Hell&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;Consumer culture and social media has bred a whole generation who believe that having negative experiences like anxiety, fear, guilt, etc is not okay.&lt;/li&gt; 
 &lt;li&gt;The desire for more positive experience is itself a negative experience, while the accepting of one&apos;s negative experience is itself a positive experience.&lt;/li&gt; 
 &lt;li&gt;Everything worthwhile in life is won through surmounting the associated negative experience, so don&apos;t try to escape it.&lt;/li&gt; 
 &lt;li&gt;You must learn how to focus and prioritize your thoughts effectively, or how to pick and choose what matters to you and what doesn&apos;t based on finely honed personal values.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;The Subtle Art of Not Giving a Fuck&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;Subtlety #1: Not giving a fuck doesn&apos;t mean being indifferent; it means being comfortable with being different.&lt;/li&gt; 
 &lt;li&gt;Indifferent people are afraid of the world and the repercussions of their own choices, which is why they don&apos;t make any meaningful choices.&lt;/li&gt; 
 &lt;li&gt;You must say &quot;fuck it&quot; not to everything in life, but rather to everything unimportant in life. Save your fucks for what truly matters.&lt;/li&gt; 
 &lt;li&gt;Subtlety #2: To not give a fuck about adversity, you must first give a fuck about something more important than adversity.&lt;/li&gt; 
 &lt;li&gt;If you don&apos;t find that meaningful something, your fucks will be given to meaningless and frivolous causes.&lt;/li&gt; 
 &lt;li&gt;Subtlety #3: Whether you realize it or not, you are always choosing what to give a fuck about.&lt;/li&gt; 
 &lt;li&gt;Maturity is what happens when we learn to give fucks about only what&apos;s truly fuckworthy.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;So Mark, What the Fuck Is the Point of This Book Anyway?&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;Practical enlightenment is becoming comfortable with the idea that some suffering is inevitable, and that no matter what you do, life is comprised of failures, loss, and even death.&lt;/li&gt; 
 &lt;li&gt;The only way to overcome pain is to first learn how to bear it.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Chapter 2: Happiness Is a Problem&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;Pain and loss are inevitable and we should let go of trying to resist them.&lt;/li&gt; 
 &lt;li&gt;Happiness is not a solvable equation. Dissatisfaction and unease are inherent parts of human nature, and necessary components to creating constant happiness.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;The Misadventures of Disappointment Panda&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;We suffer because it is biologically useful: It is nature&apos;s preferred agent for inspiring change.&lt;/li&gt; 
 &lt;li&gt;A constant dissatisfaction has kept our species fighting and striving, building and conquering.&lt;/li&gt; 
 &lt;li&gt;A society that coddles itself more and more from the discomforts of life is dangerous: We lose the benefits of experiencing healthy doses of pain, which disconnects us from the reality of the world around us.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Happiness Comes from Solving Problems&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;True happiness occurs when you find the problems you enjoy having and enjoy solving.&lt;/li&gt; 
 &lt;li&gt;Instead of solving, people either a) deny they exist in the first place, or b) choose to believe that there is nothing they can do to solve their problems, even when there is.&lt;/li&gt; 
 &lt;li&gt;Forms of blame and denial allow us to temporarily escape our problems, and that escape can provide us a quick rush to feel better.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Emotions are Overrated&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;Negative emotions are a call to action. When you feel them, it&apos;s because you&apos;re supposed to &lt;em&gt;do something&lt;/em&gt;.&lt;/li&gt; 
 &lt;li&gt;To deny one&apos;s negative emotions is to deny many of the feedback mechanisms that help a person solve problems.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Choose Your Struggle&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;An interesting question that most people will never consider is &quot;What &lt;em&gt;pain&lt;/em&gt; do you want in your life? What are you willing to struggle for?&quot;&lt;/li&gt; 
 &lt;li&gt;Real, serious, lifelong fulfillment and meaning have to be earned through the choosing and managing of our struggles.&lt;/li&gt; 
 &lt;li&gt;What determines your success isn&apos;t &quot;What do you want to enjoy?&quot; but &quot;What pain do you want to sustain?&quot; Our struggles determine our success.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Chapter 3: You Are Not Special&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;A true and accurate measurement of one&apos;s self-worth is how you feel about the negative aspects of yourself.&lt;/li&gt; 
 &lt;li&gt;Entitled people have a delusional degree of self-confidence.&lt;/li&gt; 
 &lt;li&gt;Because entitled people are incapable of acknowledging their problems openly and honestly, they are incapable of improving their lives in any lasting or meaningful way.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Things Fall Apart&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;If we have problems that are unsolvable, our unconscious figures that we&apos;re uniquely special or uniquely defective in some way. Put simply: we become entitled.&lt;/li&gt; 
 &lt;li&gt;Entitled people flip between being on top of the world or having the world on top of them, demanding special treatment in each case.&lt;/li&gt; 
 &lt;li&gt;It takes just as much energy and delusional self-aggrandizement to maintain the belief that one has insurmountable problems as that one has no problems at all.&lt;/li&gt; 
 &lt;li&gt;In an age when we&apos;re more connected than ever, entitlement seems to be at an all-time high.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;The Tyranny of Exceptionalism&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;Our lives today are filled with information from the extremes of the bell curve of human experience, because in the media business that what sells.&lt;/li&gt; 
 &lt;li&gt;This flood of extreme information has conditioned us to believe that exceptionalism is the new normal. Because we are mostly average, this drives us to feel insecure and desperate.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;B-b-b-but If I&apos;m Not Going to Be Special or Extraordinary, What&apos;s the Point?&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;When a culture&apos;s standard of success is &quot;be extraordinary,&quot; it&apos;s better to be at the low end of the bell curve than in the middle, because there you&apos;re still special and deserve attention.&lt;/li&gt; 
 &lt;li&gt;People who become great at something become great because they understand that they&apos;re only mediocre, and that they could be so much better. It&apos;s anti-entitlement.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Chapter 4: The Value of Suffering&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;If suffering is inevitable and our problems are unavoidable, then we should not ask &quot;How do I stop suffering?&quot; but instead &quot;Why am I suffering –&amp;nbsp;for what purpose?&quot;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;The Self-Awareness Onion&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;The first layer of self-awareness is a simple understanding of one&apos;s emotions.&lt;/li&gt; 
 &lt;li&gt;The second layer is the ability to ask why we feel some way; these questions are important because they illuminate what we consider success or failure.&lt;/li&gt; 
 &lt;li&gt;The third layer integrates our personal values; this is important because our values determine the nature of our problems, which in turn determines the quality of our lives.&lt;/li&gt; 
 &lt;li&gt;We must ask these questions accurately to achieve a deeper knowledge of our own values.&lt;/li&gt; 
 &lt;li&gt;What is objectively true about your situation is not as important as how you come to see the situation, and how you choose to measure it and value it.&lt;/li&gt; 
 &lt;li&gt;Problems may be inevitable, but their &lt;em&gt;meaning&lt;/em&gt; is not. We can control our problems mean based on how we choose to think about them, the standard by which we measure them.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Rock Star Problems&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;If you want to change how you see your problems, you have to change what you value and how you measure failure or success.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Shitty Values&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;Shitty values include:&lt;/li&gt; 
 &lt;li&gt;Pleasure: People who focus their energy on superficial pleasures end up more anxious, more emotionally unstable, and more depressed.&lt;/li&gt; 
 &lt;li&gt;Material Success: Once one is able to provide for basic physical needs (food, shelter, etc), the correlation between happiness and worldly success approaches zero.&lt;/li&gt; 
 &lt;li&gt;Always Being Right: Assuming you&apos;re ignorant keeps you unattached to superstitions or poorly informed beliefs and promotes a constant state of learning and growth.&lt;/li&gt; 
 &lt;li&gt;Staying Positive: Constant positivity is an avoidance of life&apos;s problems&amp;nbsp;– but upon choosing the right values and metrics, these problems should motivate you.&lt;/li&gt; 
 &lt;li&gt;The trick with negative emotions is to 1) express them in a socially acceptable and healthy manner, and 2) express them in a way that aligns with your values.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Defining Good and Bad Values&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;Good values are reality-based, socially-constructive, and immediate and controllable; while bad values are superstitious, socially destructive, and not immediate or controllable.&lt;/li&gt; 
 &lt;li&gt;Good values are achieved internally, and thereby controllable so that you engage the world as it is rather than by how you wish it were.&lt;/li&gt; 
 &lt;li&gt;Bad values are generally reliant on external events, and thereby outside your control so that you must rely on socially destructive or superstitious means to achieve them.&lt;/li&gt; 
 &lt;li&gt;Values are about prioritization: What values do you prioritize above all else, and therefore influence your decision-making above all else?&lt;/li&gt; 
 &lt;li&gt;By choosing better values, you divert your fucks to something better –&amp;nbsp;to things that matter, improve our state of well-being and generate happiness, pleasure, and success as side-effects.&lt;/li&gt; 
 &lt;li&gt;When you give better fucks, you get better problems. And when you get better problems, you get a better life.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Chapter 5: You Are Always Choosing&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;When we feel like we are choosing problems, we feel empowered. When we feel like our problems are being forced upon us, we feel victimized and miserable.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;The Choice&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;We don&apos;t always control what happens to us. But we &lt;em&gt;always&lt;/em&gt; control how we interpret what happens to us, as well as how we respond.&lt;/li&gt; 
 &lt;li&gt;Whether we like it or not, we are &lt;em&gt;always&lt;/em&gt; taking an active role in what&apos;s occurring around or within us. We are &lt;em&gt;always&lt;/em&gt; choosing, whether we recognize it or not.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;The Responsibility/Fault Fallacy&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;The more we choose to accept responsibility into our lives, the more power we will exercise over our lives. Accepting responsibility for our problems is the first step to solving them.&lt;/li&gt; 
 &lt;li&gt;We hesitate to take responsibility for our problems because we believe that to be &lt;em&gt;responsible&lt;/em&gt; for our problems is to also be at &lt;em&gt;fault&lt;/em&gt; for our problems.&lt;/li&gt; 
 &lt;li&gt;But we are responsible for experiences that aren&apos;t our fault all the time.&lt;/li&gt; 
 &lt;li&gt;Fault results from choices that have already been made. Responsibility results from the choices you&apos;re currently making, every second of every day.&lt;/li&gt; 
 &lt;li&gt;Responsibility means you get to choose how you see things, how you react to things, and how you value things. You choose the metric by which to measure your experiences.&lt;/li&gt; 
 &lt;li&gt;Taking responsibility for our problems is far more important than taking responsibility for success and happiness, because that&apos;s where the real learning comes from.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Responding to Tragedy&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;Pain of one sort or another is inevitable for all of us, but again, we get to choose what it means to and for us.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Genetics and the Hand We&apos;re Dealt&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;People who consistently make the best choices in the situations they&apos;re given are the ones who eventually come out ahead in life.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Victimhood Chic&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;Public sharing of &quot;injustices&quot; garners attention and emotional outpouring, rewarding people who are able to perpetually feel victimized with ever-growing amounts of attention and sympathy.&lt;/li&gt; 
 &lt;li&gt;The biggest problem with victimhood chic is that it diverts attention away from &lt;em&gt;actual&lt;/em&gt; victims.&lt;/li&gt; 
 &lt;li&gt;But part of living in a democracy and a free society is that we all have to deal with views and people we don&apos;t necessarily like.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;There Is No &quot;How&quot;&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;You are &lt;em&gt;already choosing&lt;/em&gt;, in every moment of every day, what to give a fuck about; so change is as simple as choosing to give a fuck about something else.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Chapter 6: You&apos;re Wrong About Everything (But So Am I)&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;Growth is endlessly iterative. We shouldn&apos;t seek to find the ultimate right answer for ourselves, but instead slowly chip away at the ways that we are wrong.&lt;/li&gt; 
 &lt;li&gt;There is no correct dogma or perfect ideology, but only what your experience has shown to be right for you.&lt;/li&gt; 
 &lt;li&gt;Instead of looking how we&apos;re right all the time, we should be looking for how we are wrong. Being wrong opens us up to change, and in turn brings us opportunity for growth.&lt;/li&gt; 
 &lt;li&gt;Don&apos;t trust your conception of positive/negative experiences. All we know for certain is what hurts in the moment and what doesn&apos;t.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Architects of Our Own Beliefs&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;What we understand as &quot;meaning&quot; is generated by the associations our brain makes between two or more experiences.&lt;/li&gt; 
 &lt;li&gt;But there are two problems: The brain is imperfect, and once we create meaning for ourselves, our brains are designed to hold onto that meaning.&lt;/li&gt; 
 &lt;li&gt;Many of our values are products of events that are not representative of the world at large, or of a totally misconceived past. So most of our beliefs are wrong.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;The Dangers of Pure Certainty&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;For individuals to feel justified in doing horrible things to others, they must feel an unwavering uncertainty in their own righteousness, beliefs, and deservedness.&lt;/li&gt; 
 &lt;li&gt;The more you embrace being uncertain and not knowing, the more comfortable you will feel in knowing that you don&apos;t know.&lt;/li&gt; 
 &lt;li&gt;Uncertainty is the root of all progress and growth, as the person who believes he knows everything learns nothing.&lt;/li&gt; 
 &lt;li&gt;Before we can look at our values and priorities and change them into better, healthier ones, we must first become &lt;em&gt;uncertain&lt;/em&gt; of our current values.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Manson&apos;s Law of Avoidance&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;Manson&apos;s Law of avoidance states the more something threatens your identity, the more you will avoid it.&lt;/li&gt; 
 &lt;li&gt;Until we change how we view ourselves, what we believe we are and are not, we cannot overcome our avoidance and anxiety, and so we cannot change.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Kill Yourself&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;There is little that is unique or special about your problems, and it&apos;s pure narcissism to believe otherwise.&lt;/li&gt; 
 &lt;li&gt;Redefine your metrics in mundane and broad ways. The narrower and rarer the identity you choose for yourself, the more everything will seem to threaten your identity.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;How to Be a Little Less Certain of Yourself&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;To create uncertainty, ask yourselves three questions:&lt;/li&gt; 
 &lt;li&gt;&lt;em&gt;What if I&apos;m wrong?&lt;/em&gt; We are the worst observers of ourselves, and so chip away at your certainty by consistently questioning how wrong we might be about ourselves.&lt;/li&gt; 
 &lt;li&gt;&lt;em&gt;What would it mean if I&apos;m wrong?&lt;/em&gt; Being able to evaluate different values without necessarily adopting them is perhaps &lt;em&gt;the&lt;/em&gt; central skill in changing one&apos;s own life meaningfully.&lt;/li&gt; 
 &lt;li&gt;&lt;em&gt;Would being wrong create a better or worse problem than my current problem, for both myself and others?&lt;/em&gt; Our problems are endless, so we must look at which problem is better.&lt;/li&gt; 
 &lt;li&gt;If it feels like you versus the world, chances are it&apos;s really just you versus yourself.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Chapter 7: Failure Is the Way Forward&lt;/h3&gt; 
&lt;h4&gt;The Failure/Success Paradox&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;Improvement at anything is based on thousands of tiny failures, and the magnitude of your success is based on how many times you&apos;ve failed at something.&lt;/li&gt; 
 &lt;li&gt;At some point, most of us reach a place where we&apos;re afraid to fail, and stick only to what is placed in front of us or only what we&apos;re really good at.&lt;/li&gt; 
 &lt;li&gt;Shitty values involve tangible external goals outside our control, and once they&apos;re achieved you feel empty because there are no more problems to solve.&lt;/li&gt; 
 &lt;li&gt;Better values are process-oriented, and their problems must continuously be re-engaged. Such a value is an ongoing, lifelong process that defies completion.&lt;/li&gt; 
 &lt;li&gt;Consequently goals, as they are traditionally defined, are limited in the amount of happiness they can produce in our lives.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Pain Is Part of the Process&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;We must suffer emotional pain to develop greater emotional resilience, a stronger sense of self, increased compassion, and a generally happier life.&lt;/li&gt; 
 &lt;li&gt;If you avoid pain by chasing highs or indulging in entitlement or overindulging in substances, then you&apos;ll never generate the requisite motivation to actually change.&lt;/li&gt; 
 &lt;li&gt;When you choose a new value, you choose to introduce a new form of pain into your life. Learn to sustain it, and act despite it.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;The &quot;Do Something&quot; Principle&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;The &quot;do something&quot; principle states: Action isn&apos;t just the effect of motivation; it&apos;s also the cause of it.&lt;/li&gt; 
 &lt;li&gt;We assume a chain reaction of &lt;em&gt;emotional inspiration ⇒ motivation ⇒ desirable action&lt;/em&gt;, but it&apos;s actually an endless loop: &lt;em&gt;inspiration ⇒ motivation ⇒ action ⇒ inspiration&lt;/em&gt;.&lt;/li&gt; 
 &lt;li&gt;We can therefore reorient our mindset around the chain &lt;em&gt;action ⇒ inspiration ⇒ motivation&lt;/em&gt;.&lt;/li&gt; 
 &lt;li&gt;So if you lack the motivation to make an important change in your life, &lt;em&gt;do something&lt;/em&gt; and then harness the reaction to that action as a way to begin motivating yourself.&lt;/li&gt; 
 &lt;li&gt;With &lt;em&gt;doing something&lt;/em&gt; as your only metric for success, then even failure pushes you forward.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Chapter 8: The Importance of Saying No&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;The only way to achieve meaning and a sense of importance is one&apos;s life is through a rejection of alternatives, or a narrowing of freedom&amp;nbsp;–&amp;nbsp;a choice of commitment to one place, one belief, or one person.&lt;/li&gt; 
 &lt;li&gt;Exposure to different cultural values and metrics forces you to reexamine what seems obvious in your own life and whether it&apos;s actually the best way to live.&lt;/li&gt; 
 &lt;li&gt;There is such pressure in the West to be likable that people often reconfigure their entire personally depending on whom they&apos;re dealing with.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Rejection Makes Your Life Better&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;We need to reject something. Or else we stand for nothing, and are without values and live our lives without any purpose.&lt;/li&gt; 
 &lt;li&gt;To truly appreciate something, you must confine your life to it. There is a certain level of joy and meaning you reach only after focusing significant time on a single relationship, craft, or career.&lt;/li&gt; 
 &lt;li&gt;Entitled people, because they feel as though they &lt;em&gt;deserve&lt;/em&gt; to feel great all the time, avoid rejecting anything because doing so might make themselves or others feel bad.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Boundaries&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;Healthy relationships are defined by 1) each person accepting responsibility, and 2) each person being willing to both reject and be rejected by their partner.&lt;/li&gt; 
 &lt;li&gt;People in healthy relationships with strong boundaries take responsibility for their own values and problems, and do not take responsibility for those of their partner.&lt;/li&gt; 
 &lt;li&gt;Entitled people either expect take others to take responsibility for their problems, or take on too much responsibility for other people&apos;s problems.&lt;/li&gt; 
 &lt;li&gt;Entitled people adopt these strategies in their relationships, as with everything, to help avoid accepting responsibility for their own problems.&lt;/li&gt; 
 &lt;li&gt;In an unhealthy relationship two people solve each other&apos;s problems to feel good about themselves. In a healthy relationship they solve their own problems to feel good about each other.&lt;/li&gt; 
 &lt;li&gt;&quot;Victims&quot; and &quot;savers&quot; end up in relationships because they use each other to achieve emotional highs.&lt;/li&gt; 
 &lt;li&gt;Acts of love are valid only if they&apos;re performed without conditions or expectations.&lt;/li&gt; 
 &lt;li&gt;It&apos;s not about giving a fuck about everything your partner gives a fuck about; it&apos;s about giving a fuck about your partner regardless of the fucks he or she gives.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;How to Build Trust&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;Conflict exists to show us who is there for us unconditionally and who is just there for the benefits.&lt;/li&gt; 
 &lt;li&gt;A healthy relationship requires both sides to be willing and able to say no and hear no, or else boundaries break down and one person&apos;s problems and values dominate the other&apos;s.&lt;/li&gt; 
 &lt;li&gt;When trust is destroyed, it can be rebuilt only if 1) the trust-breaker admits and owns up to the true values that caused the breach, and 2) the trust-breaker builds a solid track record of improved behavior over time.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Freedom Through Commitment&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;The more options we&apos;re given, the less satisfied we become with whatever we choose, because we&apos;re aware of all the other options we&apos;re potentially forfeiting.&lt;/li&gt; 
 &lt;li&gt;There are some experiences that you can have only when living in the same place, being with the same person, or working on the same craft for significant time.&lt;/li&gt; 
 &lt;li&gt;You will find increased opportunity and upside in rejecting alternatives and distractions in favor of what you&apos;ve chosen to let truly matter to you.&lt;/li&gt; 
 &lt;li&gt;The rejection of alternatives liberates us from things that do not align with our most important values or with our chosen metrics.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Chapter 9: ... And Then You Die&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;In a backwards way, death is the light by which the shadow of all life&apos;s meaning is measured.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Something Beyond Our Selves&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;We are the only animals that are aware of the inevitability of our own death; this &quot;death terror&quot; is a deep existential anxiety that underlies everything we think or do.&lt;/li&gt; 
 &lt;li&gt;To compensate for our mortality, we try to construct a conceptual self that will live forever. All human civilization is a result of such &quot;immortality projects.&quot;&lt;/li&gt; 
 &lt;li&gt;Our immortality projects are our values – the barometers of meaning and worth in our life. And when our values fail, so do we, psychologically speaking.&lt;/li&gt; 
 &lt;li&gt;Rather than attempting to implement our conceptual self across the world, we should question our conceptual self and become more comfortable with the reality of our own death.&lt;/li&gt; 
 &lt;li&gt;Becoming comfortable with our mortality allows us to choose values more freely, unrestrained by the quest for immortality, and freed from dangerous dogmatic views.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;The Sunny Side of Death&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;Death confronts us all with a painful and important question: What is your legacy?&lt;/li&gt; 
 &lt;li&gt;To be comfortable with death, see yourself as something bigger than yourself, choose values that go beyond serving yourself, and that are simple and immediate and controllable and tolerant of our chaotic world.&lt;/li&gt; 
 &lt;li&gt;Our culture today confuses great attention with great success, but they are not the same.&lt;/li&gt; 
 &lt;li&gt;There is nothing to be afraid of. Ever.&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Tempo</title>
      <link>https://tedneward.github.io/Research/thinking/tempo/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">thinking/tempo/index.html</guid>
      	<description>
	&lt;p&gt;&lt;em&gt;(by Venkatesh Rao, (publisher))&lt;/em&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>The Red Team Handbook</title>
      <link>https://tedneward.github.io/Research/thinking/red-team-handbook/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">thinking/red-team-handbook/index.html</guid>
      	<description>
	&lt;p&gt;&lt;em&gt;&lt;a href=&quot;Red_Team_Handbook.pdf&quot;&gt;PDF&lt;/a&gt;&lt;/em&gt;&lt;/p&gt; 
&lt;h2&gt;Ch 1: Introduction&lt;/h2&gt; 
&lt;p&gt;As human beings, we develop patterns of behavior and thought that help us achieve our goals with the least amount of effort possible. For example, we learn early in life that we can have greater success and more friends if we cooperate and agree with other people – go along to get along. To save time and energy, we develop shortcuts and apply solutions that work in one area to problems in another, even if the responses don’t fit perfectly. We assume we know more than we really do, and we don’t question our assumptions. The introverts among us, despite having valuable ideas, cede control in meetings to the extroverts and remain mute. These actions and this learned behavior combine to deceive us. We assume we are applying the best solutions without reflecting on our actions and asking if there is a better way, or if we are really applying the correct thought and behavior to get the outcomes we want. When we join together in groups, these human characteristics amplify, and our tendencies and learned patterns of behavior lead us to situations like the planning meeting described above.&lt;/p&gt; 
&lt;p&gt;Expanding on the words of psychologist Dietrich Dörner, people court failure in predictable ways, by degrees, almost imperceptibly, and according to their own culture and context. In other words, we routinely take shortcuts because of limitations on time, personnel, or other resources, and we accept that as a normal way of doing business. We assume we understand situations because we have been in similar ones before, and we turn a blind eye to ambiguity or don’t fully appreciate asymmetries. We discount potential threats because we don’t fully appreciate the likelihood of occurrence or the complexity of influencing factors. We make many small decisions that are individually “close enough,” but when joined together, become the seeds of failure. We take comfort in the familiar, and assume others, even on the other side of the world, share our views, beliefs, and tendencies. These reasons and more are why we Red Team.&lt;/p&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;“Every assumption we hold, every claim, every assertion, every single one of them must be challenged.” --CSA Mark A. Milley&lt;/p&gt; 
&lt;/blockquote&gt; 
&lt;p&gt;&lt;strong&gt;What is Red Teaming&lt;/strong&gt; Red Teaming is a flexible cognitive approach to thinking and planning that is specifically tailored to each organization and each situation. It is conducted by skilled practitioners normally working under charter from organizational leadership. It uses structured tools and techniques to help us ask better questions, challenge explicit and implicit assumptions, expose information we might otherwise have missed, and develop alternatives we might not have realized exist. It cultivates mental agility to allow Red Teamers to rapidly shift between multiple perspectives to develop a fuller appreciation of complex situations and environments. This leads to improved understanding, more options generated by everyone (regardless of rank or position), better decisions, and a level of protection from the unseen biases and tendencies inherent in all of us.&lt;/p&gt; 
&lt;p&gt;This is built on four main principles:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Self-awareness and Reflection&lt;/li&gt; 
 &lt;li&gt;Groupthink Mitigation and Decision Support&lt;/li&gt; 
 &lt;li&gt;Fostering Cultural Empathy&lt;/li&gt; 
 &lt;li&gt;Applied Critical Thinking&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Ch 2: Self-Awareness and Recognition&lt;/h2&gt;
	</description>
    </item>
    <item>
      <title>Superforecasting: The Art and Science of Prediction</title>
      <link>https://tedneward.github.io/Research/thinking/superforecasters/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">thinking/superforecasters/index.html</guid>
      	<description>
	&lt;p&gt;&lt;em&gt;(Tetlock, Gardner; Crown Publishers, 2015)&lt;/em&gt;&lt;/p&gt; 
&lt;h1&gt;Chapter 1: An Optimistic Skeptic&lt;/h1&gt; 
&lt;p&gt;Tom Friedman (globally-recognized predictor) vs Bill Flack (virtually unknown predictor who is right quite often).&lt;/p&gt; 
&lt;h2&gt;The One About the Chimp&lt;/h2&gt; 
&lt;p&gt;The average expert was roughly as accurate as a dart-throwing chimpanzee. Author conducted a twenty-year (1984 - 2004) study: gathered up a big group of experts (academics, pundits, etc) to make thousands of predictions about the economy, stocks, elections, wars, and other issues of the day. Time passed, and when the researcher checked the accuracy of the predictions, he found that the average expert did as well as random guessing.&lt;/p&gt; 
&lt;p&gt;People are in front of the cameras for reasons other than their skill at predictions. Old forecasts are like old news--soon forgotten--and pundits are almost never asked to reconcile what they said with what actually happened. &lt;em&gt;The one undeniable talent that talking heads have is their skill at telling a compelling story with conviction.&lt;/em&gt;&lt;/p&gt; 
&lt;p&gt;It was easiest to beat chance on the shortest-range questions that only required looking one year out, and accuracy fell off the further out experts tried to forecast, approaching random-chance levels at 3-5 years out.&lt;/p&gt; 
&lt;p&gt;Author: &quot;Call me an optimistic skeptic.&quot;&lt;/p&gt; 
&lt;h2&gt;The Skeptic&lt;/h2&gt; 
&lt;p&gt;(The story of Mohamed Bouazizi, 17 Dec 2010, who self-immolated in Tunisia after a police shakedown and started the Arab Spring.) Could Tom Friedman have predicted the Arab Spring? Of course not. &lt;em&gt;(Black swan event.)&lt;/em&gt;&lt;/p&gt; 
&lt;p&gt;1972: Meteorologist Edward Lorenz publishes &quot;Predictability: Does the Flap of a Butterfly&apos;s Wings in Brazil Set Off a Tornado in Texas?&quot; about tiny data entry variations in computer simulations (0.506127 with 0.506) could product dramatically different long-term forecasts. Inspired &quot;chaos theory&quot;: in nonlinear systems (like the atmosphere) even small changes in initial conditions can mushroom to enormous proportions. This shifted scientific opinion toward the view that there are hard limits on predictability, a deeply philosophical question.&lt;/p&gt; 
&lt;h2&gt;The Optimist&lt;/h2&gt; 
&lt;p&gt;It is one thing to recognize the limits on predictability, and quite another to dismiss &lt;em&gt;all prediction&lt;/em&gt; as an exercise in futility. We make mundane predictions routinely (when to leave the house to avoid traffic, how to anticipate other drivers&apos; behavior, expecting other people to follow through on their commitments to meetings, etc). So much of our reality is this predictable, or more so.&lt;/p&gt; 
&lt;p&gt;Of course each of these pockets of predictability can be abruptly punctured: a restaurant very likely will open its doors when it says it will, but it may not for a number of reasons (manager sleeping late, fire, bankruptcy, pandemic, nuclear war, ...). There are no certainties in life--not even death or taxes, if we assign a nonzero probability to the invention of technologies that let us upload the contents of our brains into a cloud-computing network and the emergence of a future society so public-spirited and prosperous that the state can be funded with charitable donations.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;&lt;em&gt;How predictable something is depends on what we are trying to predict, how far into the future, and under what circumstances.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;Forecasters are often groping in the dark--they have no idea how good their forecasts are in the short, medium, or long term--and no idea how good their forecasts could become. At best, they have vague hunches. That&apos;s because the forecast-measure-revise procedure operates only within the rarified confines of high-tech forecasting. It&apos;s a demand-side problem: the consumers of forecasting don&apos;t demand evidence of accuracy, so there is no measurement, which means no revision, and without revision, they can be no improvement.&lt;/p&gt; 
&lt;p&gt;(History of the Good Judgment Project (GJP) and its efforts.)&lt;/p&gt; 
&lt;p&gt;Two conclusions emerge from this research: One, foresight is real. Two, what makes these superforecasters so good isn&apos;t who they are, it&apos;s what they do: &lt;strong&gt;&lt;em&gt;Foresight isn&apos;t a mysterious gift bestowed at birth. It is the product of particular ways of thinking, of gathering information, of updating beliefs.&lt;/em&gt;&lt;/strong&gt; Broadly speaking, &lt;strong&gt;&lt;em&gt;superforecasting demands thinking that is open-minded, careful, curious and above all, self-critical. It also demands focus. The kind of thinking that produces superior judgment does not come effortlessly--only the determined can deliver it reasonably consistently, which is why our analyses have consistently found commitment to self-improvement to be the strongest predictor of performance.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt; 
&lt;h2&gt;A Forecast About Forecasting&lt;/h2&gt; 
&lt;p&gt;(Discussions about human judgment vs computer machine learning/AI.) &quot;I think it&apos;s going to get stranger and stranger&quot; for people to listen to the advice of experts whose views are informed only by their subjective judgment--human thought is beset by psychological pitfalls. &quot;So what I want is that human expert paired with a computer to overcome the human cognitive limitations and biases.&quot; (David Ferrucci, IBM Watson chief engineer)&lt;/p&gt; 
&lt;p&gt;We will need to blend computer-based forecasting and subjective judgment in the future.&lt;/p&gt; 
&lt;h1&gt;Chapter 2: Illusions of Knowledge&lt;/h1&gt; 
&lt;p&gt;(Discussions of cognitive biases and people loudly proclaiming incorrect conclusions with no proof.)&lt;/p&gt; 
&lt;h1&gt;Chapter 3: Keeping Score&lt;/h1&gt; 
&lt;h1&gt;Chapter 4: Superforecasters&lt;/h1&gt; 
&lt;h1&gt;Chapter 5: Supersmart?&lt;/h1&gt; 
&lt;h1&gt;Chapter 6: Superquants?&lt;/h1&gt; 
&lt;h1&gt;Chapter 7: Supernewsjunkies?&lt;/h1&gt; 
&lt;h1&gt;Chapter 8: Perpetual Beta&lt;/h1&gt; 
&lt;h1&gt;Chapter 9: Superteams&lt;/h1&gt; 
&lt;h1&gt;Chapter 10: The Leader&apos;s Dilemma&lt;/h1&gt; 
&lt;h1&gt;Chapter 11: Are They Really So Super?&lt;/h1&gt; 
&lt;h1&gt;Chapter 12: What&apos;s Next?&lt;/h1&gt; 
&lt;h1&gt;Appendix: 10 Commandments for Aspiring Superforecasters&lt;/h1&gt; 
&lt;p&gt;For more details visit &lt;a href=&quot;http://www.goodjudgment.com&quot;&gt;www.goodjudgment.com&lt;/a&gt;&lt;/p&gt; 
&lt;ol&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Triage&lt;/strong&gt;: Focus on questions where your hard work is likely to pay off; don&apos;t waste time on either easy &quot;clocklike&quot; questions (where simple rules of thumb can get you close to the right answer) or impenetrable &quot;cloud-like&quot; questions (where even fancy statistical models can&apos;t be the dart-throwing champ). Concentrate on questions in the Goldilocks zone of difficulty, where effort pays off the most. ... Triage judgment calls get harder as we come closer to home. ... Certain classes of outcomes have well-deserved reputations for being radically unpredictable, but we usually don&apos;t discover how unpredictable outcomes are until we have spun our wheels for a time trying to gain analytical traction. Bear in mind the two basic errors it is possible to make here: We could fail to try to predict the potentially predictable, or we could waste our time trying to predict the unpredictable. Which error would be worse in the situation you face?&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Break seemingly intractable problems into tractable sub-problems.&lt;/strong&gt; Decompose the problem into its knowable and unknowable parts. Flush ignorance into the open. Expose and examine your assumptions. Dare to be wrong by making your best guesses. Better to discover errors quickly than to hide them behind vague verbiage.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Strike the right balance between inside and outside views.&lt;/strong&gt; Nothing is 100% &quot;unique&quot;; uniqueness is a matter of degree. Conduct creative searches for comparison classes even for seemingly unique events. Superforecasters are in the habit of posing the outside-view question: How often do things of this sort happen in situations of this sort? (Summers&apos; estimates: Larry Summers, a Harvard professor knows about the planning fallacy--estimators tend to underestimate the time they need, often by factors of two or three--so he doubles the estimate, then moves to the next higher time unit. &quot;One hour&quot; becomes &quot;two days&quot;, and &quot;two days&quot; becomes &quot;four weeks&quot;.)&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Strike the right balance between under- and over-reacting to evidence.&lt;/strong&gt; Belief updating is necessary. Don&apos;t suppose that belief updating is always easy because it sometimes is; skillful updating requires teasing subtle signals from noisy news flows, all the while resisting the lure of wishful thinking. Savvy forecasters learn to ferret out telltale clues before the rest of us, snooping for nonobvious lead indicators--what would have to happen before &quot;X&quot; could. The best forecasters tend to be incremental belief updaters, often moving from probabilities of 0.4 to 0.35 or from 0.6 to 0.65. Yet superforecasters also know how to jump (move their probability estimates fast in response to diagnostic signals).&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Look for the clashing causal forces at work in each problem.&lt;/strong&gt; For every good policy argument, there is typically a counterargument that is at least worth acknowledging. Each side should list, in advance, the signs that would nudge them toward the other. In classical dialectics, thesis meets antithesis, producing synthesis. Synthesis is an art that requires reconciling irreducibly subjective judgments.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Strive to distinguish as many degrees of doubt as the problem permits but no more.&lt;/strong&gt; Few things are either certain or impossible, and &quot;maybe&quot; isn&apos;t all that informative. The more degrees of uncertainty you can distinguish, the better a forecaster you are likely to be. Translating vague-verbiage hunches into numeric probabilities feels unnatural at first but it can be done with patience and practice. Don&apos;t reserve rigorous reasoning for trivial pursuits.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Strike the right balance between under- and over-confidence, between prudence and decisiveness.&lt;/strong&gt; Superforecasters understand the risks of both rushing to judgment and of dawdling too long near &quot;maybe&quot;. Long-term accuracy requires getting good scores on both calibration and resolution.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Look for the errors behind your mistakes but beware of rearview-mirror hindsight biases.&lt;/strong&gt; Don&apos;t try to justify or excuse your failures--own them! Conduct unflinching postmortems on both failures and successes: Where exactly did I go wrong (or right)? Remember that although the more common error is to learn too little from failure and to overlook flaws in your basic assumptions, it is also possible to learn too much (you may have been basically on the right track but made a minor technical mistake that had big ramifications).&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Bring out the best in others and let others bring out the best in you.&lt;/strong&gt; Master the fine arts of team management, especially perspective-taking (understanding the arguments of the other side so well that you can reproduce them to the other&apos;s satisfaction), precision questioning (helping others to clarify their arguments so they are not misunderstood), and constructive confrontation (learning to disagree without being disagreeable).&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Master the error-balancing bicycle.&lt;/strong&gt; Implementing each commandment (these 10) requires balacing opposing errors. You can&apos;t become a superforecaster by reading training manuals. Learning requires doing with good feedback that leaves no ambiguity about whether you are succeeding or whether you are failing. Practice is not just going through the motions of making forecasts, or casually reading the news and tossing out probabilities--superforecasting is the product of deep, deliberative practice.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Don&apos;t treat commandments like commandments.&lt;/strong&gt; &quot;It is impossible to lay down binding rules because two cases will never be exactly the same.&quot; --Helmuth von Moltke Guidelines are the best we can do in a world where nothing is certain or exactly repeatable. Superforecasting requires constant mindfulness, even when you are dutifully following these commandments.&lt;/p&gt; &lt;/li&gt; 
&lt;/ol&gt;
	</description>
    </item>
    <item>
      <title>The Edge of Sentience</title>
      <link>https://tedneward.github.io/Research/thinking/the-edge-of-sentience/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">thinking/the-edge-of-sentience/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.edgeofsentience.com/formats&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;&quot;&gt;PDF&lt;/a&gt;&lt;/p&gt; 
&lt;h2&gt;Abstract&lt;/h2&gt; 
&lt;p&gt;Can octopuses feel pain and pleasure? What about crabs, shrimps, insects, or spiders? How do we tell whether a person unresponsive after severe brain injury might be suffering? When does a fetus in the womb start to have conscious experiences? Could there even be rudimentary feelings in miniature models of the human brain, grown from human stem cells? And what about AI? These are questions about the edge of sentience, and they are subject to enormous, disorienting uncertainty. The stakes are immense, and neglecting the risks can have terrible costs. We need to err on the side of caution, yet it’s often far from clear what ‘erring on the side of caution’ should mean in practice. When are we going too far? When are we not doing enough? The Edge of Sentience presents a comprehensive precautionary framework designed to help us reach ethically sound, evidence-based decisions despite our uncertainty.&lt;/p&gt; 
&lt;h2&gt;Analysis&lt;/h2&gt; 
&lt;p&gt;... from &lt;a href=&quot;https://fivebooks.com/best-books/best-philosophy-books-2024-nigel-warburton/&quot;&gt;&quot;Five Books&quot;&lt;/a&gt;:&lt;/p&gt; 
&lt;p&gt;&quot;Jonathan Birch is a philosopher with a research team at the London School of Economics. He’s particularly interested in the idea that we ought to base our ethical interactions with animals on scientific studies of what animals are actually like. So he works with zoologists, ethologists, people who look very closely at animal behaviour.&lt;/p&gt; 
&lt;p&gt;&quot;There are amazing studies that reveal for instance, that individual honey bees are able to learn and are even capable of playing. An insect, which doesn’t seem highly intelligent, and which normally functions as part of a hive, can exhibit surprising abilities if you look closely at what it’s actually doing, or put it in laboratory situations that allow those capabilities to emerge.&lt;/p&gt; 
&lt;p&gt;&quot;Jonathan’s interested in a very wide range of species, and often in species that don’t have cute faces. We don’t tend to attribute the same sensitivity and capacity to feel pain to an insect that we might to a sweet puppy or a baby chimp. Take lobsters. They are killed in quite gruesome ways for culinary purposes. He’s been involved in research that suggests that lobsters have quite sophisticated neural networks and seem to exhibit pain-like behaviour in certain situations. There is sufficient evidence, he believes, to exercise what he calls ‘the precautionary principle.’&quot;&lt;/p&gt; 
&lt;p&gt;&lt;em&gt;That we should assume they feel pain, just in case?&lt;/em&gt;&lt;/p&gt; 
&lt;p&gt;&quot;Yes. The precautionary principle is this: once you get over a threshold of evidence, treat animals as if they are sentient even though there is still some doubt. He’s not saying they are sentient, but that there is sufficient evidence to be more careful about how we treat them. So, you don’t want to drop them in boiling water and let them die slowly, for example. If we are set on killing them and it’s possible to stun lobsters or kill them electronically, then we should do this rather than resort to the boiling water in a saucepan method of killing them.&lt;/p&gt; 
&lt;p&gt;&quot;As I say, he’s not conclusively arguing that they do feel pain. This is the driving force in the way he approaches moral issues around how we treat other animals. If it seems they have the capacity, and there’s scientific evidence to back that up,, then let’s be more careful than we have been to date. Obviously, a lot of factory farming would be beyond the pale for him.&quot;&lt;/p&gt; 
&lt;p&gt;&lt;em&gt;Quite rightly, I think.&lt;/em&gt;&lt;/p&gt; 
&lt;p&gt;&quot;Agreed. But many people find it difficult to imagine that, say, fish or insects have sophisticated capacity for pain, even though the evidence supports the idea that they probably do.&lt;/p&gt; 
&lt;p&gt;&quot;Birch is a superbly clear writer, and he’s very careful to adjust his belief according to the evidence. He’s not a sentimental animal ethicist who thinks, gosh, killing a mosquito is the same as killing a fox. He bases everything that he writes on the available science and sound reasoning from the best data we have.&lt;/p&gt; 
&lt;p&gt;&quot;He’s one of the most interesting public philosophers around today because of his willingness to engage with ideas which have a very broad interest across the world. He’s also adept at dissemination those ideas. By making his book freely available online he has guaranteed a wide readership. He appears on podcasts, radio, and television and is frequently interviewed, more often these days on the potential sentience of AI than on animals. But his deep interest is in sentience in animals.&quot;&lt;/p&gt; 
&lt;p&gt;&lt;em&gt;(by Jonathan Birch, ISBN 9780192870421)&lt;/em&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Simple Rules</title>
      <link>https://tedneward.github.io/Research/thinking/simple-rules/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">thinking/simple-rules/index.html</guid>
      	<description>
	&lt;p&gt;&lt;em&gt;(by Donald Sull, Kathleen M. Eisenhardt)&lt;/em&gt;&lt;/p&gt; 
&lt;h3&gt;Introduction&lt;/h3&gt; 
&lt;p&gt;Effective simple rules share four common traits:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt; &lt;p&gt;They are limited to a handful&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Tailored to the person or organization using them&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Apply to a well-defined activity or decision&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Provide clear guidance while conferring the latitude to exercise discretion&lt;/p&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;&quot;Weaver argued that simple and uncertain problems have largely been solved, and that the greatest challenges of the future would be problems of complexity. … At the personal level, many of us struggle to manage complexity every day. We have to call a teenager to navigate the three remote controls required to turn on ESPN, an accountant to fill out our tax forms, and the IT help desk for guidance every time Microsoft introduces a new version of its software.&quot; (p 10/Kindle location 143)&lt;/p&gt; 
&lt;p&gt;&quot;People often attempt to address complex problems with complex solutions. … Meeting complexity with complexity can create more confusion than it resolves. [US tax code example]&quot; (p11/Kloc161)&lt;/p&gt; 
&lt;p&gt;&quot;Applying complicated solutions to complex problems is an understandable approach, but flawed. The parts of a complex system can interact with one another in many different ways, which quickly overwhelms our ability to envision all possible outcomes. … How many ways can you combine six Lego blocks? For one block, the answer is trivial: 1. With some work, most people can calculate that two blocks combine 24 ways, but by three blocks the calculation becomes tricky (the correct answer is 1,560). When you get to six blocks, the number of possible combinations is daunting. For decades, the commonly accepted answer for six blocks was 103 million combinations, until two mathematicians revisited the problem with some massive computer power and discovered 915 million combinations.&quot; (p13/Kloc 178)&lt;/p&gt; 
&lt;h3&gt;Why Simple Rules Work&lt;/h3&gt; 
&lt;p&gt;Four common traits:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;&lt;em&gt;Simple rules consist of a handful of guidelines applied to a specific activity or decision.&lt;/em&gt;&lt;/strong&gt; Keeping the number of rules to a handful forces you to focus on what matters most. To be used, rules have to be remembered, and limited the number to a handful makes this possible.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;&lt;em&gt;Simple rules are tailored to the situations of the particular people who will use them.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;&lt;em&gt;Simple rules are applied to a single well-defined activity or decision.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;&lt;em&gt;Simple rules give concrete guidance without being overly prescriptive.&lt;/em&gt;&lt;/strong&gt; Simple rules leave room to exercise creativity and pursue unanticipated opportunities.&lt;/p&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Simple rules to seize opportunities&lt;/h4&gt; 
&lt;p&gt;Jesuit order’s success; the &quot;Formula&quot;:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt; &lt;p&gt;carry out whatever task they were assigned&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;favor education&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;released Jesuits from their obligation to recite their daily prayers in unison&lt;/p&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;To be effective, simple rules must fit the task at hand. Simple rules work best when flexibility matters more than consistency. … Both flexibility and consistency have their advantages, but increasing one reduces the other. Detailed rules are particularly useful for avoiding catastrophic errors, such as plane crashes; pilots are fond of saying that &quot;checklists are written in blood&quot;. Detailed rules enhance efficiency in executing routine activities; McDonald’s requires that each franchisee follow the 386-page operating manual. This detailed rule book reduces discretion to a bare minimum, and tips the balance to consistency to ensure predictability, efficiency, and few mistakes.&lt;/p&gt; 
&lt;h4&gt;Simple rules produce better decisions&lt;/h4&gt; 
&lt;p&gt;By using simple rules, people can function without constantly stopping to rethink every aspect of a decision every time they make it.&lt;/p&gt; 
&lt;p&gt;There are some situations where simple rules are not just quick and easy mental shortcuts, they also produce surprisingly accurate decisions. This is especially true in situations when the links between cause and effect are poorly understood, when important variables are highly correlated, when a few factors matter most, and when a gap exists between knowing what to do and actually doing it. Simple rules do not trump complicated models every time, but they do so more often than you might think.&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt; &lt;p&gt;Simple rules can avoid &quot;overfitting&quot; (fitting a model to closely to historical data hardwires error into the model)&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Simple rules can focus only on the most critical variables. By ignoring peripheral factors and tenuous correlations, rules of thumb eliminate a great deal of noise.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Simple rules also capture correlated information about context. … Psychologists have found that people tend to overweigh peripheral variables at the expense of critical ones when they try to take all factors into account. Simple rules minimize the risk of overweighing peripheral considerations by focusing on the criteria most crucial for making good decisions.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Simple rules also make it more likely that people will act on their decisions, because they are easy to remember and less cumbersome to follow than complex guidelines for action.&lt;/p&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;Simple rules not only trigger people to act, they also keep them from abandoning a decision once they have made it.&amp;nbsp;Willpower, it turns out, is more like a reservoir than a river. If we deploy willpower on one decision, we have less self-control available for our next decision. But research finds that people in periods of low willpower can [make good decisions], provided they follow a simple rule.&lt;/p&gt; 
&lt;h4&gt;Simple rules promote collective behavior&lt;/h4&gt; 
&lt;p&gt;Example: honeybees and how they select their new home; &quot;Bees achieve this impressive feat of coordination by following simple rules, such as &quot;Dance longer for better sites&quot;, &quot;Follow the first dancer you bump into&quot;, and &quot;Head-butt scouts promoting other sites&quot;. The rules provide individual scouts with guidance on what to do, while leaving them the freedom to explore unexpected opportunities.&quot; (p40/Kloc 433)&lt;/p&gt; 
&lt;p&gt;Simple rules impose a minimal level of coordination, while leaving ample room for individuals to pursue their own objectives.&amp;nbsp;Zipper uses six simple rules for members sharing a car: (1) report damage, (2) keep it clean, (3) no smoking, (4) fill &apos;er up, (5) return on time, and (6) pets in carriers. When the rules that guide collective behavior are simple and clear, members of a community can monitor one another and sanction anyone who violates the social norms.&lt;/p&gt; 
&lt;p&gt;Simple rules work because they do three things well:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt; &lt;p&gt;They allow for flexibility in the pursuit of new opportunities, avoiding the rigidity of too many rules and the chaos of none at all. They are particularly effective when the situation is in flux, flexibility trumps consistency, and the benefits of seizing opportunities exceed the cost of making mistakes.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Simple rules can produce decisions that match or outperform more sophisticated decision models across a wide variety of possible scenarios, and do so quickly, with limited data requirements, and when cause and effect are imperfectly understood.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Collective action, like the honeybees’ choice of nest, can emerge from simple rules even when individuals’ mental capacity is limited and no one member understands the situation in its entirety. By following a few simple rules, members of a community can produce results, like the choice of a safe nest or the protection of intellectual property, far better than what individuals could do on their own.&lt;/p&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Making Better Decisions&amp;nbsp;(Rules for Decisions)&lt;/h3&gt; 
&lt;p&gt;[Bail decisions]&lt;/p&gt; 
&lt;p&gt;&lt;em&gt;Boundary rules&lt;/em&gt; help you decide between two mutually exclusive alternatives. Boundary rules also help you pick which opportunities to pursue and which to reject when faced with a large number of alternatives. Prioritizing rules rank options to decide which alternatives will receive limited resources, such as medical care during battle or cash in a startup. Prioritizing rules are particularly useful when you lack sufficient resources or time to do everything, or when people hold conflicting views about what to do. Stopping rules dictate when to reverse a decision. They provide guidance, for example, on when to sell a stock, end the search for a mate, or descend from a treacherous mountaintop.&lt;/p&gt; 
&lt;h4&gt;Boundary rules&lt;/h4&gt; 
&lt;p&gt;Because these rules define the boundaries of inclusion or exclusion, they sometimes take the form of negative prohibitions, like the &quot;thou shalt nots&quot; of the Commandments. … Boundary rules narrow down the alternatives, helping people decide which opportunities to pursue in the face of an overwhelming number of choices. Boundary rules provide a quick screen to select the most promising targets based on readily available information which is highly correlated with what makes an opportunity attractive.&lt;/p&gt; 
&lt;p&gt;Example: DARPA’s research initiatives; two boundary rules: the project must further the quest for fundamental scientific understanding, and second, it must have a practical use.&lt;/p&gt; 
&lt;p&gt;Example: clinical depression; four boundary rules: Have you cried more than usual within the last week? Have you been disappointed in yourself or hated yourself within the last week? Have you felt discouraged about the future within the last week? Have you felt that you failed in your life within the last week? Patients who answer yes to all four questions are likely to be clinically depressed, and the rules correctly classified depressed patients over 97% of the time.&lt;/p&gt; 
&lt;p&gt;Boundary rules are also easier to understand and communicate than the results of complicated statistical studies. … Complex models, which make simple statistical problems like [the breast cancer calculation percentage] look like child’s play, are difficult to understand and explain, leading to dangerous misunderstandings. Boundary rules can translate statistical findings into easy-to-use decision aids.&lt;/p&gt; 
&lt;p&gt;Boundary rules can also translate broad policies into practical guidelines. [Example: Obama’s three rules for drone strikes.]&lt;/p&gt; 
&lt;p&gt;Boundary rules guide the choice of what to do (and not do) without requiring a lot of time, analysis or information. Boundary rules work well for categorial choices, like a judge’s yes-or-no decision on a defendant’s bail, and decisions requiring many potential opportunities to be screened quickly. These rules also come in handy when time, convenience, and cost matter. Boundary rules cover the basics of what to do.&lt;/p&gt; 
&lt;h4&gt;Prioritizing rules&lt;/h4&gt; 
&lt;p&gt;&lt;em&gt;Prioritizing rules&lt;/em&gt; can help you rank a group of alternatives competing for scarce money, time, or attention. Prioritizing rules are also relevant in our personal lives for guiding everything from deciding how we spend our limited free time to ranking home-improvement projects. Prioritizing rules are useful when a large number of opportunities meet the threshold of the boundary rules, but resources are limited.&lt;/p&gt; 
&lt;p&gt;[Example: Brazilian rail system decisions]&lt;/p&gt; 
&lt;p&gt;[Example: Valentinian III, providing guidance on how to resolve Rome’s massive conflicting set of laws and interpretations, issues the Law of Citations: first specified a rule that limited the use of historical opinions to those written by five jurists widely acknowledged to be the greatest legal thinkers Rome had ever produced; then laid out four prioritizing rules that further clarified what judges should do: (1) when the jurists unanimously agreed on the issue, the judge was to follow their opinion; (2) if there was disagreement, the judge should follow the majority; (3) if the historical opinions were divided evenly, the judge should follow the opinion of Papinian; (4) if there was a tie among jurists and Papinian did not express an opinion, the judge could rely on his own discretion to decide the matter.]&lt;/p&gt; 
&lt;p&gt;&lt;em&gt;Stopping rules&lt;/em&gt;&lt;/p&gt; 
&lt;p&gt;[Example: Crickets choosing mates] &quot;Choose a mate who meets your quality threshold&quot; is known as the fixed-threshold&amp;nbsp;strategy; lowering the bar if they do not run across enough high-quality options adhere to what is known as the variable-threshold strategy.&lt;/p&gt; 
&lt;p&gt;Whenever alternatives present themselves sequentially (as opposed to all at once), the question of when to stop searching and make a choice arises. Knowing when to stop searching is a thorny problem. Continuing the quest costs time, effort, and opportunity—you forgo listening to a good song while trying to find a great one. But the next tune might be worth the wait. You just don’t know. These are stopping rules. &quot;Nobel Prize-winning economist Herbert A. Simon argued that individuals lack the information, time, and brainpower to determine the single best option when faced with a sequence of alternatives. Instead, like crickets, they rely on a rule of thumb to stop searching when they find an alternative that is good enough. Simon called this rule&amp;nbsp;satisficing, an inelegant but descriptive combination of &quot;satisfy&quot; and &quot;suffice&quot;.&quot; (p64/Kloc829)&lt;/p&gt; 
&lt;p&gt;A well-documented tendency among human decision makers, known as the status quo bias, leads individuals to hold &apos;em when they should fold &apos;em across a range of decisions.&lt;/p&gt; 
&lt;p&gt;[Example: Loeb’s investing strategy rule: &quot;If an investment loses 10 percent of its initial value, sell it.&quot;]&lt;/p&gt; 
&lt;p&gt;[Example: Chicago diners vs Paris eaters; Parisians used rules like &quot;Stop eating when I start feeling full&quot;, whereas Chicago were more likely to follow rules linked to external factors, such as &quot;Stop eating when I run out of a beverage&quot; or &quot;Stop eating when the TV show I’m watching is over&quot;.]&lt;/p&gt; 
&lt;p&gt;Stopping rules are particularly critical in situations when people tend to double down on a losing hand. ... Several factors increase the odds of this error, such as proximity to completion, the desire to save face, reluctance to write off sunk costs, and the fear of living with regret of not trying.&lt;/p&gt; 
&lt;p&gt;[Example: Mt Everest climbing disaster]&lt;/p&gt; 
&lt;h3&gt;Doing Things Better&amp;nbsp;(Rules for Actions)&lt;/h3&gt; 
&lt;p&gt;[Example: Jack’s bar, author-as-bouncer; simple rules for keeping the peace: &quot;Don’t let trouble in the door&quot;; &quot;Stay sober until the last patron leaves&quot;; &quot;Double up for heavy metal, ska, and punk bands&quot;; &quot;Keep the bikers on your side&quot;]&lt;/p&gt; 
&lt;p&gt;&lt;em&gt;Process rules&lt;/em&gt; are more about how to do things better, and center on getting the job at hand done. Process rules work because they steer a middle path between the chaos of too few rules that can result in confusion and mistakes, and the rigidity of so many rules that there is little ability to adapt to the unexpected or take advantage of new opportunities. Simple put, process rules are useful whenever flexibility trumps consistency.&lt;/p&gt; 
&lt;p&gt;&lt;em&gt;How-to rules&lt;/em&gt; guide the basics of executing tasks; coordination rules center on getting something done when multiple actors—people, organizations or nations—have to work together; timing rules center on getting things done in situations where temporal factors such as rhythms, sequences and deadlines are relevant.&lt;/p&gt; 
&lt;h4&gt;How-to rules&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt; &lt;p&gt;How-to rules can provide robust guidance.&lt;/p&gt; &lt;p&gt;[Example: sports announcing; Seymour Joly de Lotbiniere, the &quot;Lenin of the commentary revolution&quot;. A good commenter should: (1) set the scene, (2) describe the action, (3) give the score or results, regularly and succinctly, (4) explain, without interrupting, the stadium’s reaction to the game’s event, (5) share &quot;homework&quot;, such as historical facts and figures or personal information, and (6) assess the significance of the occasion and key moments.]&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;How-to rules are particularly helpful when there is extreme pressure and severe time constraint.&lt;/p&gt; &lt;p&gt;[Example: the Mann Gulch tragedy; four simple rules for how to deal with out-of-control fires: (1) start an escape fire in the path of the advancing fire if possible; (2) go to where the fuel is thinner; (3) turn toward the fire and try to work through it; (4) don’t let the fire choose the spot where it hits you]&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;How-to rules can also foster artistic creativity.&lt;/p&gt; &lt;p&gt;&quot;At first glance, this seems counterintuitive, because following the rules and being creative are often viewed as antithetical. The reality is, however, that a blank canvas and no rules on how to fill it can overwhelm an artist with too many degrees of freedom.&quot;&lt;/p&gt; &lt;p&gt;[Examples of Chinese creativity: first group was simply given the assignment; second group received &quot;Please try to be creative&quot;; third group received simple rules on how to complete the activity, such as &quot;Fold or tear the stickers to vary the shape and size of the materials&quot;.]&lt;/p&gt; &lt;p&gt;Simple rules are not just for beginners, but rather can also stimulate the creativity of master artists.&amp;nbsp;&lt;/p&gt; &lt;p&gt;&quot;Patricia Stokes, a painter and psychologist at Columbia University, studied how influential artists like Claude Monet, William Motherwell, and Piet Mondrian produced their groundbreaking work. She argues that truly original artists work by imposing constraints on themselves, in terms of the subjects they paint, materials they use, and artists they draw upon for inspiration. Monet, for example, purposefully limited his subjects, repeatedly painting pictures, by the dozens, of subjects like grain stacks and water lilies. This self-imposed constraint allowed him to focus on exploring how light changes, and his exploration helped spark a transition in the art world from representation to impressionism, setting the stage for twentieth-century artists like Picasso. By constraining the infinite possibilities, simple rules allow creativity to flourish, less from thinking outside the box and more from deciding how to draw the box in the first place.&quot; (p77/Kloc 1000)&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;How-to rules can also accelerate creativity.&lt;/p&gt; &lt;p&gt;[Example: White Stripes album. Five rules: (1) no blues; (2) no guitar solos; (3) no slide guitar; (4) no covers; (5) no bass. 18 songs in 10 days.) &quot;By restricting their creative process, how-to rules freed the White Stripes to follow a short, clear path to their favorite patch of creativity.&lt;/p&gt; &lt;p&gt;Simple rules can help balance novelty and continuity and add a dash of efficiency to the creative process.&lt;/p&gt; &lt;p&gt;[Example: Elmore Leonard’s forty-six novels. &quot;Avoid prologues&quot;, &quot;Never use a verb other than &apos;said’ to carry dialogue&quot;, &quot;Try to leave out the part that readers tend to skip&quot;.]&lt;/p&gt; &lt;p&gt;How-to rules address the basics of getting things done without prescribing every detail of what to do. They work well in situations where the unexpected is the expected. They can stimulate creativity, shape action when there is no time to plan, and create structure that allows entrepreneurs to grow their company.&lt;/p&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Coordination rules&lt;/h4&gt; 
&lt;p&gt;[Example: flocking behavior of starlings and other birds; Craig Reynolds avian avatar flocking rules: (1) avoid collisions; (2) head in the same direction as your nearest neighbors; (3) stay close to your nearest neighbors.]&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt; &lt;p&gt;Coordination rules work by clarifying what to do in relation to others.&lt;/p&gt; &lt;p&gt;[Example: locust swarms: When the density of locusts exceeds a threshold, they begin to sneak up behind others to bit them. When forced into tight quarters, they follow two simple rules: (1) flee from the locusts chasing you from behind, and (2) try to eat the locust in front of you if it gets too close.]&lt;/p&gt; &lt;p&gt;[Example: improv comedy]&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Coordination rules can be followed by using only local information. Coordination rules also allow for adaptation to local conditions while still recognizing the group objectives.&lt;/p&gt; &lt;p&gt;[Example: Combat. Napoleon: &quot;march toward the sound of gunfire&quot;]&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Coordination rules delineate what to do, and likewise what others should do, so that collective objectives can be achieved. Coordination rules do not deal with when&amp;nbsp;to do something.&lt;/p&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Timing rules&lt;/h4&gt; 
&lt;p&gt;[Example: insomnia. Four simple rules: (1) get up at the same time every morning; (2) avoid going to bed until you feel sleepy; (3) do not stay in bed if you are not sleeping; (4) reduce the time spent in bed.]&lt;/p&gt; 
&lt;p&gt;&lt;em&gt;Timing rules&lt;/em&gt; sometimes taking action when some triggering event happens; event pacing, this kind of rule links actions to events. Other timing rules call for action at a particular time on the clock or calendar—time pacing, creating deadlines and rhythms. Timing rules clarify when to do something and work best when temporal considerations like deadlines, rhythms, and sequences are relevant.&lt;/p&gt; 
&lt;p&gt;[Example: dragonfly migration: (1) fly only when the nighttime temp falls for two consecutive nights; (2) stay put on windy days.]&lt;/p&gt; 
&lt;p&gt;Time pacing rules dictate acting at a particular time on the clock or the calendar, and thereby create rhythms and deadlines.&lt;/p&gt; 
&lt;p&gt;[Example: Pixar studios put into place timing rules: release a new movie every year; release movies at Thanksgiving.]&lt;/p&gt; 
&lt;p&gt;Timing rules are particularly relevant in competitive situations when rivals go out of their way to disrupt their opponents.&lt;/p&gt; 
&lt;p&gt;[Example: Riitta Katila has studied the global robotics industry. Finds that the best firms purposefully stay out of sync with their rivals. They stay ahead by introducing their newest products before their competitors, but they also stay behind by exploiting well-known technology to the fullest, and avoid releasing products when their rivals do.]&lt;/p&gt; 
&lt;p&gt;[Example: Rothschild’s investing rule: &quot;Buy when there is blood in the streets, even if that blood is your own.&quot;]&lt;/p&gt; 
&lt;p&gt;Timing rules can also guide activities that follow predictable patterns or sequences.&lt;/p&gt; 
&lt;h3&gt;Where Simple Rules Come From&lt;/h3&gt; 
&lt;p&gt;[Example: &quot;Hilltopping&quot;--butterfly orgies; (a) &quot;Fly uphill most of the time&quot;, (b) &quot;Fly toward the highest slope in sight&quot;, (c) &quot;Pause to check out local peaks, even if they are not the highest, but leave if you do not get lucky right away&quot;, (d) &quot;Periodically make a random movement&quot;]&lt;/p&gt; 
&lt;h4&gt;Natural selection&lt;/h4&gt; 
&lt;p&gt;Simple rules evolve in communities much as they do in societies as a whole; standup comedians and &quot;Don&apos;t steal jokes&quot;; &quot;Rules evolve to address the most pressing issues in communities.&quot; &quot;While evolved rules benefit from legitimacy and relevance, they also have weaknesses. Evolved rules are often implicit and deeply entrenched, making it difficult to examine them critically when circumstances change, or abandon them when they become dysfunctional. ... Without a guiding hand, rules often take on a life of their own.&quot; (p101/Kloc 1298)&lt;/p&gt; 
&lt;p&gt;Four approaches that people commonly use to formulate rules:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt; &lt;p&gt;People can develop their rules through thoughtful engagement with their own experience, a particularly effective approach for those with lots of relevant history&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;People can also develop their rules by adopting the experiences of others, as conveyed through firsthand advice, books and analogies&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;When high-quality scientific evidence exists, distilling it into simple rules can be the best approach&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Simple rules can arise through negotiation, when diverse stakeholders have divergent aims and views of what to do&lt;/p&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Codifying personal experience&lt;/h4&gt; 
&lt;p&gt;[Example: Tina Fey&apos;s nine rules for managing a comedy show; (4) states, &quot;When hiring, mix Harvard nerds with Chicago improvisers and stir&quot;; (9) is &quot;Never tell a crazy person he&apos;s crazy&quot;.]&lt;/p&gt; 
&lt;p&gt;Values are another source of rules that often arise from personal experience. Personal values can dictate what is correct and even essential to do. &quot;By drawing on their own experience, people are more likely to create relevant rules and to understand where the rules came from and why they matter. When people develop rules themselves and base them on values that matter to them, they also feel a greater ownership over their rules. People are more likely to use rules devised by themselves, reflecting their own values, rather than those imposed on them by someone else. Moreover, when people invest the time to reflect on their experience and codify it into rules, they typically do so with some goal that matters deeply to them.&quot; (p.103/Kloc 1333)&lt;/p&gt; 
&lt;p&gt;[Example: UMichigan study looking at team of 45 employees looking to design a laser printer; need for engineering flow time leads to rules making sure engineers are uninterrupted]&lt;/p&gt; 
&lt;h4&gt;Drawing on the experience of others&lt;/h4&gt; 
&lt;p&gt;Advice from experienced people about how to ..., whether given directly or conveyed through a book or magazine article, can prove useful in formulating one&apos;s own approach.&lt;/p&gt; 
&lt;h4&gt;Personal observation is another effective way to learn what works for others.&lt;/h4&gt; 
&lt;p&gt;We also use analogies, finding similarities between our own experience and others&apos;, which can streamline the process of devising our own rules. ... Analogies involve three elements: (a) a new situation, (b) a prior example that is similar in important respects to the new situation, and (c) rules that can be transferred from the prior example to the current situation.&lt;/p&gt; 
&lt;p&gt;Analogies to existing companies and other competitive domains like sports and battle are a favorite approach of entrepreneurs looking for guidance in attacking new opportunities. ... Analogies can be a powerful source of rules even when the comparison involves two very different domains.&lt;/p&gt; 
&lt;p&gt;It&apos;s possible to be misled by superficial features when deciding when an analogy works. [Example: fictitious scenario involving conflict between small democratic country and large totalitarian one--red herring similarities to WW2 and Vietnam highly color the participants&apos; results.]&lt;/p&gt; 
&lt;h4&gt;Distilling scientific evidence&lt;/h4&gt; 
&lt;p&gt;Scientific knowledge accumulates over time as researchers conduct diverse studies looking at complex phenomena from unique vantage points and with distinctive methodologies. Scientific evidence, however, is not inherently simple. The resulting knowledge is often full of qualifications and contingencies that hold under some circumstances, but not others. One way to develop simple rules is to review a body of scientific research, sort through to determine the most consistent findings across studies, and distill these findings into a few simple rules.&lt;/p&gt; 
&lt;p&gt;[Example: Doctors distilling rules of infection for children.]&lt;/p&gt; 
&lt;p&gt;[Example: Scientists distilling data for rules around sea life.]&lt;/p&gt; 
&lt;p&gt;Distilling the evidence works when there is sufficient, high-quality evidence and when stakeholders view the situation in similar ways.&lt;/p&gt; 
&lt;h4&gt;Negotiating an agreement&lt;/h4&gt; 
&lt;p&gt;[Example: Author&apos;s experience with Executive Education at London Business School] &quot;The key to moving past the political impasse was shifting the debate from, &quot;Which programs should we run?&quot; to &quot;What simple rules should we use to decide which programs to run?&quot; The Executive Education team met with faculty members, explaining the financial situation and drop in rankings, and asked the professors what guidelines they would suggest to manage the program portfolio. The team emphasized that they were aiming for a general set of rules that would apply to every program. The professors argued with one another, but ultimately converged on a handful of robust rules that would work across many situations. ... Of course, individual professors were not pleased when their own programs were cut. But since they had actively participated in negotiating the rules, they were much less likely to oppose the change.&quot; (p114/Kloc 1474)&lt;/p&gt; 
&lt;p&gt;Negotiating simple rules works particularly well when it is cumbersome or impossible to resolve conflicts by escalating them to a higher authority. James Buchanan ... argued that when there are competing interests, it is critical for stakeholders to negotiate decision rules before haggling over specific decisions. An agreed set of rules provides a clear framework for settling contentious issues. When negotiating rules to guide future decisions, stakeholders cannot anticipate every situation or what their interests might be in every case. Since they cannot forecast every contingency, they are more likely to converge on general rules that a wide range of stakeholders can live with and consider fair across a broad set of choices.&lt;/p&gt; 
&lt;p&gt;Negotiation can be a helpful approach even if there is a higher authority, when multiple interest groups are involved, their values conflict, and some facts are hard to come by. [Example: whale-watching rules]&lt;/p&gt; 
&lt;h3&gt;Strategy as Simple Rules&lt;/h3&gt; 
&lt;p&gt;[Example: eToro going from currency trading game platform to social network for traders]&lt;/p&gt; 
&lt;h3&gt;Studying simple rules in action&lt;/h3&gt; 
&lt;p&gt;&quot;The best way to understand something is to try to change it.&quot;&lt;/p&gt; 
&lt;p&gt;&quot;Developing a strategy and implementing it are often viewed as two distinct activities--first you come up with the perfect plan and then you worry about how to make it happen. This approach, common though it is, creates a disconnect between what a company is trying to accomplish and what employees do on a day-to-day basis. ... Strategy and execution, in our view, cannot be separated, because they represent two sides of the same coin. ... &apos;Strategy as Simple Rules&apos; argued that companies can close the gap between strategic intent and day-to-day action by adopting a strategy of simple rules, applying a handful of guidelines to critical activity or decision within the organization. A strategy of simple rules provides the flexibility to seize opportunities, produce good decisions when data and time are scarce, and help the various parts of the organization coordinate their activities to achieve common objectives.&quot; (p121/Kloc 1554)&lt;/p&gt; 
&lt;h4&gt;Strategic process:&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;&lt;em&gt;Figure out what will move the needles&lt;/em&gt;&lt;/strong&gt;: identify the critical choices that will drive a wedge between revenues and costs to increase profits and sustain them over time&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;&lt;em&gt;Choose a bottleneck&lt;/em&gt;&lt;/strong&gt;: identify a bottleneck, a decision or activity that is preventing the company from achieving profitability&lt;/p&gt; &lt;p&gt;In nearly every case, the company&apos;s goals were misunderstood, and top executives disagreed on what mattered most for the company&apos;s success. ... Without a clear understanding of what their company is trying to achieve, executives struggle to identify where to apply simple rules, let alone what the rules should be.&lt;/p&gt; &lt;p&gt;The best bottlenecks to focus on share three characteristics: (a) they have a direct and significant impact on value creation--what moves the needles will vary from company to company and so should the chosen bottleneck; (b) chosen bottlenecks should represent recurrent decisions (rather than one-off choices), so the rules can be tested, refined, and used many times; (c) bottlenecks, as their name implies, arise when opportunities exceed available resources&lt;/p&gt; &lt;p&gt;&quot;The how&amp;nbsp;from a who, what, how analysis is often a good place to start, and often points in the right direction. ... A company&apos;s how&amp;nbsp;will often point to a broad process, such as marketing and sales or new-product development, crucial to creating economic value. These overarching processes consist of several discrete steps, each of which is a candidate for simple rules.&quot;&lt;/p&gt; &lt;p&gt;&quot;When searching for the right bottleneck, it helps to look for a critical activity where the number of opportunities exceeds the available resources, such as when sales opportunities outstrip a company&apos;s ability to meet demand. ... Choosing external partners is another bottleneck where opportunities often exceed a firm&apos;s capacity to pursue them. ... Decisions that require coordination across different departments or teams are another good place to look for bottlenecks.&quot;&lt;/p&gt; &lt;p&gt;&quot;When it comes to deciding where to apply simple rules, the most obvious activity is not always the right answer.&quot;&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;&lt;em&gt;Craft the rules&lt;/em&gt;&lt;/strong&gt;: a set of simple rules that, when applied to the bottleneck, improves profitability&lt;/p&gt; &lt;p&gt;Developing rules from the top down is a big mistake. When leaders rely on their gut instincts, they overemphasize recent events, build in their personal biases, and ignore data that doesn&apos;t fit with their preconceived notions. It is much better to involve a team (4-8 members) and use a structured process to harness members&apos; diverse insights and points of view. When drafting the team to develop simple rules, it is critical to include some of the people who will be using them on a day-to-day basis. ... Having users make the rules confers several advantages: (a) they are closest to the facts on the ground and best positioned to codify experience into usable rules; (b) because they will make decisions based on the rules, they can strike the right balance between guidance and discretion, avoiding rules that are overly vague or restrictive; (c) users can also phrase the rules in language that resonates for them, rather than relying on business jargon; (d) by actively participating in the process, users are more likely to buy into the final rules and therefore apply them in practice; (e) firsthand knowledge also makes it easier to explain the rules, and their underlying rationale, to colleagues who did not participate in the process.&lt;/p&gt; &lt;p&gt;It is critical to test your first-cut rules in a rigorous fashion, and refine them in light of your findings.&lt;/p&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Getting Personal&lt;/h3&gt; 
&lt;p&gt;[Applying the above three-step process to personal goals; same process, different scope; fill in any details later]&lt;/p&gt; 
&lt;p&gt;[Example: dating]&lt;/p&gt; 
&lt;p&gt;[Example: managing depression]&lt;/p&gt; 
&lt;p&gt;[Example: winning friends and influencing people]&lt;/p&gt; 
&lt;h3&gt;Rules for Improvement&lt;/h3&gt; 
&lt;h3&gt;Breaking the Rules&lt;/h3&gt; 
&lt;h3&gt;Conclusion&lt;/h3&gt; 
&lt;p&gt;Overcoming the barriers to simplicity&lt;/p&gt; 
&lt;p&gt;The effort required to develop simple rules.&lt;/p&gt; 
&lt;p&gt;The people who benefit from complexity.&lt;/p&gt; 
&lt;p&gt;The &quot;myth of requisite complexity&quot;.&lt;/p&gt; 
&lt;p&gt;Whether simple rules or detailed regulations are more effective is ultimately an empirical question that should be resolved by testing them to see which works better in the real world. ... Often, complex rules and regulations arise out of a distrust of human nature. If people cannot be trusted to do the right thing, detailed regulations are necessary to prevent malfeasance. [Example: Netflix&apos;s HR policies. &quot;After studying their human resources policies, Netflix determined that 97% of their employees were trustworthy. ... Rather than continue to produce binders of detailed regulations, Netflix executives concentrated on not hiring people who would cause problems, and removing them quickly when hiring mistakes were made. This change allowed the company to replace thick manuals with simple rules. The company&apos;s policy for expenses, travel, gifts, and conducting personal business at work, for example, was reduced to four rules: (1) expense what you would not otherwise spend, (2) travel as if it were your own money, (3) disclose nontrivial gifts from vendors, and (4) do personal stuff at work when it is inefficient not to.&quot; (p227/Kloc2924)&lt;/p&gt; 
&lt;p&gt;Rules to liberate&lt;/p&gt; 
&lt;p&gt;Rules enable as well as constrain. They provide a threshold level of structure while leaving ample scope to exercise discretion. ... Close to the facts on the ground, individuals can draw on their judgment and creativity to manage risk and seize unexpected opportunities. The latitude to exercise discretion not only makes simple rules effective, it makes them attractive. People thrive when given the opportunity to apply their judgment and creativity to situations they face from day to day. And if they benefit from simple rules, they are more likely to use them and use them well.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Sway</title>
      <link>https://tedneward.github.io/Research/thinking/sway/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">thinking/sway/index.html</guid>
      	<description>
	&lt;p&gt;&lt;em&gt;(by (author), (publisher))&lt;/em&gt;&lt;/p&gt; 
&lt;h2&gt;Preface&lt;/h2&gt; 
&lt;p&gt;Asbestos &amp;amp; open-heart surgery -&amp;gt; ignoring the O-ring -&amp;gt; diagnosing the wrong patient -&amp;gt; where business &amp;amp; psychology collide&lt;/p&gt; 
&lt;h2&gt;Chapter 1: Anatomy of an accident&lt;/h2&gt; 
&lt;p&gt;Taking off at Tenerife -&amp;gt; the oversensitive egg shoppers -&amp;gt; would you like insurance with that? -&amp;gt; so long, Martha&apos;s Vineyard&lt;br&gt; * hidden forces/currents behind some of our decision making:&lt;br&gt; &amp;nbsp;&amp;nbsp; * loss aversion (tendency to go to great lengths to avoid possible losses)&lt;br&gt; &amp;nbsp;&amp;nbsp; * value attribution (inclination to imbue a person/thing with certain qualities based on an initial perceived value)&lt;br&gt; &amp;nbsp;&amp;nbsp; * diagnosis bias (blindness to all evidence that contradicts our initial assessment)&lt;/p&gt; 
&lt;h2&gt;Chapter 2: The swamp of commitment&lt;/h2&gt; 
&lt;p&gt;Playing not to lose -&amp;gt; fun-n-gun -&amp;gt; only the Gators walked out alive -&amp;gt; the $204 twenty-dollar bill -&amp;gt; the end of the Great Society -&amp;gt; &quot;we don&apos;t even know where the tunnel is&quot;&lt;br&gt; * loss aversion + commitment =&amp;gt; Vietnam&lt;/p&gt; 
&lt;h2&gt;Chapter 3: The Hobbit &amp;amp; the Missing Link&lt;/h2&gt; 
&lt;p&gt;the real-life Indiana Jones -&amp;gt; the hunt for the missing link -&amp;gt; the Stradivarius on the subway -&amp;gt; what&apos;s in a five-cent hot dog, anyway? -&amp;gt; Homer Simpson &amp;amp; Piltdown Man -&amp;gt; can a discount drink decrease IQ? -&amp;gt; Shakespeare was wrong -&amp;gt; a paleontological lineup&lt;/p&gt; 
&lt;h2&gt;Chapter 4: Michael Jordan &amp;amp; the first-rate interview&lt;/h2&gt; 
&lt;p&gt;the curse of the low draft pick -&amp;gt; the &quot;cold&quot; professor -&amp;gt; what lovesick college freshmen have in common w/ HR managers -&amp;gt; when a pretty face equals a higher interest rate -&amp;gt; the &quot;mirror, mirror&quot; effect -&amp;gt; the Joe Friday solution&lt;/p&gt; 
&lt;h2&gt;Chapter 5: The Bipolar Epidemic &amp;amp; the Chameleon Effect&lt;/h2&gt; 
&lt;p&gt;A psychiatric outbreak -&amp;gt; sugar pills &amp;amp; prozac -&amp;gt; tricking Israeli army commanders -&amp;gt; how to sound beautiful -&amp;gt; how old do you feel? -&amp;gt; the love bridge&lt;/p&gt; 
&lt;h2&gt;Chapter 6: In France, the Sun revolves around the Earth&lt;/h2&gt; 
&lt;p&gt;Who wants to trick a millionaire? -&amp;gt; splitting the pie -&amp;gt; sentimental car dealers -&amp;gt; the talking cure for felons &amp;amp; venture capitalists -&amp;gt; russian justice -&amp;gt; the rational machiguenga&lt;br&gt; * fairness is important in dealings, but fairness is relative to society&lt;/p&gt; 
&lt;h2&gt;Chapter 7: Compensation &amp;amp; cocaine&lt;/h2&gt; 
&lt;p&gt;Switzerland&apos;s toxic conundrum -&amp;gt; the GMAT rebels -&amp;gt; the tower of the pleasure center &amp;amp; hijacking altruism -&amp;gt; fast times at &quot;Commie High&quot; -&amp;gt; the anticipation factor&lt;br&gt; * pleasure center &amp;amp; altruism centers cannot both operate simultaneously&lt;br&gt; * the anticipation factor drives the addictive behavior &amp;amp; suppresses the altruism center&lt;/p&gt; 
&lt;h2&gt;Chapter 8: dissenting justice&lt;/h2&gt; 
&lt;p&gt;The Supreme Court conference -&amp;gt; peer pressure &amp;amp; coke-bottle glasses -&amp;gt; Ferris Bueler &amp;amp; the blocker -&amp;gt; &quot;we are not focusing ont he name you give to potatoes&quot; -&amp;gt; the captain is not God -&amp;gt; not just thinking out loud -&amp;gt; justice has been served&lt;br&gt; * Group dynamics: initiator, blocker, supporter, observer&lt;br&gt; * Power of even just one dissenter to break the tyranny of the majority&lt;br&gt; * Crew Resource Management (CRM): facts, challenge, action&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Thinking Fast and Slow</title>
      <link>https://tedneward.github.io/Research/thinking/thinking-fast-and-slow/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">thinking/thinking-fast-and-slow/index.html</guid>
      	<description>
	&lt;p&gt;&lt;em&gt;(by Daniel Kahneman)&lt;/em&gt;&lt;/p&gt; 
&lt;p&gt;&lt;em&gt;I, &lt;a href=&quot;http://omgitsmgp.com/&quot;&gt;Michael Parker&lt;/a&gt;, own this book and took these notes to further my own learning. If you enjoy these notes, please &lt;a href=&quot;http://www.amazon.com/Thinking-Fast-Slow-Daniel-Kahneman/dp/0374533555&quot;&gt;purchase the book&lt;/a&gt;!&lt;/em&gt;&lt;/p&gt; 
&lt;h3&gt;Introduction&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;We use resemblance as a simplifying heuristic to make difficult judgment, causing predictable biases in predictions.&lt;/li&gt; 
 &lt;li&gt;Social scientists in the 1970s broadly accepted that people are generally rational, and emotions such as fear, affection, and hatred explain departures from rationality.&lt;/li&gt; 
 &lt;li&gt;People tend to assess the relative importance of issues by the ease with which they are retrieved from memory, which is largely determined by the media.&lt;/li&gt; 
 &lt;li&gt;Accurate intuitions of experts are better explained by the effects of prolonged practice than by heuristics.&lt;/li&gt; 
 &lt;li&gt;Valid intuitions develop when experts have learned to recognize familiar elements in a new situation and to act in a manner that is appropriate to it.&lt;/li&gt; 
 &lt;li&gt;When faced with a difficult question, we often answer an easier one instead, usually without noticing the substitution.&lt;/li&gt; 
 &lt;li&gt;When intuition fails, because neither an expert solution nor a heuristic answer comes to mind, we resort to slower, deliberate, and effortful thinking.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Part 1: Two Systems&lt;/h3&gt; 
&lt;h4&gt;Ch 1: The Characters of the Story&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;System 1 operates automatically and quickly, with no effort and no voluntary control.&lt;/li&gt; 
 &lt;li&gt;System 2 allocates attention to effortful mental activities. It&apos;s associated with the subjective experience of agency, choice, and concentration.&lt;/li&gt; 
 &lt;li&gt;All operations of System 2 require attention and are disrupted when attention is drawn away.&lt;/li&gt; 
 &lt;li&gt;System 2 has some ability to change the way System 1 works, by programming the normally automatic functions of attention and memory.&lt;/li&gt; 
 &lt;li&gt;System 1 generates impressions, intuitions, intentions, and feelings. Those endorsed by System 2 turn into beliefs and voluntary actions.&lt;/li&gt; 
 &lt;li&gt;Most of what System 2 thinks and does originates in your System 1, but System 2 takes over when things get difficult, and it normally has the last word.&lt;/li&gt; 
 &lt;li&gt;One of the tasks of System 2 is to overcome the impulses of System 1. System 2 is in charge of self-control.&lt;/li&gt; 
 &lt;li&gt;System 2 is too slow and inefficient to substitute for System 1. The best we can do is to recognize when mistakes are likely, and to try harder to avoid significant mistakes when the stakes are high.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Ch 2: Attention and Effort&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;Pupils are sensitive indicators of mental effort. The more System 2 exerts mental effort, the more they dilate.&lt;/li&gt; 
 &lt;li&gt;We decide what to do, but we have limited control over the effort of doing it. The task at hand decides this.&lt;/li&gt; 
 &lt;li&gt;Orienting and responding quickly to the gravest threats or most promising situations improved the chance of survival.&lt;/li&gt; 
 &lt;li&gt;In the economy of action, effort is a cost, and the acquisition of skill is driven by balancing benefits and costs. Laziness is in our nature.&lt;/li&gt; 
 &lt;li&gt;System 2 is the only one that can follow rules, compare objects on several attributes, and make deliberate choices between objects.&lt;/li&gt; 
 &lt;li&gt;A crucial capability of System 2 is that it can program memory to obey an instruction that overrides habitual responses.&lt;/li&gt; 
 &lt;li&gt;Multitasking is effortful. Time pressure is another driver. Any task that requires keeping several ideas in mind simultaneously has the same hurried character.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Ch 3: The Lazy Controller&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;Mihaly&apos;s flow is a state of effortless concentration so deep that people lose a sense of time, of themselves, and of their problems.&lt;/li&gt; 
 &lt;li&gt;This flow separates the two forms of effort: Concentration on the task and the deliberate control of attention.&lt;/li&gt; 
 &lt;li&gt;People who are cognitively busy are more likely to yield to temptation, make selfish choices, use sexist language, and make superficial judgments in social situations.&lt;/li&gt; 
 &lt;li&gt;Controlling thoughts and behaviors is one of the tasks that System 2 performs.&lt;/li&gt; 
 &lt;li&gt;If you exert self-control for a task, then you are less willing or able to exert self-control for a following task. This is called &lt;em&gt;ego depletion&lt;/em&gt;.&lt;/li&gt; 
 &lt;li&gt;When you are thinking hard or exerting self-control, your blood glucose level drops. The implication is that you can undo ego depletion by ingesting glucose.&lt;/li&gt; 
 &lt;li&gt;When people believe a conclusion is true, they are also very likely to believe arguments that appear to support it, even when those arguments are unsound.&lt;/li&gt; 
 &lt;li&gt;Intelligence is not only the ability to reason; it is also the ability to find relevant material in memory and to deploy attention when needed.&lt;/li&gt; 
 &lt;li&gt;&quot;Engaged&quot; people are more alert, less willing to be satisfied with superficially attractive answers, and more skeptical about their intuitions.&lt;/li&gt; 
 &lt;li&gt;People who are not &quot;engaged&quot; are impulsive, impatient, and keen to receive immediate gratification.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Ch 4: The Associative Machine&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;The responses by System 1 are &lt;em&gt;associatively coherent&lt;/em&gt;, yielding a self-reinforcing pattern of cognitive, emotional, and physical responses.&lt;/li&gt; 
 &lt;li&gt;Cognition is embodied. You think with your body, not only with your brain.&lt;/li&gt; 
 &lt;li&gt;Ideas are nodes in a vast network called associative memory, where causes link to effects, things to their properties, and things to their categories.&lt;/li&gt; 
 &lt;li&gt;Priming is not restricted to concepts and words. Events that you are not even aware of prime your actions and emotions.&lt;/li&gt; 
 &lt;li&gt;The influence of an action by the idea is called the ideomotor effect. It also works in reverse. For example, thinking of old age makes you act old, and vice versa.&lt;/li&gt; 
 &lt;li&gt;Money primes individualism: a reluctance to be involved with others, to depend on others, or to accept demands from others.&lt;/li&gt; 
 &lt;li&gt;Feeling that one&apos;s soul is stained triggers a desire to cleanse one&apos;s body, an impulse that is dubbed the Lady Macbeth Effect.&lt;/li&gt; 
 &lt;li&gt;System 1 provides the impressions that often turn into your beliefs, and is the source of impulses that often become the choices of our actions.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Ch 5: Cognitive Ease&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;Cognitive strain is affected by both the current level of effort and the presence of unmet demands. This mobilizes System 2.&lt;/li&gt; 
 &lt;li&gt;A repeated experience, clear display, primed idea, and good mood all increase cognitive ease. This in turn makes things feel familiar, true, good, and effortless.&lt;/li&gt; 
 &lt;li&gt;When strained, you are vigilant, suspicious, invest more effort, feel less comfortable, and make fewer errors. But you are less intuitive and less creative.&lt;/li&gt; 
 &lt;li&gt;Predictable illusions occur if judgment is based on an impression of cognitive ease or strain. For example, frequent repetition makes people believe lies.&lt;/li&gt; 
 &lt;li&gt;To craft a persuasive message, use high quality paper, bright colors, simple words, memorable verse, and quote the source with the simpler name.&lt;/li&gt; 
 &lt;li&gt;Cognitive strain, whatever the source, mobilizes System 2, which is more likely to reject the intuitive answer suggested by System 1.&lt;/li&gt; 
 &lt;li&gt;The mere exposure effect links the repetition of an arbitrary stimulus and the mild affection that people have for it. It&apos;s stronger for stimuli that we don&apos;t consciously see.&lt;/li&gt; 
 &lt;li&gt;Mood affects the operation of System 1. When we are uncomfortable and unhappy, we lose touch with our intuition.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Ch 6: Norms, Surprises, and Causes&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;The main function of System 1 is to maintain and update a model of your personal world, which represents what is normal in it.&lt;/li&gt; 
 &lt;li&gt;Norm theory is when a surprising event happens, and subsequent surprising events will appear more normal because they are interpreted in conjunction with it.&lt;/li&gt; 
 &lt;li&gt;We have norms for a vast number of categories, which provide the background for the immediate detection of anomalies.&lt;/li&gt; 
 &lt;li&gt;System 1 is adept at finding a coherent causal story that links the fragments of knowledge at its disposal.&lt;/li&gt; 
 &lt;li&gt;We are ready from birth to have &lt;em&gt;impressions&lt;/em&gt; of causality, which do not depend on reasoning about patterns or causation. They are products of System 1.&lt;/li&gt; 
 &lt;li&gt;We are prone to apply causal thinking to situations that require statistical reasoning, but System 1 cannot do this, and System 2 requires necessary training.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Ch 7: A Machine for Jumping to Conclusions&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;Jumping to conclusions is efficient if the jump saves time and effort, the conclusion is likely correct, and the cost of an occasional mistake is acceptable.&lt;/li&gt; 
 &lt;li&gt;System 1 bets on answers, where recent events and the current context have the most weight in determining and interpretation. Otherwise, more distant memories govern.&lt;/li&gt; 
 &lt;li&gt;System 1 is gullible and biased to believe, while System 2 is in charge of doubting and unbelieving, but System 2 is sometimes busy and often lazy.&lt;/li&gt; 
 &lt;li&gt;Unlike scientists, which test hypotheses by trying to refute them, we seek data that are likely to be compatible with the beliefs that we currently hold.&lt;/li&gt; 
 &lt;li&gt;The tendency to like or dislike everything about a person, including things you have not observed, is known as the &lt;em&gt;halo effect&lt;/em&gt;.&lt;/li&gt; 
 &lt;li&gt;The halo effect increases the weight of first impressions, sometimes to the point that subsequent information is mostly wasted.&lt;/li&gt; 
 &lt;li&gt;To derive the most useful information from multiple sources of evidence, you should always try to make these sources independent of each other.&lt;/li&gt; 
 &lt;li&gt;The standard practice of open discussion gives too much weight to the opinions of those who speak early and assertively, causing others to line up behind them.&lt;/li&gt; 
 &lt;li&gt;System 1 excels at constructing the best possible story that incorporates ideas currently activated, but it cannot allow for information that it does not have.&lt;/li&gt; 
 &lt;li&gt;Jumping to conclusions facilitates the achievement of coherence and of the cognitive ease that causes us to accept a statement as true. It explains overconfidence.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Ch 8: How Judgments Happen&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;System 1 continually assesses the problems that an organism must solve to survive. We equate good mood and cognitive ease with safety and familiarity.&lt;/li&gt; 
 &lt;li&gt;Faces with a strong chin and a slight confident-appearing smile exude confidence.&lt;/li&gt; 
 &lt;li&gt;A &lt;em&gt;judgment heuristic&lt;/em&gt; is falling back on a simpler assessment that is made quickly and automatically and is available when System 2 must make its decision.&lt;/li&gt; 
 &lt;li&gt;Because System 1 represents categories by a prototype or a set of typical exemplars, it deals well with averages but poorly with sums.&lt;/li&gt; 
 &lt;li&gt;System 1 allows &lt;em&gt;matching&lt;/em&gt; intensity across diverse and unrelated dimensions. This mode of prediction by matching is statistically wrong, although acceptable to both systems.&lt;/li&gt; 
 &lt;li&gt;The control over intended computations is far from precise, and we often compute much more than we want or need. This is called the &lt;em&gt;mental shotgun&lt;/em&gt;.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Ch 9: Answering an Easier Question&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;If we can&apos;t satisfactorily answer a hard &lt;em&gt;target question&lt;/em&gt;, then System 1 invokes &lt;em&gt;substitution&lt;/em&gt; by recalling and answering an easier &lt;em&gt;heuristic question&lt;/em&gt;.&lt;/li&gt; 
 &lt;li&gt;After answering a heuristic question, System 1 uses intensity matching to translate this answer to an answer of the target question.&lt;/li&gt; 
 &lt;li&gt;The dominance of conclusions over arguments is most pronounced when emotions are involved.&lt;/li&gt; 
 &lt;li&gt;An &lt;em&gt;affect heuristic&lt;/em&gt; is when people let their likes and dislikes determine their beliefs about the world.&lt;/li&gt; 
 &lt;li&gt;While self-criticism is one of the functions of System 2, it is more of an apologist for than a critic of the emotions of System 1.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Part 2: Heuristics and Biases&lt;/h3&gt; 
&lt;h4&gt;Ch 10: The Law of Small Numbers&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;System 1 is inept when faced with statistical facts, which change the probability of outcomes but do not cause them to happen.&lt;/li&gt; 
 &lt;li&gt;Extreme outcomes, both high and low, are most likely to be found in small than in large samples.&lt;/li&gt; 
 &lt;li&gt;Even statistical experts pay insufficient attention to sample size, and have poor intuitions of sampling effects.&lt;/li&gt; 
 &lt;li&gt;System 2 is capable of doubt, but sustaining doubt is harder work than sliding into certainty.&lt;/li&gt; 
 &lt;li&gt;System 1 runs ahead of the facts and constructs a rich image based on scraps of evidence, causing us to exaggerate the consistency and coherence of what we see.&lt;/li&gt; 
 &lt;li&gt;The associative machine seeks causes. But instead of focusing on how the event came to be, the statistical view relates it to what could have happened instead.&lt;/li&gt; 
 &lt;li&gt;We do not expect to see regularity produced by a random process. When we detect what appears to be a rule, we quickly reject the idea that the process is truly random.&lt;/li&gt; 
 &lt;li&gt;We pay more attention to the content of messages than to information about their reliability. Consequently we view the world in a simpler and more coherent way than the data justify.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Ch 11: Anchors&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;An &lt;em&gt;anchoring effect&lt;/em&gt; occurs when people consider a particular value for an unknown quantity before estimating that quantity.&lt;/li&gt; 
 &lt;li&gt;Adjusting your estimate away from the anchor is an effortful activity. Insufficient adjustment, where we accept the anchor, is a sign of a weak or lazy System 2.&lt;/li&gt; 
 &lt;li&gt;Anchoring is also a priming effect, which selectively evokes compatible evidence. This is the automatic operation of System 1.&lt;/li&gt; 
 &lt;li&gt;The &lt;em&gt;anchoring index&lt;/em&gt; is 100% for people who adopt the anchor as an estimate, and zero for people who are able to ignore the anchor altogether.&lt;/li&gt; 
 &lt;li&gt;Anchors that are obviously random can be just as effective as potentially informative anchors.&lt;/li&gt; 
 &lt;li&gt;When negotiating, don&apos;t make an outrageous counteroffer to an outrageous proposal, but make a scene and make it clear that you won&apos;t continue with that number on the table.&lt;/li&gt; 
 &lt;li&gt;To resist anchoring effects, search your memory for arguments against the anchor. This negates the biased recruitment of thoughts that produces these effects.&lt;/li&gt; 
 &lt;li&gt;System 2 is susceptible to the biasing effect of some anchors that makes some information easier to retrieve. It has control over or knowledge of the effect.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Ch 12: The Science of Availability&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;The &lt;em&gt;availability heuristic&lt;/em&gt; replaces estimating the size of a category or frequency of an event with the ease with which instances come to mind.&lt;/li&gt; 
 &lt;li&gt;Salient events, dramatic events, and personal experiences versus experiences by others bias the ease with which instances come to mind.&lt;/li&gt; 
 &lt;li&gt;This explains why everyone in a group may feel as though he or she does more than his or her fair share.&lt;/li&gt; 
 &lt;li&gt;By asking people to provide more instances of a given behavior, you increase their struggle, and consequently they conclude that they don&apos;t adopt that behavior.&lt;/li&gt; 
 &lt;li&gt;Judgment is influenced more by the ease of retrieval than the number of instances retrieved. Increasing the number of requested instances therefore weakens judgment.&lt;/li&gt; 
 &lt;li&gt;When you provide a spurious reason for the difficulty of retrieving a large number of instances, judgment is again strengthened. The surprise is eliminated.&lt;/li&gt; 
 &lt;li&gt;People who are personally involved in the judgment are more likely to consider the number of instances and less likely to go by fluency.&lt;/li&gt; 
 &lt;li&gt;Fluency of instances is a System 1 heuristic, which is replaced by a focus on content when System 2 engages.&lt;/li&gt; 
 &lt;li&gt;Merely reminding people of a time when they had power increases their apparent trust in their own intuition.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Ch 13: Availability, Emotion, and Risk&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;Our expectations about the frequency of events are distorted by the prevalence and emotional intensity of the messages to which we are exposed.&lt;/li&gt; 
 &lt;li&gt;Jonathan Haidt said &quot;the emotional tail wags the rational dog.&quot;&lt;/li&gt; 
 &lt;li&gt;An &lt;em&gt;availability cascade&lt;/em&gt; is the self-sustaining chain of events through which a minor event leads to public panic and large-scale government action.&lt;/li&gt; 
 &lt;li&gt;Policy is about what people want and what is best for them. The availability cascade is the mechanism through which biases flow into policy.&lt;/li&gt; 
 &lt;li&gt;When dealing with small risks, we either ignore them or give them far too much weight, with no middle ground.&lt;/li&gt; 
 &lt;li&gt;Availability cascades may have a long-term benefit of calling attention to classes of risks and by increasing the risk-reduction budget.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Ch 14: Tom W&apos;s Speciality&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;The proportion of a particular class in a population is called the &lt;em&gt;base rate&lt;/em&gt; of that class.&lt;/li&gt; 
 &lt;li&gt;How much an instance conforms to the stereotype of a particular class is called the &lt;em&gt;representativeness&lt;/em&gt; of that instance.&lt;/li&gt; 
 &lt;li&gt;To determine how likely an instance belongs to a class, we ignore the base rate of the class and focus on the representativeness of the instance.&lt;/li&gt; 
 &lt;li&gt;Probability by representativeness is more accurate than chance guesses, but neglecting base rate information that points in another direction is a statistical sin.&lt;/li&gt; 
 &lt;li&gt;When endorsing representativeness, System 1 will automatically process the available information as if it were true, unless you decide immediately to reject it.&lt;/li&gt; 
 &lt;li&gt;Bayesian statistics govern how we should adjust the base rates given an account of representativeness.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Ch 15: Linda: Less is More&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;A &lt;em&gt;conjunction fallacy&lt;/em&gt; is when we judge a conjunction of two events to be more probable than one of the events in a direct comparison.&lt;/li&gt; 
 &lt;li&gt;The most coherent stories are not the most probable, but they are plausible. And we confuse the notions of coherence, plausibility, and probability.&lt;/li&gt; 
 &lt;li&gt;Consequently, adding details to a scenario can make it more persuasive, but less likely to come true.&lt;/li&gt; 
 &lt;li&gt;When performing single evaluation instead of joint evaluation, the &lt;em&gt;less is more&lt;/em&gt; principle evaluates a collection of items by its average and not its sum.&lt;/li&gt; 
 &lt;li&gt;The sum-like nature of a variable is less obvious for probability than something more enumerable like money.&lt;/li&gt; 
 &lt;li&gt;A question phrased as &quot;how many&quot; makes you think of individuals, while &quot;what percentage&quot; does not. This decreases the incidence of the conjunction fallacy.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Ch 16: Causes Trump Statistics&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;em&gt;Statistical base rates&lt;/em&gt; are facts about a population to which a case belongs, but they are not relevant to the individual case.&lt;/li&gt; 
 &lt;li&gt;&lt;em&gt;Causal base rates&lt;/em&gt; change your view of how the case came to be.&lt;/li&gt; 
 &lt;li&gt;We neglect statistical base rates, and we easily combine causal base rates with other case-specific information.&lt;/li&gt; 
 &lt;li&gt;Resistance to stereotyping is a laudable moral position, but neglecting valid stereotypes inevitably leads to suboptimal judgments.&lt;/li&gt; 
 &lt;li&gt;System 1 can deal with stores in which the elements are causally linked, but it is weak in statistical reasoning.&lt;/li&gt; 
 &lt;li&gt;Individuals feel relieved of responsibility when they know that others have heard the same request for help.&lt;/li&gt; 
 &lt;li&gt;When the outcome surprises us, we are unwilling to deduce the particular from the general, but are willing to infer the general from the particular.&lt;/li&gt; 
 &lt;li&gt;Consequently, we are more likely to learn something by finding surprises in our own behavior than by hearing surprising facts about people in general.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Ch 17: Regression to the Mean&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;em&gt;Regression to the mean&lt;/em&gt; is when poor performance is followed by improvement, and good performance is followed by deterioration.&lt;/li&gt; 
 &lt;li&gt;We tend to be nice to other people when they please us and nasty when they do not, we are statistically punished for being nice and rewarded for being nasty.&lt;/li&gt; 
 &lt;li&gt;The discrepancies between two trials does not need a causal explanation. Often luck explains why one is a significant outlier.&lt;/li&gt; 
 &lt;li&gt;The &lt;em&gt;correlation coefficient&lt;/em&gt; between two measures is a measure of the relative weight of the factors they share.&lt;/li&gt; 
 &lt;li&gt;Whenever the correlation between two scores is imperfect, there will be regression to the mean.&lt;/li&gt; 
 &lt;li&gt;Causal explanations will be evoked when we detect regression, but they will be wrong because regression to the mean has an explanation but does not have a cause.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Ch 18: Taming Intuitive Predictions&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;We are capable of rejecting information as irrelevant and false, but adjusting for smaller weaknesses in the evidence is not something System 1 can do.&lt;/li&gt; 
 &lt;li&gt;If we are asked for a prediction but substitute an evaluation of the evidence, we generate biased predictions that completely ignore regression to the mean.&lt;/li&gt; 
 &lt;li&gt;To create an unbiased prediction, start with a baseline estimate and an estimate derived from the evidence, and choose the value between them that is proportional to your estimate of correlation.&lt;/li&gt; 
 &lt;li&gt;Such unbiased predictions make errors, but they are smaller and do not favor either higher or lower outcomes.&lt;/li&gt; 
 &lt;li&gt;Unbiased predictions permit predicting rare or extreme cases only when the information is very good, so you&apos;ll never have the satisfaction of calling an extreme case.&lt;/li&gt; 
 &lt;li&gt;Unbiased predictions are less preferred when error has varying types and severity, and extreme cases must be called correctly even if it accumulates error elsewhere.&lt;/li&gt; 
 &lt;li&gt;Your intuitions will deliver predictions that are too extreme and you will be inclined to put far too much faith into them.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Part 3: Overconfidence&lt;/h3&gt; 
&lt;h4&gt;Ch 19: The Illusion of Understanding&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;We are always ready to interpret behavior as a manifestation of general propensities and personality traits, or causes that you readily match to effects.&lt;/li&gt; 
 &lt;li&gt;In a story, many of the important events that involve choices tempts us to exaggerate the role of skill and underestimate the part of luck.&lt;/li&gt; 
 &lt;li&gt;When you adopt a new view of the world, you immediately lose much of your ability to recall what you used to believe before your mind changed.&lt;/li&gt; 
 &lt;li&gt;This causes us to underestimate the extent to which we were surprise by past events, also known as &lt;em&gt;hindsight bias&lt;/em&gt;.&lt;/li&gt; 
 &lt;li&gt;Hindsight bias leads us to asses the quality of a decision not by whether the process was sound but by whether its outcome was good or bad.&lt;/li&gt; 
 &lt;li&gt;The sense-making System 1 makes us see the world as more tidy, simple, predictable, and coherent than it really is. So we think that we can predict the future.&lt;/li&gt; 
 &lt;li&gt;The comparison of firms that have been more or less successful is to a significant extent a comparison between firms that have been more or less lucky.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Ch 20: The Illusion of Validity&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;Declarations of high confidence tell you that an individual has constructed a coherent story in his or her mind, not necessarily that the story is true.&lt;/li&gt; 
 &lt;li&gt;The persistence of individual differences in achievement is the measure by which we confirm the existence of skill in someone.&lt;/li&gt; 
 &lt;li&gt;Facts that challenge basic assumptions, and thereby threaten our livelihood and self-esteem, are simply not absorbed. The mind does not digest them.&lt;/li&gt; 
 &lt;li&gt;People can maintain an unshakeable faith, however absurd, when they are surrounded by a community of like-minded believers.&lt;/li&gt; 
 &lt;li&gt;A person who acquires more knowledge develops an enhanced illusion of skill and becomes unrealistically overconfident. They have many excuses ready when proven wrong.&lt;/li&gt; 
 &lt;li&gt;Errors in prediction are inevitable because the world is unpredictable. And high subjective confidence is not an indicator of accuracy.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Ch 21: Intuitions vs Formulas&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;Roughly 60% of studies have shown significantly better accuracy for algorithms in comparisons of clinical and statistical predictions.&lt;/li&gt; 
 &lt;li&gt;One reason experts may be inferior is that they try to be clever, think outside the box, and consider complex combinations of features. This actually reduces validity.&lt;/li&gt; 
 &lt;li&gt;Another reason is that when asked to evaluate the same information twice, we frequently give different answers. Unnoticed stimuli can substantially influence System 1.&lt;/li&gt; 
 &lt;li&gt;Assigning equal weights to all predictors is often superior than varying weights found by multiple regression, because it&apos;s not affected by accidents of sampling.&lt;/li&gt; 
 &lt;li&gt;Consequently, we can develop useful algorithms without any prior statistical research. And back of the envelope judgments are often good enough.&lt;/li&gt; 
 &lt;li&gt;The aversion to algorithms making decisions is rooted in the strong preference that many people have for the natural over the synthetic or artificial.&lt;/li&gt; 
 &lt;li&gt;Intuition adds value, but only after a disciplined collection of objective information and disciplined scoring of separate traits.&lt;/li&gt; 
 &lt;li&gt;When creating your own formula for an interview procedure, pick at most six dimensions, and develop a 1 to 5 scale for each one.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Ch 22: Expert Intuition: When Can We Trust It?&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;In the &lt;em&gt;recognition-primed decision&lt;/em&gt; model, System 1 comes up with a plan. System 2 simulates it. If it works, it&apos;s implemented. Otherwise it&apos;s tweaked or discarded.&lt;/li&gt; 
 &lt;li&gt;Emotional learning may be quick, but expertise takes time to develop because it requires building a large collection of mini-skills.&lt;/li&gt; 
 &lt;li&gt;Confidence does not imply truth. The associative machine suppresses doubt and evokes ideas that are compatible with the current dominant story.&lt;/li&gt; 
 &lt;li&gt;Skilled intuitions come from environments where the environment is sufficiently regular to be predictable, and we can learn these regularities through prolonged practice.&lt;/li&gt; 
 &lt;li&gt;Human learning is normally efficient. If a strong predictive cue exists, human observers are likely to find it, given a sufficient opportunity to do so.&lt;/li&gt; 
 &lt;li&gt;Algorithms perform better in noisy environments because they detect weakly valid cues, and they use such cues consistently.&lt;/li&gt; 
 &lt;li&gt;The unrecognized limits of professional skill help explain why experts are often overconfident.&lt;/li&gt; 
 &lt;li&gt;Judgments that answer the wrong question can also be made with high confidence.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Ch 23: The Outside View&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;Confidentially collecting the judgment of each person in a group makes better use of the knowledge of its members.&lt;/li&gt; 
 &lt;li&gt;Our &lt;em&gt;inside view&lt;/em&gt; judgment is overly optimistic, while the &lt;em&gt;outside view&lt;/em&gt; judgment rightly adjusts a baseline prediction.&lt;/li&gt; 
 &lt;li&gt;We routinely discard statistical information, such as that offered by the outside view, when it&apos;s incompatible with personal impressions of a case.&lt;/li&gt; 
 &lt;li&gt;A &lt;em&gt;planning fallacy&lt;/em&gt; is unrealistically close to a best-case scenario, and could be improved by consulting the statistics of similar cases.&lt;/li&gt; 
 &lt;li&gt;To counter the planning fallacy, &lt;em&gt;reference class forecasting&lt;/em&gt; uses distributional information to create a baseline prediction. This adopts an outside view.&lt;/li&gt; 
 &lt;li&gt;People often, but not always, take on risky projects because they are overly optimistic about the odds they face.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Ch 24: The Engine of Capitalism&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;The people who have the greatest influence on the lives of others are likely to be optimistic and overconfident, and to take more risks than they realize.&lt;/li&gt; 
 &lt;li&gt;The optimistic risk taking of entrepreneurs contributes to the economic dynamism of society, even if most risk takers end up disappointed.&lt;/li&gt; 
 &lt;li&gt;We rate ourselves below average on any task we find difficult, and so we are overly optimistic about our standing on any activity we do moderately well.&lt;/li&gt; 
 &lt;li&gt;Entrepreneurs imagine a future where their actions determine the outcome of the firm, and not their competitors. This is because they know so little about these competitors.&lt;/li&gt; 
 &lt;li&gt;This &lt;em&gt;competition neglect&lt;/em&gt; begets more competitors than the market can profitably sustain, and so the average outcome is a loss.&lt;/li&gt; 
 &lt;li&gt;A wide confidence interval is a confession of ignorance, which is not socially acceptable for someone who is paid to be knowledgeable. So we must be overconfident.&lt;/li&gt; 
 &lt;li&gt;Optimism is highly valued, both socially and in the market, and so we reward the providers of dangerously misleading information more than we reward truth tellers.&lt;/li&gt; 
 &lt;li&gt;Optimism contributes to resilience by defending one&apos;s self image, where we take credit for successes but little blame for failures.&lt;/li&gt; 
 &lt;li&gt;A &lt;em&gt;premortem&lt;/em&gt; assumes that a year has passed, you implemented the plan as it exists, and the outcome was a disaster. It explains why.&lt;/li&gt; 
 &lt;li&gt;This counters overconfident optimism by escaping groupthink, and unleashing the imagination of knowledgeable individuals in a much needed direction.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Part 4: Choices&lt;/h3&gt; 
&lt;h4&gt;Ch 25: Bernoulli&apos;s Errors&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;Choices between simple gambles provide a simple model that shares important features with the more complex decisions that researchers actually aim to understand.&lt;/li&gt; 
 &lt;li&gt;Expected utility theory defined axioms of rationality. Prospect theory examines why we deviate this theory under risk.&lt;/li&gt; 
 &lt;li&gt;A risk-averse decision maker will choose a sure thing that is less than the expected value of a gamble, paying a premium to avoid uncertainty.&lt;/li&gt; 
 &lt;li&gt;Bernoulli proposed that the psychological gamble isn&apos;t the weighted average of the monetary values, but the weighted average of the utility of these outcomes.&lt;/li&gt; 
 &lt;li&gt;Prospect theory states that happiness is determined by the recent change in wealth, and not its absolute value. It defines a reference point for happiness.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Ch 26: Prospect Theory&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;You know you have made a theoretical advance when you can no longer reconstruct why you failed for so long to see the obvious.&lt;/li&gt; 
 &lt;li&gt;Your personal wealth does not determine your attitudes to gains and losses. We like winning and dislike losing. And we dislike losing more than you like winning.&lt;/li&gt; 
 &lt;li&gt;In financial outcomes, the reference point can be the status quo, what you expect, or what you feel entitled to. Better outcomes are gains. Worse outcomes are losses.&lt;/li&gt; 
 &lt;li&gt;A principle of diminishing sensitivity applies to changes of wealth, both for gains and losses.&lt;/li&gt; 
 &lt;li&gt;We typically only accept a bet if its &lt;em&gt;loss aversion ratio&lt;/em&gt;, or its ratio of gains to losses, is a minimum between 1.5 and 2.5.&lt;/li&gt; 
 &lt;li&gt;In mixed gambles, where both a gain and a loss are possible, loss aversion causes extremely risk-averse choices.&lt;/li&gt; 
 &lt;li&gt;In bad choices, where a sure loss is compared to a larger loss that is merely possible, diminishing sensitivity causes risk seeking.&lt;/li&gt; 
 &lt;li&gt;But prospect theory cannot deal with disappointment. It also cannot deal with regret, such as losing the gamble and foregoing the sure option.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Ch 27: The Endowment Effect&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;Indifference curves assume that your utility depends entirely on the present situation, and that the evaluation of a possible job does not depend on your current job.&lt;/li&gt; 
 &lt;li&gt;In labor negotiations and bargaining, the reference point and loss aversion is well understood. But their omission in most scenarios is &lt;em&gt;theory-induced blindness&lt;/em&gt;.&lt;/li&gt; 
 &lt;li&gt;Loss aversions says the disadvantages of a change loom larger than its advantages. This introduces a bias that favors the status quo.&lt;/li&gt; 
 &lt;li&gt;Under the &lt;em&gt;endowment effect&lt;/em&gt;, owning a good increases its value. Your minimum selling price greatly exceeds your maximum buying price, violating rational economic behavior.&lt;/li&gt; 
 &lt;li&gt;The endowment effect applies to goods &quot;for use,&quot; or consumed or enjoyed. It doesn&apos;t apply to goods &quot;for exchange,&quot; or traded for other goods.&lt;/li&gt; 
 &lt;li&gt;Loss aversion is built into the automatic evaluations of System 1. Consider the baby who holds on fiercely to a toy and shows agitation when it is taken away.&lt;/li&gt; 
 &lt;li&gt;Selling goods activates regions of the brain that are associated with disgust as pain. Buying activates these areas if the price is too high.&lt;/li&gt; 
 &lt;li&gt;Veteran traders are unaffected by the endowment effect. They ask &quot;How much do I want to &lt;em&gt;have&lt;/em&gt; this good, compared with other things I could have instead?&quot;&lt;/li&gt; 
 &lt;li&gt;Being poor is living below one&apos;s reference point. Small amounts of money they receive are a reduced loss, not a gain. All their choices, then, are between losses.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Ch 28: Bad Events&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;Our brain prioritizes threats above opportunities. It can process hostile images that we can&apos;t consciously see, and can quickly pick hostile faces out from a crowd.&lt;/li&gt; 
 &lt;li&gt;Even symbolic threats evoke in attenuated form many reactions of the real thing, including fractional tendencies to avoid or approach, recoil or lean forward.&lt;/li&gt; 
 &lt;li&gt;Given a goal, not achieving it is a loss, while exceeding it is a gain. But the aversion to the failure of not reaching a goal is stronger than the desire to exceed it.&lt;/li&gt; 
 &lt;li&gt;Negotiations are difficult because losses by one side induce pain that exceeds the pleasure of the gains by the other side.&lt;/li&gt; 
 &lt;li&gt;An existing wage, price, or rent sets a reference point that is entitled. We think that exploiting market power to impose losses on others is unacceptable.&lt;/li&gt; 
 &lt;li&gt;A firm has its own entitlement, which is to retain its current profit. But we think it&apos;s not unfair for a firm to reduce its workers&apos; wages when its profitability is falling.&lt;/li&gt; 
 &lt;li&gt;If a merchant lowers the price of a good, customers who bought at the higher price think of themselves as having sustained a loss that is more than appropriate.&lt;/li&gt; 
 &lt;li&gt;Punishing one stranger for behaving unfairly to another stranger activates the pleasure centers of the brain.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Ch 29: The Fourfold Pattern&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;When mapping decision weights to outcome probabilities, they are not equal in value, contrary to the &lt;em&gt;expectation principle&lt;/em&gt;.&lt;/li&gt; 
 &lt;li&gt;We overweight unlikely events, which illustrates the &lt;em&gt;possibility effect&lt;/em&gt;. We underweight highly likely events, which illustrates the &lt;em&gt;certainty effect&lt;/em&gt;.&lt;/li&gt; 
 &lt;li&gt;We also have inadequate sensitivity to intermediate probabilities. The range of decision weights is much smaller than the range of probabilities.&lt;/li&gt; 
 &lt;li&gt;Paying a premium to eliminate a worry with certainty is compatible with the psychology of worry but not with the rational model.&lt;/li&gt; 
 &lt;li&gt;Between a sure loss and a gamble with a high probability of a larger loss, diminishing sensitivity makes the sure loss more aversive, and the certainty effect reduces the aversiveness of the gamble.&lt;/li&gt; 
 &lt;li&gt;This explains why people accept a high probability of making things worse for a small hope of avoiding a large loss, which can turn manageable failures into disasters.&lt;/li&gt; 
 &lt;li&gt;These same two factors enhance the attractiveness of the sure thing and reduce the attractiveness of the gamble when the out come is positive.&lt;/li&gt; 
 &lt;li&gt;Systematic deviations from expected value are costly in the long run. This rule applies to both risk aversion and to risk seeking.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Ch 30: Rare Events&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;Emotion and vividness influence fluency, availability, and judgments of probability, and thus account for our excessive response to the few rare events we don&apos;t ignore.&lt;/li&gt; 
 &lt;li&gt;People overestimate the probabilities of unlikely events, and overweight unlikely events in their decisions.&lt;/li&gt; 
 &lt;li&gt;If the event we are asked to estimate is very unlikely, we instead focus on its alternative. We focus on the odd, different, and unusual.&lt;/li&gt; 
 &lt;li&gt;A rich and vivid representation of the outcome, whether or not it is emotional, reduces the role of probability in the evaluation of an uncertain prospect.&lt;/li&gt; 
 &lt;li&gt;The &lt;em&gt;denominator effect&lt;/em&gt; is when your attention is drawn to one outcome that &quot;stands out,&quot; and you do not assess the alternative outcome with the same care.&lt;/li&gt; 
 &lt;li&gt;We weight low-probability events more when stated in terms of relative frequencies (how many) than when stated in more abstract terms of &quot;chances,&quot; &quot;risk,&quot; and &quot;probability&quot; (how likely).&lt;/li&gt; 
 &lt;li&gt;In &lt;em&gt;choice from experience&lt;/em&gt;, instead of &lt;em&gt;choices from description&lt;/em&gt;, we are exposed to variable outcomes from the same source, and so we do not overweight rare events.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Ch 31: Risk Policies&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;Every simple choice formulated as gains and losses can be deconstructed in innumerable ways into a combination of choices, yielding preferences that are likely to be inconsistent.&lt;/li&gt; 
 &lt;li&gt;If paying a premium for sure gains and to avoid a sure loss come out of the same pocket, the discrepant attitudes are unlikely to be optimal.&lt;/li&gt; 
 &lt;li&gt;We prefer &lt;em&gt;narrow framing&lt;/em&gt;, or considering a sequence of simple decisions, even when we must entertain &lt;em&gt;broad framing&lt;/em&gt;, or considering the decisions jointly.&lt;/li&gt; 
 &lt;li&gt;Narrow framing of gambles leads to loss aversion. Broad framing treats each gamble as one of many, blunting the emotional reaction to loss and increasing the tolerance of risk.&lt;/li&gt; 
 &lt;li&gt;Closely following daily fluctuations is a losing proposition, because the pain of small losses exceeds the pleasure of equally frequent small gains.&lt;/li&gt; 
 &lt;li&gt;A &lt;em&gt;risk policy&lt;/em&gt; eliminates the pain of occasional loss by the thought that the policy that left you exposed to it will be advantageous to you over the long run.&lt;/li&gt; 
 &lt;li&gt;While an outside view protects you from the exaggerated optimism of the planning fallacy, a risk policy protects you from the exaggerated caution induced by loss aversion.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Ch 32: Keeping Score&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;The emotion that people attach to the state of our &lt;em&gt;mental accounts&lt;/em&gt; are not acknowledged in standard economic theory.&lt;/li&gt; 
 &lt;li&gt;The &lt;em&gt;disposition effect&lt;/em&gt; is the bias in finance to sell winners rather than losers, and is an instance of narrow framing.&lt;/li&gt; 
 &lt;li&gt;The &lt;em&gt;sunk-cost fallacy&lt;/em&gt; invests additional resources in a losing account when better investments are available. It prefers an unfavorable gamble to a sure loss.&lt;/li&gt; 
 &lt;li&gt;Members of a board will replace a CEO with one who does not carry the same mental accounts and is therefore better able to ignore sunk costs of past involvements.&lt;/li&gt; 
 &lt;li&gt;A poignant story evokes more regret if it involves unusual events, because such events attract attention and are easier to undo in our imagination.&lt;/li&gt; 
 &lt;li&gt;People expect to have stronger emotional reactions to an outcome that is produced by action than to the same reaction when it is produced by inaction.&lt;/li&gt; 
 &lt;li&gt;When you deviate from the default, you can easily imagine the norm. If the default is associated with bad consequences, the discrepancy can be a source of painful emotions.&lt;/li&gt; 
 &lt;li&gt;You will be more loss averse in situations that are more important than money, and more reluctant to sell important endowments when it might lead to an awful outcome.&lt;/li&gt; 
 &lt;li&gt;To inoculate yourself against regret, remind yourself of its possibility and that things can go badly, and preclude any hindsight that might cause it.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Ch 33: Reversals&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;We normally experience situations in which contrasting alternatives are absent, and so moral intuitions that come to your mind in different scenarios are inconsistent.&lt;/li&gt; 
 &lt;li&gt;Preference reversal can occur if joint evaluation focuses attention on a situational aspect that is less salient than in single evaluation.&lt;/li&gt; 
 &lt;li&gt;The emotional reactions of System 1 likely determine single evaluation, while the comparison and careful evaluation required by joint evaluation calls for System 2.&lt;/li&gt; 
 &lt;li&gt;Judgments and preferences are coherent within categories but potentially incoherent when the objects are evaluated belonging to different categories.&lt;/li&gt; 
 &lt;li&gt;The &lt;em&gt;evaluability hypothesis&lt;/em&gt; states that some attributes are only given weight in a joint evaluation because they are not evaluable on their own.&lt;/li&gt; 
 &lt;li&gt;Be wary of joint evaluation when someone who controls what you see has a vested interest in what you choose.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Ch 34: Frames and Reality&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;em&gt;Losses&lt;/em&gt; evoke stronger negative feelings than &lt;em&gt;costs&lt;/em&gt; do, and so the cost of a lottery ticket that did not win is more acceptable than losing a gamble.&lt;/li&gt; 
 &lt;li&gt;&quot;Rational&quot; subjects, which are least susceptible to framing effects, showed enhanced activity in the frontal area of the brain that is implicated in combining emotion and reasoning.&lt;/li&gt; 
 &lt;li&gt;Reframing is effortful and System 2 is normally lazy. Most of us passively accept decisions as they are framed, and so our preferences are &lt;em&gt;frame-bound&lt;/em&gt; and not &lt;em&gt;reality-bound&lt;/em&gt;.&lt;/li&gt; 
 &lt;li&gt;Broader frames and inclusive accounts generally lead to more rational decisions.&lt;/li&gt; 
 &lt;li&gt;Opt-in versus opt-out is another framing effect. We check a box if we&apos;ve already decided what we wish to do. But if unprepared for the question, laziness prefers the default.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Part 5: Two Selves&lt;/h3&gt; 
&lt;h4&gt;Ch 35: Two Selves&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;The decision maker who pays different amounts to achieve the same gain or be spared the same loss is making a mistake.&lt;/li&gt; 
 &lt;li&gt;The &lt;em&gt;peak-end rule&lt;/em&gt; states that a global retrospective rating is dominated by the highest score (the peak) and the final score (the end).&lt;/li&gt; 
 &lt;li&gt;The &lt;em&gt;duration neglect&lt;/em&gt; states that the length of the evaluated activity has no effect whatsoever on its evaluation.&lt;/li&gt; 
 &lt;li&gt;The &lt;em&gt;experiencing self&lt;/em&gt;, which evaluates each moment, does not have a voice. The &lt;em&gt;remembering self&lt;/em&gt;, which keeps score and governs what we learn, makes our decisions.&lt;/li&gt; 
 &lt;li&gt;What we learn from the past is to maximize the qualities of our future memories, not necessarily our future experience.&lt;/li&gt; 
 &lt;li&gt;This is a feature of System 1, which represents sets by averages, norms, and prototypes. Not by sums.&lt;/li&gt; 
 &lt;li&gt;In some cases rats who can stimulate their brain by pressing a lever will die of starvation without taking a break to feed themselves.&lt;/li&gt; 
 &lt;li&gt;A memory that neglects duration will not serve our preference for long pleasures and short pains.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Ch 36: Life as a Story&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;Duration neglect is normal in a story. A story is about significant events and memorable events like its ending, not about time passing.&lt;/li&gt; 
 &lt;li&gt;The peak-end rule and duration effect also influence our evaluation of others&apos; lives.&lt;/li&gt; 
 &lt;li&gt;Vacation pictures may be important to the remembering self. The photographer does not view the scene as a moment to be savored but as a future memory to be designed.&lt;/li&gt; 
 &lt;li&gt;We use the word &quot;memorable&quot; to describe vacation highlights, which explicitly reveals the goal of the experience.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Ch 37: Experienced Well-Being&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;A small fraction of the population endures most of the suffering, whether because of illness, an unhappy temperament, or misfortunes or tragedies.&lt;/li&gt; 
 &lt;li&gt;Our emotional state is largely determined by what we attend to, and we are normally focused on our current activity and immediate environment.&lt;/li&gt; 
 &lt;li&gt;Less commuting, greater availability of child care, and improved socializing opportunities can reduce the &quot;unhappiness index&quot; of a society.&lt;/li&gt; 
 &lt;li&gt;From Gallup data, some life aspects, such as education, is associated with a higher evaluation of one&apos;s life, but not with greater experienced well-being.&lt;/li&gt; 
 &lt;li&gt;Religion has favorable impact on both positive affect and stress reduction than on life evaluation, but provides no reduction of feelings of depression or worry.&lt;/li&gt; 
 &lt;li&gt;Being poor makes one miserable. A salary beyond $75,000 may enhance one&apos;s life satisfaction, but it does not improve experienced well-being.&lt;/li&gt; 
 &lt;li&gt;Higher income allows the purchase of many pleasures, but it also reduces the ability to enjoy the smaller things in life. Therefore the emotional experience is unchanged.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Ch 38: Thinking About Life&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;em&gt;Affective forecasting&lt;/em&gt; is the forecast of one&apos;s personal state in the future. An error happens when you think statistics don&apos;t apply to you.&lt;/li&gt; 
 &lt;li&gt;The score you assign to your life is determined by a small sample of highly available ideas, and not a careful weighing of the domains of your life.&lt;/li&gt; 
 &lt;li&gt;Both experienced temperament and life satisfaction are largely determined by the genetics of temperament.&lt;/li&gt; 
 &lt;li&gt;Setting goals that are especially difficult to attain leads to a dissatisfied adulthood. We must consider what people want in the concept of well-being.&lt;/li&gt; 
 &lt;li&gt;The &lt;em&gt;focusing illusion&lt;/em&gt; states that nothing in life is as important as you think it is when you are thinking about it.&lt;/li&gt; 
 &lt;li&gt;This illusion can cause people to be wrong about their present state of well-being as well as the happiness of others, and about their own happiness in the future.&lt;/li&gt; 
 &lt;li&gt;The term &lt;em&gt;miswanting&lt;/em&gt; describes bad choices that arise from the errors of affective forecasting. The focusing illusion is a rich source of it.&lt;/li&gt; 
 &lt;li&gt;The focusing illusion favors goods or experiences that are initially exciting but may lose their appeal. It appreciates less experiences that retain their attention value.&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Good Strategy Bad Strategy</title>
      <link>https://tedneward.github.io/Research/thinking/good-strategy-bad-strategy/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">thinking/good-strategy-bad-strategy/index.html</guid>
      	<description>
	&lt;p&gt;&lt;em&gt;(by Richard Rumelt; ISBN )&lt;/em&gt;&lt;/p&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;The most basic idea of strategy is the application of strength against weakness. Or, if you prefer, strength applied to the most promising opportunity.&lt;/p&gt; 
 &lt;p&gt;A Good Strategy identifies the one or two critical issues — and then focuses and concentrates action and resources on them. It doesn’t just draw on existing strength; it creates strength through the coherence of its design.&lt;/p&gt; 
&lt;/blockquote&gt; 
&lt;h1&gt;Introduction: Overwhelming obstacles&lt;/h1&gt; 
&lt;p&gt;Core of strategy work: Discovering the critical factors in a situation and designing a way of coordination and focusing actions to deal with those factors.&lt;/p&gt; 
&lt;p&gt;Good strategy honestly acknowledges the challenges being faces and provides an approach to overcoming them.&lt;/p&gt; 
&lt;p&gt;Strategy selects the path, identifying how, why, and where determination and leadership are to be applied.&lt;/p&gt; 
&lt;p&gt;Strategy must include concrete actions (“Implementation”).&lt;/p&gt; 
&lt;p&gt;Goal setting != strategy.&lt;/p&gt; 
&lt;h1&gt;Part 1: Good and bad strategy&lt;/h1&gt; 
&lt;p&gt;Basic idea of strategy: apply strength to opportunity.&lt;/p&gt; 
&lt;p&gt;A strategy is like a lever that magnifies force. Yes, you might be able to drag a giant block of rock across the ground with muscles, ropes and motivation. But it is wiser to build levers and wheels and then move the rock. Unlike a stand-alone decision or a goal, a strategy is a coherent set of analyses/concepts/policies/arguments/actions that respond to a high-stakes challenge.&lt;/p&gt; 
&lt;p&gt;Sources of strength:&lt;br&gt; * Having a coherent strategy, one that creates strength.&lt;br&gt; * Subtle shifts in viewpoints.&lt;/p&gt; 
&lt;p&gt;A leader identifies the one or two critical issues in the situation — and then focuses and concentrates action and resources on them.&lt;/p&gt; 
&lt;p&gt;Good strategy almost always looks simple and obvious; doesn&apos;t require huge #s of Powerpoint slides to explain, and is not auto-generated from &quot;strategic management&quot; tools (matrix, chart, triangle, or fill-in-the-blanks).&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;&lt;em&gt;A good strategy honestly acknowledges the challenges being faced and provides an approach to overcoming them. And the greater the challenge, the more a strategy focuses and coordinates efforts to achieve a powerful competitive punch or problem-solving effect.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;End result should be a strategy that is aimed at channelling energy into what seem to be one or two of the most attractive opportunities, where it looks like you can make major inroads or breakthroughs.&lt;/p&gt; 
&lt;h2&gt;Chapter 1 - Good strategy is unexpected&lt;/h2&gt; 
&lt;p&gt;The first natural advantage of good strategy arises because other organisations often don’t have one. And because they don’t expect you to have one. ... Instead, they have multiple goals and initiatives to symbolize progress, but no coherent approach to accomplish that progress other than &quot;spend more and try harder&quot;.&lt;/p&gt; 
&lt;p&gt;Apple strategy: survive and wait for the next big thing. Succeed on that next thing.&lt;/p&gt; 
&lt;p&gt;Good strategy requires leaders who are willing and able to say no to a wide variety of actions and interests. Strategy is at least as much about what an organisation does not do as it is about what it does.&lt;/p&gt; 
&lt;h2&gt;Chapter 2 - Discovering power&lt;/h2&gt; 
&lt;p&gt;When there is a successful company, there is always failing competition. Learn from both. What the competition was not able to copy?&lt;/p&gt; 
&lt;p&gt;Wal-Mart: did not break conventional wisdom; it broke the definition of store.&lt;/p&gt; 
&lt;p&gt;US Department of Defense: From pure military capabilities to asymmetric cost on opponent.&lt;/p&gt; 
&lt;h2&gt;Chapter 3 - Bad strategy&lt;/h2&gt; 
&lt;p&gt;Hallmarks of bad strategy:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Fluff: Origin in […] and recently in the IT industry.&lt;/li&gt; 
 &lt;li&gt;Failure to face the challenge.&lt;/li&gt; 
 &lt;li&gt;Mistaking goals for strategy.&lt;/li&gt; 
 &lt;li&gt;Bad strategic objectives: 
  &lt;ul&gt; 
   &lt;li&gt;Fail to address critical issues.&lt;/li&gt; 
   &lt;li&gt;Impracticable.&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;True expertise is making a complex subject understandable.&lt;/p&gt; 
&lt;p&gt;If a challenge is not defined, it is impossible to assess the quality of the strategy.&lt;/p&gt; 
&lt;p&gt;Strategy work is episodic, not annual.&lt;/p&gt; 
&lt;p&gt;One of the challenges of being a leader is mastering the shift from having others define your goals to being the architect of the organization’s purpose and objectives.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Goal&lt;/strong&gt;: overall values and desires.&lt;br&gt; &lt;strong&gt;Objective&lt;/strong&gt;: specific operational target.&lt;br&gt; &lt;strong&gt;&lt;em&gt;Strategy transforms goals into coherent actionable objectives.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;Good strategy focuses on one or very few pivotal objectives.&lt;/p&gt; 
&lt;p&gt;Underperformance is not a challenge; is a result. The true challenges are the reasons for it.&lt;/p&gt; 
&lt;h2&gt;Chapter 4 - Why so much bad strategy?&lt;/h2&gt; 
&lt;p&gt;Bad strategy is the active avoidance of the hard work of crafting a good strategy.&lt;/p&gt; 
&lt;p&gt;If you fail to identify and analyse the obstacles you don’t have a strategy. All you have is a stretch goal, a budget, or a list of things you wish would happen.&lt;/p&gt; 
&lt;h3&gt;Some Forms of Bad Strategy&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Dog’s Dinner Objectives&lt;/strong&gt;: A long list of &quot;things to do,&quot; often mislabeled as &quot;strategies&quot; or &quot;objectives.&quot; These lists usually grow out of planning meetings in which stakeholders state what they would like to accomplish, then they throw these initiatives onto a long list called the &quot;strategic plan&quot; so that no one’s feelings get hurt, and they apply the label &quot;long-term&quot; so that none of them need be done today.&lt;/p&gt; &lt;p&gt;A lot of companies conflate OKRs (Objectives and Key Results) with strategy. OKRs shouldn&apos;t replace strategy work. The process typically looks like this:&lt;br&gt; * once a year, each department head is asked to come up with their own departmental OKRs, which are supposed to be connected to company goals (increase revenue, decrease costs, etc.).&lt;br&gt; * Then each department breaks down their OKRs into sub-OKRs for their teams to carry out,&lt;br&gt; * which are then broken down into sub-sub-OKRs for sub-teams and/or specific people,&lt;br&gt; * so on down the chain.&lt;/p&gt; &lt;p&gt;This process just perpetuates departmental silos and are rarely cohesive or mutually supportive of each other (if this does happen, it’s usually a happy accident). Department and team leaders often throw dependencies on other departments and teams, which causes extra work for teams that they often haven’t planned for and aren’t connected to their own OKRs, which drags down the efficiency and effectiveness of the entire organization. It’s easy for leaders to underestimate this drag since it’s hard to measure, and what isn’t measured isn’t managed.&lt;/p&gt; &lt;p&gt;&lt;em&gt;Setting objectives is not the same as creating a strategy to reach those goals&lt;/em&gt;. You still need to do the hard strategy work of making a diagnosis of what obstacle is holding you back, creating a guiding policy for overcoming the obstacle, and breaking that down into coherent actions for the company to take (which shouldn’t be based on what departments or people or expertise you already have, but instead you should look at what competencies you need to carry out your strategy and then apply existing teams and people to carrying them out, if they exist, and hire where you’re missing expertise, and get rid of competencies that are no longer needed in the strategy). OKRs can be applied at the top layer as company goals to reach, then applied again to the coherent actions (i.e. what’s the objective of each action, and how will you know if you reached it?), and further broken down for teams and people as needed. You still need an actual strategy before you can set OKRs, but most companies conflate OKRs with strategy.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Blue Sky Objectives&lt;/strong&gt;: A blue-sky objective is a simple restatement of the desired state of affairs or of the challenge. It skips over the annoying fact that no one has a clue as to how to get there.&lt;/p&gt; &lt;pre&gt;&lt;code&gt;For example, &quot;underperformance&quot; isn’t a challenge, it’s a result. It’s a restatement of a goal. The true challenge are the reasons for the underperformance. Unless leadership offers a theory of why things haven’t worked in the past (a.k.a. a diagnosis), or why the challenge is difficult, it is hard to generate good strategy.
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;The Unwillingness or Inability to Choose&lt;/strong&gt;: Any strategy that has universal buy-in signals the absence of choice. Because strategy focuses resources, energy, and attention on some objectives rather than others, a change in strategy will make some people worse off and there will be powerful forces opposed to almost any change in strategy (e.g. a department head who faces losing people, funding, headcount, support, etc., as a result of a change in strategy will most likely be opposed to the change). Therefore, strategy that has universal buy-in often indicates a leader who was unwilling to make a difficult choice as to the guiding policy and actions to take to overcome the obstacles.&lt;/p&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;This is true, but there are ways of mitigating this that he doesn’t discuss, which I talk about in the &quot;Closing Thoughts&quot; section below.&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Template-style &quot;strategic planning&quot;&lt;/strong&gt;: Many strategies are developed by following a template of what a &quot;strategy&quot; should look like. Since strategy is somewhat nebulous, leaders are quick to adopt a template they can fill in since they have no other frame of reference for what goes into a strategy.&lt;/p&gt; 
  &lt;ul&gt; 
   &lt;li&gt;&lt;strong&gt;The Vision&lt;/strong&gt;: Your unique vision of what the org will be like in the future. Often starts with &quot;the best&quot; or &quot;the leading.&quot;&lt;/li&gt; 
   &lt;li&gt;&lt;strong&gt;The Mission&lt;/strong&gt;: High-sounding politically correct statement of the purpose of the org.&lt;/li&gt; 
   &lt;li&gt;&lt;strong&gt;The Values&lt;/strong&gt;: The company’s values. Make sure they are non-controversial.&lt;/li&gt; 
   &lt;li&gt;&lt;strong&gt;The Strategies&lt;/strong&gt;: Fill in some aspirations/goals but call them strategies.&lt;/li&gt; 
  &lt;/ul&gt; &lt;p&gt;This template-style strategy skips over the hard work of identifying the key challenge to overcome, and setting out a guiding policy and actions to overcome the obstacle. It mistakes pious statements of the obvious as if they were decisive insights. The vision, mission, and goals are usually statements that no one would argue against, but that no one is inspired by, either.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;New Thought&lt;/strong&gt;: This is the belief that you only need to envision success to achieve it, and that thinking about failure will lead to failure. The problem with this belief is that strategy requires you to analyze the situation to understand the problem to be solved, as well as anticipating the actions/reactions of customers and competitors, which requires considering both positive and negative outcomes. Ignoring negative outcomes does not set you up for success or prepare you for the unthinkable to happen. It crowds out critical thinking.&lt;/p&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Chapter 5 - The Kernel of good strategy&lt;/h2&gt; 
&lt;p&gt;Strategy is &lt;em&gt;designing a way to deal with a challenge&lt;/em&gt;. A good strategy, therefore, &lt;em&gt;must identify the challenge to be overcome&lt;/em&gt;, and &lt;em&gt;design a way to overcome it&lt;/em&gt;. Good strategy has an essential logical structure called Kernel, that has:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Diagnosis&lt;/strong&gt;: Simplifies reality by identifying the critical aspects. Leaders must absorb a large part of a situation/problem’s complexity and ambiguity and pass on to the organization a simpler problem, one that is solvable. Answers: “What is going on here?”. At minimum:&lt;/p&gt; 
  &lt;ul&gt; 
   &lt;li&gt;Names/classifies situation.&lt;/li&gt; 
   &lt;li&gt;Links facts into patterns.&lt;/li&gt; 
   &lt;li&gt;Highlights important issues.&lt;/li&gt; 
  &lt;/ul&gt; &lt;p&gt;It defines a domain of action: If no action can be derived from it, the diagnosis is useless.&lt;/p&gt; &lt;p&gt;If a challenge is ill-structured, the diagnosis has to be an educated guess.&lt;/p&gt; &lt;p&gt;In business, most deep strategic changes are brought about by a change in diagnosis.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Guiding policy&lt;/strong&gt;: Overall approach to cope or overcome the obstacles identified in the diagnosis. Drawn upon or creates sources of advantage. It channels action in certain direction without defining exactly what shall be done. Not goals or vision. In nonprofit and public policy, good strategy creates advantage by magnifying the effects of resources and actions.&lt;/p&gt; &lt;p&gt;A good guiding policy itself can be a source of advantage by: Anticipating actions of others. Reducing complexity and ambiguity. Concentrating effort on critical aspects. Create coherent actions.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Coherent action&lt;/strong&gt;: Non conflicting and coordinated. Resource commitments. Coordination by itself can be a source of advantage.&lt;/p&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;Strategy is visible as &lt;strong&gt;&lt;em&gt;coordinated action imposed on a system&lt;/em&gt;&lt;/strong&gt;. Imposed = &quot;exercise in centralized power used to overcome the natural workings of a system&quot;.&lt;/p&gt; 
&lt;h1&gt;Part 2: Sources of power&lt;/h1&gt; 
&lt;h2&gt;Chapter 6 - Using leverage&lt;/h2&gt; 
&lt;p&gt;Strategic leverage arises from a mixture of:&lt;br&gt; * anticipation: buyer demand, competition reactions. Anticipation does not require psychic powers. In many circumstances, anticipation simply means considering the habits, preferences and policies of others, as well as various inertias and constraints in change.&lt;br&gt; * pivot points: small adjustment magnifies effect of effort&lt;br&gt; * concentration: focus on a few objectives, due to limited resources, limited leadership cognition, perceived effectiveness (a 100% improvement in one department seems more effective than a 10% improvement in 100 departments)&lt;/p&gt; 
&lt;p&gt;To achieve leverage, you must have insight into a pivot point that with magnify the effects of focused energy and resources. A pivot point magnifies the effect of effort. It is a natural or created imbalance in a situation, a place where a relatively small adjustment can unleash much larger pent-up forces.&lt;/p&gt; 
&lt;h2&gt;Chapter 7 - Proximate objectives&lt;/h2&gt; 
&lt;p&gt;Proximate objective: one that is close enough at hand to be feasible, guided by forecast of the future; the more uncertain the future, the more proximate objective must be.&lt;/p&gt; 
&lt;p&gt;How proximate an objective is depends on the skills and accumulated resources of the organization.&lt;/p&gt; 
&lt;h2&gt;Chapter 8 - Chain-link systems.&lt;/h2&gt; 
&lt;p&gt;Strengthen the weakest link.&lt;/p&gt; 
&lt;p&gt;Quality matters when quantity is an inadequate substitute.&lt;/p&gt; 
&lt;p&gt;Find limiting factors.&lt;/p&gt; 
&lt;p&gt;Quality matching: when each link is managed separately, the system can get stuck in a low-effectiveness state:&lt;br&gt; * Quality of the chain is equal to the lowest link.&lt;br&gt; * Improving on any other link is a waste.&lt;/p&gt; 
&lt;p&gt;Problems with chain-linked:&lt;br&gt; * Identify bottlenecks.&lt;br&gt; * Incremental change may not pay off and even make things worse: Focus success measurement on change itself.&lt;/p&gt; 
&lt;p&gt;Excellence in a chain-linked system is difficult to replicate.&lt;/p&gt; 
&lt;h2&gt;Chapter 9 - Using Design&lt;/h2&gt; 
&lt;p&gt;Strategy is not about choice/decision but about design, more constructed than chosen.&lt;/p&gt; 
&lt;p&gt;In design, issue of mutual adjustment: Sharp gain or cost on getting the combinations right or wrong.&lt;/p&gt; 
&lt;p&gt;Most of the work in system design is figuring out the interactions.&lt;/p&gt; 
&lt;p&gt;A design-type strategy is an adroit configuration of resources and actions that yields an advantage in a challenging situation.&lt;/p&gt; 
&lt;p&gt;Given a set bundle of resources, the greater the competitive challenge, the greater the need for the clever, tight integration of resources and actions.&lt;/p&gt; 
&lt;p&gt;Given a set level of challenge, higher-quality resources lessen the need for the tight integration of resources and actions.&lt;/p&gt; 
&lt;p&gt;Resources and tight coordination are partial substitutes for each other.&lt;/p&gt; 
&lt;p&gt;Tight integration cost:&lt;br&gt; * Harder to create.&lt;br&gt; * Narrower focus.&lt;br&gt; * More fragile.&lt;br&gt; * Less flexible to change.&lt;/p&gt; 
&lt;p&gt;Strategic resource is one that competitors cannot duplicate without suffering a net economic loss. High quality strategic resource yielding a powerful competitive advantage makes for great strategy simplicity (think useful patents). But it can impede innovation. Current profits are rarely associated with recent action, but with actions from the past.&lt;/p&gt; 
&lt;p&gt;Success leads to laxity and bloat, and these lead to decline.&lt;/p&gt; 
&lt;h2&gt;Chapter 10 - Focus&lt;/h2&gt; 
&lt;p&gt;Coordination of policies that produces extra power through their interacting and overlapping effects&lt;br&gt; Demands application of that power to the right target&lt;br&gt; At the core, strategy is about focus, and most complex organisations don’t focus their resources. Instead, they pursue multiple goals at once, not concentrating enough resources to achieve a breakthrough in any of them.&lt;/p&gt; 
&lt;h2&gt;Chapter 11 - Growth&lt;/h2&gt; 
&lt;p&gt;Healthy growth is not engineered (ie through acquisition). It is the outcome of growing demand for special capabilities or of expanded or extended capabilities. It is the outcome of having superior products or skills.&lt;/p&gt; 
&lt;h2&gt;Chapter 12 - Using advantage&lt;/h2&gt; 
&lt;p&gt;An advantage is the result of differences – an asymmetry between rivals. Knowing your relative strengths and weaknesses, as well as the relative strengths and weaknesses of your competitors, can help you find an advantage. Strengths and weaknesses are &quot;relative&quot; because a strength you have in one context, or against one competitor, may be a weakness in another context, or against a different competitor. Press where you have advantage and side-step situations in which you do not. Exploit rivals’ weaknesses; avoid leading with your own.&lt;/p&gt; 
&lt;p&gt;The most basic advantage is producing at a lower cost than your competitors, or delivering more perceived value than your competitors, or a mix of the two. The difficult part is sustaining an advantage. To do that, you need an &quot;isolating mechanism&quot; that prevents competitors from duplicating it. Isolating mechanisms include patents, reputations, commercial and social relationships, network effects, dramatic economies of scale, and tacit knowledge and skill gained through experience.&lt;/p&gt; 
&lt;p&gt;Once you have an advantage, you should strengthen it by:&lt;br&gt; * &lt;em&gt;deepening it&lt;/em&gt;&lt;br&gt; * &lt;em&gt;broadening it&lt;/em&gt;&lt;br&gt; * &lt;em&gt;creating higher demand&lt;/em&gt; for your products and services&lt;br&gt; * &lt;em&gt;strengthening your isolating mechanisms&lt;/em&gt;&lt;/p&gt; 
&lt;h2&gt;Chapter 13 - Using dynamics&lt;/h2&gt; 
&lt;p&gt;Dynamics are waves of change that roll through an industry. They are the net result of a myriad of shifts and advances in technology, cost, competition, politics, and buyer perceptions. Such waves of change are largely exogenous – that is, beyond the control of any one organization.&lt;/p&gt; 
&lt;p&gt;Most industries, most of the time, are fairly stable. When change occurs, understand the forces underlying the main effect to find out the second order effects. These second effects are the ones to focus on.&lt;/p&gt; 
&lt;p&gt;If you can see them coming, they are like an earthquake that creates new high ground and levels what had previously been high ground, leaving behind new sources of advantage for you to exploit. To discern a wave of change, you need to understand the gritty details well enough to question experts.&lt;/p&gt; 
&lt;p&gt;There are 5 guideposts to look out for:&lt;/p&gt; 
&lt;ol&gt; 
 &lt;li&gt;Rising fixed costs&lt;/li&gt; 
 &lt;li&gt;Deregulation&lt;/li&gt; 
 &lt;li&gt;Predictable Biases 
  &lt;ul&gt; 
   &lt;li&gt;Ignore the fact that all business trends peak and then decline.&lt;/li&gt; 
   &lt;li&gt;Market leaders will duke it out for supremacy.&lt;/li&gt; 
   &lt;li&gt;The future winners will be the current apparent winners.&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Incumbent Response&lt;/li&gt; 
 &lt;li&gt;Attractor States (i.e. where an industry &quot;should&quot; go).&lt;/li&gt; 
&lt;/ol&gt; 
&lt;p&gt;Attractor states are especially interesting because he defines it as where an industry &quot;should&quot; end up in the light of technological forces and the structure of demand. By &quot;should,&quot; he means to emphasize an evolution in the direction of efficiency – meeting the needs and demands of buyers as efficiently as possible. They’re different from corporate visions because the attractor state is based on overall efficiency rather than a single company’s desire to capture most of the pie. Attractor states are what pundits and industry analysts write about. There’s no guarantee, however, that the attractor state will ever come to pass. As it relates to strategy, you can anticipate most players to chase the attractor state. This leads many companies to waste resources chasing the wrong vision, and faltering as a result (e.g. Cisco rode the wave of &quot;dumb pipes&quot; and &quot;IP everywhere&quot; that AT&amp;amp;T and other telecom companies should have exploited). If you &quot;zig&quot; when other companies &quot;zag&quot;, you can build yourself an advantage.&lt;/p&gt; 
&lt;p&gt;As a strategist, you should seek to do your own analysis of where an industry is going, and create a strategy based on that (rather than what pundits &quot;predict&quot; will happen). Combining your own proprietary knowledge of your customers, technology, and capabilities with industry trends can give you deeper insights that analysts on the outside can’t see. Taking that a step further, you should also look for second-order effects as a result of industry dynamics. For example, the rise of the microprocessor was predicted by many, and largely came true. But what most people didn’t predict was the second-order effect that commoditized microprocessors getting embedded in more products led to increased demand for software, making the ability to write good software a competitive advantage.&lt;/p&gt; 
&lt;h2&gt;Chapter 14 - Inertia and entropy&lt;/h2&gt; 
&lt;p&gt;Entropy: weakly managed organizations tend to be less organized and focused.&lt;/p&gt; 
&lt;p&gt;Inertia: Even when change programs at full speed, it can take years to alter a large company.&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Routine: If top management are convinced that new routines are essential, change can be quick.&lt;/li&gt; 
 &lt;li&gt;Culture: 
  &lt;ul&gt; 
   &lt;li&gt;To break: 
    &lt;ul&gt; 
     &lt;li&gt;Simplification: it will highlight obsolete units, waste, bad behaviour.&lt;/li&gt; 
     &lt;li&gt;Fragment the operation units.&lt;/li&gt; 
     &lt;li&gt;Triage units: close, repair or empower.&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;To change the culture, replace the alpha members.&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;By proxy: Abandon old profit streams.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Chapter 15 - Putting it together&lt;/h2&gt; 
&lt;p&gt;(NVidia&apos;s strategy)&lt;/p&gt; 
&lt;p&gt;Good strategy&lt;/p&gt; 
&lt;p&gt;Intelligent anticipation&lt;/p&gt; 
&lt;p&gt;Guiding policy that reduces complexity&lt;/p&gt; 
&lt;p&gt;Power of design, focus, using advantage, riding a dynamic wave of change, and the important role played by inertia and disarray of rivals&lt;/p&gt; 
&lt;h1&gt;Part 3 - Thinking like a strategist&lt;/h1&gt; 
&lt;p&gt;Change in viewpoint is important when creating strategy.&lt;/p&gt; 
&lt;p&gt;Most useful shift in viewpoint: thinking about your own thinking.&lt;/p&gt; 
&lt;h2&gt;Chapter 16 - The science of strategy&lt;/h2&gt; 
&lt;p&gt;A new strategy is an hypothesis and its implementation an experiment.&lt;/p&gt; 
&lt;p&gt;Best knowledge to build good strategy is the one available only to your company.&lt;/p&gt; 
&lt;p&gt;If new insights or ideas are not needed, deduction is sufficient.&lt;/p&gt; 
&lt;p&gt;Strategy requires induction.&lt;/p&gt; 
&lt;p&gt;In creating strategy, it is often important to take on the viewpoints of others, seeing how the situation looks to a rival or to a customer. Advice to do this is both often given and taken. Yet the advice skips over what is possibly he most useful shift in viewpoint: thinking about your own thinking.&lt;/p&gt; 
&lt;h2&gt;Chapter 17 - Using your head&lt;/h2&gt; 
&lt;p&gt;Make a short list of the most important and actionable. Things to do, not things to worry about.&lt;/p&gt; 
&lt;p&gt;It is unnatural, even painful, to question your own ideas.&lt;/p&gt; 
&lt;p&gt;Good strategy emphasize focus over compromise.&lt;/p&gt; 
&lt;p&gt;Judgment can be practiced: Write down before every meeting what issues will arise and who will take which positions.&lt;/p&gt; 
&lt;h2&gt;Chapter 18 - Keeping your head&lt;/h2&gt; 
&lt;p&gt;Independent, not eccentric. Doubting without curmudgeon.&lt;/p&gt; 
&lt;p&gt;Errors in judgment:&lt;br&gt; * Engineering overreach: when failure modes and consequences are not understood.&lt;br&gt; * Smooth-sailing fallacy: when lack of recent failures make people overconfident.&lt;br&gt; * Working under risk-seeking malincentives: You profit if things go well, others pay if things go bad.&lt;br&gt; * Social herding.&lt;br&gt; * Inside view: believe “this case is different” despite data.&lt;/p&gt; 
&lt;h3&gt;Improve on strategy&lt;/h3&gt; 
&lt;ol&gt; 
 &lt;li&gt;Have tools to fight myopia and guide attention&lt;/li&gt; 
 &lt;li&gt;Question your own judgement&lt;/li&gt; 
 &lt;li&gt;Record judgements so you can learn from them&lt;/li&gt; 
&lt;/ol&gt; 
&lt;h3&gt;Tools to help thinking&lt;/h3&gt; 
&lt;p&gt;Think about first principles — not what is done but by WHY it’s done&lt;br&gt; Create-Destroy — try hard to destroy current alternative&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Pragmatic Thinking &amp; Learning</title>
      <link>https://tedneward.github.io/Research/thinking/prag-thinking-learning/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">thinking/prag-thinking-learning/index.html</guid>
      	<description>
	&lt;p&gt;&lt;em&gt;(by Andy Hunt)&lt;/em&gt;&lt;/p&gt; 
&lt;h3&gt;Chapter 1: Introduction&lt;/h3&gt; 
&lt;p&gt;Programming is all about problem solving. It requires creativity, ingenuity, and invention.&lt;/p&gt; 
&lt;p&gt;Software isn&apos;t designed in an IDE or other tool. It’s imagined and created in our heads.&lt;/p&gt; 
&lt;p&gt;Two of the most important modern skills are communication, and learning and thinking.&lt;/p&gt; 
&lt;h3&gt;Chapter 2: Journey from Novice to Expert&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;Event theories can be measured, verified, and proven. Construct theories are intangible abstractions, cannot be proven, and are evaluated by usefulness.&lt;/li&gt; 
 &lt;li&gt;It&apos;s often difficult for experts to explain their actions to a fine level of detail; many of their responses are so well practiced that they become preconscious actions.&lt;/li&gt; 
 &lt;li&gt;Novices need clear, context-free rules by which they can operate, just as the expert would be rendered ineffective if he were constrained to operate under those same rules.&lt;/li&gt; 
 &lt;li&gt;When becoming an expert, you don&apos;t just know more, but you experience fundamental differences in how you perceive the world, how you approach problem solving, and the mental models you form and use.&lt;/li&gt; 
 &lt;li&gt;At stage 1 of the Dreyfus model, novices can be somewhat effective by following context-free rules, but are vulnerable to confusion when mistakes happen or things go awry.&lt;/li&gt; 
 &lt;li&gt;At stage 2, advanced beginners try things on their own, take advice, and want information fast, but still have problems troubleshooting and don&apos;t see a big picture.&lt;/li&gt; 
 &lt;li&gt;At stage 3, competent practitioners can develop and use mental models, troubleshoot problems on their own, and find and apply advice from experts.&lt;/li&gt; 
 &lt;li&gt;At stage 4, proficient practitioners can correct previous poor task performance, learn from the experience of others, and know what likely happens next or what can break.&lt;/li&gt; 
 &lt;li&gt;At stage 5, experts are primary sources of knowledge, continually look for better methods, and work from intuition instead of reason.&lt;/li&gt; 
 &lt;li&gt;Novices following rules by experts thrive, while experts following rules by other experts suffer. Their tool is intuition.&lt;/li&gt; 
 &lt;li&gt;Three most important changes are moving from rules to intuition, equal weighting of parts to distinguishing important and unimportant ones, and detached observer to involved influencer.&lt;/li&gt; 
 &lt;li&gt;Most people are advanced beginners who overstate their abilities (the Dunning-Kruger effect) because metacognitive abilities tend to only appear at higher skill levels.&lt;/li&gt; 
 &lt;li&gt;A competent practitioner might be better suited to teach a novice than an expert, who are often unable to articulate why they reached a particular decision.&lt;/li&gt; 
 &lt;li&gt;Deliberate practice requires tackling a well-defined and appropriately difficult task, in an environment that provides feedback and provides opportunities for repetition and correction of errors.&lt;/li&gt; 
 &lt;li&gt;To help promote the skills of advanced beginners to competent practitioners, have good exemplars in the environment; they will be watched and imitated.&lt;/li&gt; 
 &lt;li&gt;Trumpeter Clark Terry told students the secret to learning music was to imitate, assimilate, and then innovate.&lt;/li&gt; 
 &lt;li&gt;Tools and models are useful in the right environments, but none are a panacea, and their misapplication has probably done more damage than good.&lt;/li&gt; 
 &lt;li&gt;Avoid formal rules if you need creativity, intuition, or inventiveness.&lt;/li&gt; 
 &lt;li&gt;Context matters, as the expert uses context-dependent intuition, but the lower stages of the Dreyfus model aren&apos;t skilled enough to use it.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Chapter 3: This Is Your Brain&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;The R-mode of your brain is critical for intuition, problem solving, and creativity. The L-mode gives you the power to work through the details and make it happen.&lt;/li&gt; 
 &lt;li&gt;Memory is actively maintained by an executing loop. Like dynamic RAM, your brain needs constant refreshing, or its memories fade.&lt;/li&gt; 
 &lt;li&gt;Like describing a dream, R-mode yields many results that can&apos;t be verbalized. Additionally, it&apos;s like peripheral vision, outside your direct control.&lt;/li&gt; 
 &lt;li&gt;R-mode is unpredictable, so you need to be ready to capture any insight or idea at any time.&lt;/li&gt; 
 &lt;li&gt;Once you start keeping track of ideas, you&apos;ll get more of them. Everyone has good ideas to capture.&lt;/li&gt; 
 &lt;li&gt;L-mode gives you verbal, analytic, symbolic, abstract, temporal, rational, digital, logical, and linear thinking abilities.&lt;/li&gt; 
 &lt;li&gt;R-mode is non-verbal, non-rational, synthetic to compose and form wholes, spatial, concrete, intuitive, analogic, and holistic to recognize patterns and structures. This is where intuition lies.&lt;/li&gt; 
 &lt;li&gt;Building things you can learn from, like prototypes and unit tests, is R-mode synthesis; inspecting and dissecting is L-mode analysis.&lt;/li&gt; 
 &lt;li&gt;When you are fearful or angry, filled with negative emotions, your body shuts down extra resources in preparation for for fight or flight.&lt;/li&gt; 
 &lt;li&gt;Creativity comes from the selection of the right components in the right presentation to create the work. And selection comes from pattern matching.&lt;/li&gt; 
 &lt;li&gt;R-mode helps you find global, holistic patterns. L-mode lets you analyze parts and look into the detail.&lt;/li&gt; 
 &lt;li&gt;Believing in the plasticity of your brain, or the amount you can learn and number of skills you can attain, increases those abilities.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Chapter 4: Get in Your Right Mind&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;Activate more neural pathways than usual to involve more of your brain. For example, fiddle with a tactile puzzle while pondering a tricky problem.&lt;/li&gt; 
 &lt;li&gt;Allow several senses to interact, like writing a problem down, drawing it, describing it verbally, engaging in open discussion, and act out roles.&lt;/li&gt; 
 &lt;li&gt;Listening to music, drawing, meditation, jogging, needlework, rock climbing, and so on can engage the R-mode that shuts off the L-mode.&lt;/li&gt; 
 &lt;li&gt;Once you experience the shift to R-mode, you&apos;ll better know what R-mode processing feels like, and it will become easier over time.&lt;/li&gt; 
 &lt;li&gt;You want to let the R-mode lead and then switch to the L-mode to &quot;productize&quot; it.&lt;/li&gt; 
 &lt;li&gt;Working together is an effective way to discover helpful and interesting abstractions. In pair programming, the driver is in L-mode, while the navigator is in R-mode.&lt;/li&gt; 
 &lt;li&gt;A strong metaphor comes from suddenly switching from one frame of reference to a different, unexpected one. That junction between the two frames is the bisociation.&lt;/li&gt; 
 &lt;li&gt;The farther away the ideas are, the harder it is to join them in a metaphor that works. But such imprinting from one frame to another is very powerful.&lt;/li&gt; 
 &lt;li&gt;Programmers are sloppy in their use of metaphors. For example, using &lt;code&gt;insert()&lt;/code&gt; instead of &lt;code&gt;add()&lt;/code&gt; on a container, tables that aren&apos;t like tables, threads that aren&apos;t like threads.&lt;/li&gt; 
 &lt;li&gt;Humor comes from drawing or extending relationships beyond the norm, which also helps build stronger metaphors.&lt;/li&gt; 
 &lt;li&gt;Your brain stores every input it receives, although does not necessarily index them. Your R-mode asynchronously scans these memories, albeit inefficiently.&lt;/li&gt; 
 &lt;li&gt;Image streaming harvests R-mode imagery: Pose a question, then close your eyes, and describe out loud every image that crosses your mind. Imagine it using all five senses.&lt;/li&gt; 
 &lt;li&gt;With the morning pages technique, write three uncensored pages long hand before you &quot;wake up.&quot; This gives you an unguarded, unconscious R-mode brain dump.&lt;/li&gt; 
 &lt;li&gt;Insight can come at odd times like taking a shower or mowing the lawn because the L-mode gets bored and tunes out, leaving the R-mode to present its findings.&lt;/li&gt; 
 &lt;li&gt;As Poincaré did, write down everything you know about a problem, and then go on a walk without focusing on it, allowing the R-mode to dominate.&lt;/li&gt; 
 &lt;li&gt;Making source code human-readable means making the larger patterns in the code easier to see.&lt;/li&gt; 
 &lt;li&gt;Use consistent typographic cues to aid visual perception. Conflicting styles are contentious because they represent conflicting patterns.&lt;/li&gt; 
 &lt;li&gt;Change your viewpoint on a problem by viewing it in reverse, exaggerating an idea, combining disparate ideas, and non-goal-directed playing with ideas.&lt;/li&gt; 
 &lt;li&gt;Even small changes in your routine, like where you park, where you part your hair, when you eat, and what days you shave help prevent neural ruts.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Chapter 5: Debug Your Mind&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;Cognitive biases are mental &quot;bugs&quot; that affect your decision making, memory, perception, rationality, and so on. There are a lot of them.&lt;/li&gt; 
 &lt;li&gt;Symbolic reduction, or reducing large, complex systems to simple, easily manipulated symbols, is essential to computer programming and knowledge-based work.&lt;/li&gt; 
 &lt;li&gt;Humans are bad at trying to extrapolate future events from previous ones. We assume a stable, linear progression, with easily defined cause and effect.&lt;/li&gt; 
 &lt;li&gt;Don&apos;t discount unobserved or rare phenomena as impossible. And homogeneity and randomness are different things.&lt;/li&gt; 
 &lt;li&gt;On an exploratory or inventive project, you learn as you go, and so you know most at the end. So defer closure in order to make better decisions later.&lt;/li&gt; 
 &lt;li&gt;Agile development embraces uncertainty; it is not a bad thing. Chip away at the details, and don&apos;t nail them down until ready.&lt;/li&gt; 
 &lt;li&gt;Write things down. As a Chinese proverb says, the palest ink is better than the best memory.&lt;/li&gt; 
 &lt;li&gt;Attitudes on risk, individualism vs teamwork, stability vs freedom, and family vs work are affected by your cohort and your parents.&lt;/li&gt; 
 &lt;li&gt;Generation X form the greatest entrepreneurial generation in U.S. history. They&apos;re fiercely individualistic, and resist being labeled at all costs.&lt;/li&gt; 
 &lt;li&gt;The four generational archetypes are the prophet, with vision, values; the nomad, with liberty, survival, honor; the hero, with community, affluence; and the artist, with pluralism, expertise, due process.&lt;/li&gt; 
 &lt;li&gt;With Howe/Strauss generational archetypes, the hero begets the artist, who begets the prophet, who begets nomad, who begets the hero.&lt;/li&gt; 
 &lt;li&gt;The best way to keep from falling victim to your generation’s particular set of biases is to embrace diversity.&lt;/li&gt; 
 &lt;li&gt;Within the MBTI framework, sensing (S) vs intuition (N) is probably the largest source of miscommunication and misunderstanding. 75 percent of folks are sening.&lt;/li&gt; 
 &lt;li&gt;Work out a compromise. Do not try to change the other person’s temperament to match your own.&lt;/li&gt; 
 &lt;li&gt;Our primeval characteristics include immediate fight or flight, wanting everything now, being dominant, defending territory, crying foul, and considering anyone different evil.&lt;/li&gt; 
 &lt;li&gt;Attitudes, beliefs, behaviors, and emotions are all contagious.&lt;/li&gt; 
 &lt;li&gt;It&apos;s easy to write a short and snippy e-mail because it doesn&apos;t give the neocortex time to intervene, unlike writing a longhand letter.&lt;/li&gt; 
 &lt;li&gt;Lead with intuition, but follow up with provable, linear feedback. Your intuition may be wrong.&lt;/li&gt; 
 &lt;li&gt;Expectations color reality. So ask hard questions about a problem, measure all you can, get the opinion of others, and define its opposite to draw a more critical eye.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Chapter 6: Learn Deliberately&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;Learning isn&apos;t done to you, it&apos;s something you do. &quot;Education&quot; comes from &quot;educare,&quot; which literally means &quot;led out.&quot; And knowledge alone, without experience, isn&apos;t effective.&lt;/li&gt; 
 &lt;li&gt;To develop competence and expertise, you need continuing goals, feedback to understand your progress, and a deliberate approach to the whole thing.&lt;/li&gt; 
 &lt;li&gt;An objective is something you do to get you closer to a goal. It should be specific, measurable, achievable, relevant, and time-boxed. Together, SMART objectives.&lt;/li&gt; 
 &lt;li&gt;By being deliberate about your learning, by allocating appropriate time, and by using that time wisely, you can be much more efficient in your learning.&lt;/li&gt; 
 &lt;li&gt;All knowledge investments have some value. Even if you never use a particular technology vocationally, it will impact the way you think and solve problems.&lt;/li&gt; 
 &lt;li&gt;Not all learning sessions will be equally productive, but by scheduling them regularly, you will win out in the long run.&lt;/li&gt; 
 &lt;li&gt;Visual learners need to see the material, auditory learners need to hear the material, and kinesthetic learners need to physically experience the material.&lt;/li&gt; 
 &lt;li&gt;Howard Gardner defined seven facets of intelligence: kinesthetic, linguistic, logical/mathematical, visual/spatial, musical, interpersonal, and intrapersonal.&lt;/li&gt; 
 &lt;li&gt;The team that studies together learns together, teaches each other, and learns more effectively.&lt;/li&gt; 
 &lt;li&gt;Written instructions are considered the least efficient because many parts of the brain and body you want to train or educate aren&apos;t the parts that process language.&lt;/li&gt; 
 &lt;li&gt;After surveying the work, forming questions, and then reading, &lt;em&gt;recite&lt;/em&gt; the information by playing with it, exercising your R-mode. Finally, review it.&lt;/li&gt; 
 &lt;li&gt;Reading the same material over and over doesn&apos;t help you remember it. Instead, test yourself by trying to recall the material over and over.&lt;/li&gt; 
 &lt;li&gt;Redrawing a mind map from memory helps strengthen the connections and may expose additional insights in the process.&lt;/li&gt; 
 &lt;li&gt;For exploratory mind maps, use words as titles, draw icons to represent key ideas, and make important lines thick. Do it quickly, giving the R-mode unfettered access.&lt;/li&gt; 
 &lt;li&gt;For a collaborative mind map, write ideas on stick notes, cluster related notes together, and draw circles around each group and connect them with lines.&lt;/li&gt; 
 &lt;li&gt;Documenting makes you turn your attention inward, as you would when working with a mind map, promoting insight later in the project.&lt;/li&gt; 
 &lt;li&gt;Teaching others clarifies your own understanding of something and reveals many of your underlying assumptions.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Chapter 7: Gain Experience&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;Non-goal-directed exploring, or playing with a problem, doesn&apos;t make it any easier, but it gets us closer to how we&apos;re wired to learn.&lt;/li&gt; 
 &lt;li&gt;Working with new material or solving a problem in a playful manner makes it more enjoyable and also easier to learn.&lt;/li&gt; 
 &lt;li&gt;When learning from similarities, clinging to them thinking may prevent us from fully embracing a new skill. And our notion of &quot;similar&quot; may be completely wrong.&lt;/li&gt; 
 &lt;li&gt;&quot;I don&apos;t know&quot; is a fine answer, but don&apos;t let it end there. And it&apos;s not important to get something right the first time; it&apos;s important to get it right the last time.&lt;/li&gt; 
 &lt;li&gt;Version control allows backtracking; unit testing measures progress; automation ensures repetition. Together, they give you the ability to experiment with little risk.&lt;/li&gt; 
 &lt;li&gt;Inner game stresses learning from your own experience. It&apos;s difficult to learn something by words; we learn something better by discovery, not instruction.&lt;/li&gt; 
 &lt;li&gt;When playing the inner game, just be aware. Don&apos;t try to get it right, but notice when it&apos;s wrong, and act to correct it.&lt;/li&gt; 
 &lt;li&gt;When debugging, be fully aware of how the system is behaving, and then decide what part is wrong before moving on to devise a solution.&lt;/li&gt; 
 &lt;li&gt;Not only does your creativity suffer with a deadline looming, but it suffers for two days after the deadline. So end a project iteration on a Friday.&lt;/li&gt; 
 &lt;li&gt;Once you create an environment where it&apos;s acceptable to fail, the pressure is off, and you can be attentive, comfortable, and observant. See unit testing and prototyping.&lt;/li&gt; 
 &lt;li&gt;Much of perception is based on prediction, which is based on context and past experience, so much that current, real-time input takes a backseat.&lt;/li&gt; 
 &lt;li&gt;You can imagine experiences and learn from as effectively as if you had lived them for real, because your brain has difficulty telling the difference.&lt;/li&gt; 
 &lt;li&gt;Intuition grows by having more patterns to draw on and apply, and a growing body of tacit knowledge of what to look for and when.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Chapter 8: Manage Focus&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;Information is raw data in a given context, while knowledge imparts meaning to that information, from the application of time, attention, or skill.&lt;/li&gt; 
 &lt;li&gt;Much of meditation, yoga, and similar practices offer some relief from the idle chatter of your L-mode, to live in the moment, and to not divide your mental energy unnecessarily.&lt;/li&gt; 
 &lt;li&gt;With Vipassana meditation, explicitly focus on your breathing. Words can come, but just let them go, and return attention to your breath.&lt;/li&gt; 
 &lt;li&gt;With the segmented breath controlled breathing approach, on the inhale, fill the lower belly first, then the chest, and then finally up to the collar bones.&lt;/li&gt; 
 &lt;li&gt;Handing over work to the unconscious only works if you have some data to fill up on.&lt;/li&gt; 
 &lt;li&gt;Tools you use for mental support outside your brain become part of your operating mind. They help form your exocortex.&lt;/li&gt; 
 &lt;li&gt;Whether a wiki or a shoebox, once you have a place or page to put some type of thought, you&apos;ll get more thoughts of that type.&lt;/li&gt; 
 &lt;li&gt;Transcribing notes to the wiki or cleaning them up on the wiki helps get your head around the material.&lt;/li&gt; 
 &lt;li&gt;Multitasking can cost you 20 to 50 percent of your productivity, while after an interruption it make 20 minutes to pick up where you left off.&lt;/li&gt; 
 &lt;li&gt;GTD suggests scanning the input queue only once, processing each pile of work in order, and not keeping lists in your head.&lt;/li&gt; 
 &lt;li&gt;Set up times of the day when you aren&apos;t to be interrupted, and other times for collaboration, daily stand-up meetings, and other assorted contingencies.&lt;/li&gt; 
 &lt;li&gt;To control the flood of email, remember that you&apos;ll receive less email if you send less email, and that your reply speed sets the tempo for a conversation.&lt;/li&gt; 
 &lt;li&gt;To try and keep context, raise the physical cost of entry and exit to remind you of the mental cost.&lt;/li&gt; 
 &lt;li&gt;In the few seconds before an interruption takes hold, leave some breadcrumbs or cues that you can pick up on when you get back to resuming the task.&lt;/li&gt; 
 &lt;li&gt;You can instantly recognize productivity gains of 20 to 30 percent with a second monitor. Get one of the same size and brand to minimize distractions.&lt;/li&gt; 
 &lt;li&gt;Organize virtual desktops by task, such as communications, writing, coding, surfing, and music.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Chapter 9: Beyond Expertise&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;To manage effective change, remember: Start with a plan, fear inaction and not error, give it a fair chance, believe that change is possible, and take small and achievable steps.&lt;/li&gt; 
 &lt;li&gt;The professional kiss of death for the expert is to act like one. Your own judgment and views, instead of supporting you, can imprison you.&lt;/li&gt; 
 &lt;li&gt;Leonardo Da Vinci said: &quot;People look without seeing, hear without listening, eat without awareness of taste, touch without feeling, and talk without thinking.&quot;&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>The Elephant in the Brain</title>
      <link>https://tedneward.github.io/Research/thinking/elephant-in-the-brain/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">thinking/elephant-in-the-brain/index.html</guid>
      	<description>
	&lt;p&gt;&lt;em&gt;(by Kevin Simler, Robin Hanson)&lt;/em&gt;&lt;/p&gt; 
&lt;h1&gt;Introduction&lt;/h1&gt; 
&lt;h4&gt;First example: health care&lt;/h4&gt; 
&lt;p&gt;Why do patients spend so much on medical care? To get healthier: That&apos;s their one and only goal, right? Maybe not. Consider data points:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;People in developed countries consume way too much medicine, well beyond what&apos;s useful for staying healthy. &lt;em&gt;(I&apos;d be curious to know which studies... citation?)&lt;/em&gt;&lt;/li&gt; 
 &lt;li&gt;Large randomized studies, for example, find that people given free healthcare consume way too much medicine, yet don&apos;t end up noticably healthier. &lt;em&gt;(Again, studies/citations?)&lt;/em&gt;&lt;/li&gt; 
 &lt;li&gt;Meanwhile, &lt;em&gt;non-medical&lt;/em&gt; interventions--such as efforts to alleviate stress or improve diet, exercise, sleep or air quality--have a much more apparent effect on health, and yet patients and policymakers are far less eager to pursue them.&lt;/li&gt; 
 &lt;li&gt;Patients are also easily satisfied with the &lt;em&gt;apperance&lt;/em&gt; of good medical care, and show shockingly little interest in digging beneath the surface (by getting second opinions or asking for outcome statistics from their doctors or hospitals).&lt;/li&gt; 
 &lt;li&gt;People spend exorbitantly on heroic end-of-life care even though cheap, palliative care is usually just as effective at prolonging life and usually better and preserving quality of life.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;Altogether, these puzzles cast considerable doubt on the simple idea that medicine is strictly about health.&lt;/p&gt; 
&lt;p&gt;People might have other motives for buying medicine (beyond getting healthy) and that these motives are largely unconscious. Medicine isn&apos;t just about health--it&apos;s also an exercise in &lt;em&gt;conspicuous caring&lt;/em&gt;.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;We&apos;re suggesting that key human behaviors are often driven by multiple motives; secondly, we&apos;re suggesting that some of these motives are unconscious; and these are elephant-sized motives large enough to leave footprints in national economic data.&lt;/strong&gt;&lt;/p&gt; 
&lt;h4&gt;Second example: startup&lt;/h4&gt; 
&lt;p&gt;Inspired by &lt;em&gt;Hierarchy in the Forest&lt;/em&gt; (Christopher Boehm): parallels between chimpanzee societies and startup/business societies.&lt;/p&gt; 
&lt;p&gt;People don&apos;t typically think or talk in terms of maximizing social status or showing conspicuous care. And yet we all instinctively act this way. In fact, we&apos;re able to act quite skillfully and strategically, pursuing our self-interest without explicitly acknowledging it, even to ourselves.&lt;/p&gt; 
&lt;h4&gt;The Core Idea&lt;/h4&gt; 
&lt;p&gt;&lt;strong&gt;We, human beings, are a species that&apos;s not only capable of acting on hidden motives--we&apos;re designed to do it.&lt;/strong&gt; Our brains are built to act in our self-interest while at the same time trying hard not to appear selfish in front of other people. And in order to throw them off the trail, our brains often keep &quot;us&quot;, our conscious minds, in the dark. The less we know of our own ugly motives, the easier it is to hide them from others.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Self-deception is therefore &lt;em&gt;strategic&lt;/em&gt;, a ploy our brains use to look good while behaving badly.&lt;/strong&gt; As long as we continue to tiptoe around it, we&apos;ll be unable to think clearly about human behavior.&lt;/p&gt; 
&lt;blockquote&gt; 
 &lt;h4&gt;Box 1: &quot;The Elephant&quot;&lt;/h4&gt; 
 &lt;p&gt;The elephant in the brain, in a word, is selfishness--the selfish parts of our psyches. But it&apos;s also broader than that. Selfishness is just the heart, if you will, and an elephant has many other parts, all interconnected. &quot;The elephant&quot;, therefore, refers not just to human selfishness, but to a whole cluster of related concepts: competitiveness fighting for power, status, and sex; our willingness to lie and cheat to get ahead; that we hide some of our motives and that we do so to mislead others.&lt;/p&gt; 
&lt;/blockquote&gt; 
&lt;h4&gt;The Basic Argument&lt;/h4&gt; 
&lt;p&gt;At least four strands of research all lead to the same conclusion: that we are &quot;strangers to ourselves&quot;:&lt;/p&gt; 
&lt;ol&gt; 
 &lt;li&gt; &lt;p&gt;&lt;em&gt;Microsociology.&lt;/em&gt; The depth and complexity of our social behaviors (laughing, blushing, tears, eye contact, body language)--our brains choreograph these interactions on our behalf, and with surprising skill.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;em&gt;Cognitive and social psychology.&lt;/em&gt; Our brains aren&apos;t just hapless and quirky--they&apos;re &lt;em&gt;devious&lt;/em&gt;. &quot;At every stage [of processing information]--from its biased arrival, to its biased encoding, to organizing it around false logic, to misremembering and then misrepresenting it to others--the mind continually acts to distort information flow in favor of the usual goal of appearing better than one really is.&quot; The &lt;em&gt;introspection illusion&lt;/em&gt;, the fact that we don&apos;t know our own minds nearly as well as we pretend to.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;em&gt;Primatology.&lt;/em&gt; Humans are primates, specifically apes. When we study primate groups, we notice a lot of Machiavellian behavior; when asked to describe our own behavior, we mostly portray our motives as cooperative and prosocial.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;em&gt;Economic puzzles.&lt;/em&gt; When we study specific social institutions--medicine, education, etc--we notice they frequently fall short of their stated goals. In many cases, this is due to simple execution failures. But in other cases, the institutions behave as though they were designed to achieve other, unacknowledged goals.&lt;/p&gt; &lt;/li&gt; 
&lt;/ol&gt; 
&lt;p&gt;We act on hidden motives together, in public, just as often as we do by ourselves, in private. And when enough of our hidden motives harmonize, we end up constructing stable, long-lived institutions that are designed, at least partially, to accommodate such motives.&lt;/p&gt; 
&lt;blockquote&gt; 
 &lt;h4&gt;Box 2: Our Thesis in Plain English&lt;/h4&gt; 
 &lt;ol&gt; 
  &lt;li&gt;People are judging us all the time. One of the important things they&apos;re judging is our &lt;em&gt;motives&lt;/em&gt;.&lt;/li&gt; 
  &lt;li&gt;Because others are judging us, we&apos;re eager to look good. So we emphasize our pretty motives and downplay our ugly ones.&lt;/li&gt; 
  &lt;li&gt;This applies not just to our words, but also to our thoughts. Why can&apos;t we be honest with ourselves? The answer is that our thoughts aren&apos;t as private as we imagine; in many ways, conscious thought is a rehearsal of what we&apos;re ready to say to others.&lt;/li&gt; 
  &lt;li&gt;In some areas of life (politics), we&apos;re quick to point out when others&apos; motives are more selfish than they claim, But in other areas (medicine), we prefer to believe that almost all of us have pretty motives.&lt;/li&gt; 
 &lt;/ol&gt; 
&lt;/blockquote&gt; 
&lt;h1&gt;Part I: Why We Hide Our Motives&lt;/h1&gt; 
&lt;h2&gt;Chapter 1: Animal Behavior&lt;/h2&gt; 
&lt;p&gt;Let&apos;s start at a simpler beginning: two animal behaviors that are hard to decipher. In each case, the animals appear to be doing something simple and straightforward, but as we dig beneath the surface, we&apos;ll find extra layers of complexity.&lt;/p&gt; 
&lt;h3&gt;Social Grooming&lt;/h3&gt; 
&lt;p&gt;To keep their fur clean, primates enlist the aid of others to groom their backs, faces, and heads: &lt;em&gt;social grooming&lt;/em&gt;.&lt;/p&gt; 
&lt;p&gt;At first blush, social grooming looks like an act of hygiene, a way to keep one&apos;s fur clean. But we can&apos;t take it at face value:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt; &lt;p&gt;Most primates spend far more time grooming each other than necessary to keep fur clean. (Gelada baboons spend 17% of their daylight hours; other primates spend 0.1%, and birds 0.01%.)&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Primates spend a lot more time grooming each other than they spend grooming themselves.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;We can correlate the average body size with the amount of time they spend grooming--if grooming were strictly a hygienic activity, we&apos;d expect larger species (with more fur) to spend more time grooming each other. But in fact there&apos;s no correlation.&lt;/p&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;Primatologist Robin Dunbar suggests social grooming isn&apos;t about hygiene--it&apos;s also about politics. By grooming each other, primates help forge alliances that help them in other situations. &quot;Grooming creates a platform off which trust can be built.&quot; This explains why higher-ranked individuals receive more grooming than lower-ranked individuals. It also explains why grooming time across species is correlated with the size of the social group, but not the amount of fur.&lt;/p&gt; 
&lt;h3&gt;Competitive Altruism&lt;/h3&gt; 
&lt;p&gt;The Arabian babbler (bird) lives in small groups of 3 to 20 members who collectively defend a small territory of trees, shrubs, and bushes that provide much-needed cover from predators. Babblers who live as part of a group do well; those who are kicked out of a group are in great danger. Male babblers arrange themselves into rigid dominance hierarchies. At first, these activities seem straightforwardly altruistic, but closer inspection suggests otherwise.&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Babblers compete to help each other and the group, often aggressively so. If the goal of these behaviors is to be helpful, why waste effort competing to perform them? 
  &lt;ul&gt; 
   &lt;li&gt;One theory is that higher-ranked babblers are stronger and better able to forego food and fight off predators.&lt;/li&gt; 
   &lt;li&gt;The problem: babblers compete primarily with the birds immediately above or below them in the hierarchy (#1 v #2, never #1 v #10).&lt;/li&gt; 
   &lt;li&gt;Babblers often intefere in the helpful behaviors of their rivals, which makes no sense if the goal is to benefit the group as a whole.&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;The answer: altruistic babblers develop a kind of &quot;credit&quot; among their groupmates: &lt;em&gt;prestige status&lt;/em&gt;. This earns them two perks: 
  &lt;ul&gt; 
   &lt;li&gt;Mating opportunities--the alpha will allow a high-prestige beta to mate with some of the females, &quot;bribing&quot; the beta to stick around.&lt;/li&gt; 
   &lt;li&gt;Reduced risk of ostracization.&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Human Behaviors&lt;/h3&gt; 
&lt;p&gt;To find out why we misconstrue animal motives, including our own, we have to look more carefully at how our brains were designed and what problems they&apos;re intended to solve.&lt;/p&gt; 
&lt;h2&gt;Chapter 2: Competition&lt;/h2&gt; 
&lt;h2&gt;Chapter 3: Norms&lt;/h2&gt; 
&lt;h2&gt;Chapter 4: Cheating&lt;/h2&gt; 
&lt;h2&gt;Chapter 5: Self-Deception&lt;/h2&gt; 
&lt;h2&gt;Chapter 6: Counterfeit Reasons&lt;/h2&gt; 
&lt;h1&gt;Part II: Hidden Motives in Everyday Life&lt;/h1&gt; 
&lt;h2&gt;Chapter 7: Body Language&lt;/h2&gt; 
&lt;h2&gt;Chapter 8: Laughter&lt;/h2&gt; 
&lt;h2&gt;Chapter 9: Conversation&lt;/h2&gt; 
&lt;h2&gt;Chapter 10: Consumption&lt;/h2&gt; 
&lt;h2&gt;Chapter 11: Art&lt;/h2&gt; 
&lt;h2&gt;Chapter 12: Charity&lt;/h2&gt; 
&lt;h2&gt;Chapter 13: Education&lt;/h2&gt; 
&lt;h2&gt;Chapter 14: Medicine&lt;/h2&gt; 
&lt;h2&gt;Chapter 15: Religion&lt;/h2&gt; 
&lt;h2&gt;Chapter 16: Politics&lt;/h2&gt; 
&lt;h2&gt;Chapter 17: Conclusion&lt;/h2&gt;
	</description>
    </item>
    <item>
      <title>Inverted Computer Culture</title>
      <link>https://tedneward.github.io/Research/thinking/inverted-computer-culture/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">thinking/inverted-computer-culture/index.html</guid>
      	<description>
	&lt;p&gt;&lt;em&gt;(from &lt;a href=&quot;http://viznut.fi/texts-en/inverted_computer_culture.html&quot;&gt;http://viznut.fi/texts-en/inverted_computer_culture.html&lt;/a&gt;)&lt;/em&gt;&lt;/p&gt; 
&lt;p&gt;Imagine a world where computers are inherently old. Whatever you do with them is automatically seen as practice of an ancient and unchanging tradition. Even though new discoveries do happen, they cannot dispel the aura of oldness.&lt;/p&gt; 
&lt;p&gt;Most computers are located in ancient buildings, &quot;computer temples&quot;, situated in tranquil natural environments. They stand unchanged over centuries, like mountains, no matter what happens in the world around them.&lt;/p&gt; 
&lt;p&gt;The idea of using computers in urban everyday life or for commercial purposes is something that doesn&apos;t even occur to people&apos;s minds – that would be just as absurd and wild as the idea of cleaning one&apos;s home with a 100-year-old tortoise.&lt;/p&gt; 
&lt;p&gt;Mundane mechanical technology has limited lifespans, a couple of decades at most. Solid-state computer components, on the other hand, have no mechanical decay, so they are practically eternal. An average microchip is hundreds of years old and has thus seen many different uses in many different eras. It is difficult to even look at a computer without admiring the long history it has gathered within itself. Computers thus feel more rooted to the world than any other human creation – despite the fact that they have no practical use in the society.&lt;/p&gt; 
&lt;p&gt;Computing is something stereotypically practiced by old women. Someone who is interested in computers is probably also interested in crocheting. Men and youngsters who visit computer temples are considered oddballs by their peers; young people in particular tend to see computers as something profoundly anti-cool. Movements that try to rid computing of its &quot;grandmotherly bias&quot; are usually seen as silly and embarrassing.&lt;/p&gt; 
&lt;p&gt;It is commonly thought to be futile to even try to make youngsters interested in computers – they simply don&apos;t yet have the required patience or concentration. There&apos;s no addictivity or instant gratification, nothing flashy or punk that fascinates the young mind. The appreciation and understanding of computers is something that develops slowly over years, often via gateway interests such as meditation, cultural history or pure mathematics. The kind of people who want to settle in a monastery and dedicate their lives to science or art may also develop an interest in computing.&lt;/p&gt; 
&lt;p&gt;The psychological effects of human-computer interaction are considered similar to those of meditation: concentration, awareness, mental clarity. Computers are also seen as amplifiers of wisdom and intelligence. However, it may take years for a user to attain these effects, so those who are after self-improvement are more likely to adopt more straightforward practices.&lt;/p&gt; 
&lt;p&gt;It is considered essential to be in a properly alert and rested state of mind when using a computer. Even to seasoned users, every session is special, and the purpose of the session must be clear in mind before sitting down. The outer world is often hurried and flashy, but computers provide a &quot;sacred space&quot; for relaxing, slowing down and concentrating on a specific idea without distractions. Breathing slows down, thought processes become more wholesome and contemplative. People who have spent a lot of time in a computer temple often find it difficult to readjust to the fast pace, distractivity and intellectual one-dimensionality of the non-computer world.&lt;/p&gt; 
&lt;p&gt;Computers are seldom privately owned – they are considered essentially communal rather than personal – but their usage patterns are often highly individualistic. Programming is the most essential element of all computer use, and it is not uncommon to find users who have created all of their software from scratch. Centuries of computer science research has valued simplicity, elegance, smallness and clarity over mundane values such as efficiency or scalability, so there are many beautiful ideas to base one&apos;s individual programs on.&lt;/p&gt; 
&lt;p&gt;A small percentage of computer use consists of long-distance human communication. The topics of non-technical discussion are often big and timeless and seldom concern daily news events. Heated arguments and polarization are considerably less common than in the non-computer &quot;world of illusions&quot;.&lt;/p&gt; 
&lt;p&gt;There are computer games, but they are never framed as &quot;entertainment&quot;. They are more often seen as learning experiences that help see the world from different viewpoints. Children would find most of the games utterly boring, if someone were crazy enough to try to get them interested.&lt;/p&gt; 
&lt;p&gt;Common people have all kinds of weird misconceptions about computing. They often see computers as far more spiritual or even divine than they actually are, so computer people often need to bring them down to earth from their fantasies. Even though computers often do help improve minds, they do not turn people into omniscient gods or saints or grant them eternal lives. And the computers themselves aren&apos;t omniscient either, and cannot manipulate the fabric of reality.&lt;/p&gt; 
&lt;hr&gt; 
&lt;p&gt;The purpose of this thought experiment was to invert the current mainstream cultural aspects of computing. It is not intended to be a utopian fantasy, even though some of it does align with what I have written about permacomputing.&lt;/p&gt; 
&lt;p&gt;In the real world, people associate computers with many different things: corporate dehumanization, overwhelming consumer capitalism, alienation from the material world, shortened attention spans, ridiculously short obsolescence cycles, etc. etc. It is often difficult to tell these cultural biases apart from the &quot;essence&quot; of computing, and it is even more difficult to envision alternatives due to the lack of diversity. Thought experiments like this may be helpful for widening the perspective.&lt;/p&gt; 
&lt;p&gt;So, what is the &quot;essence&quot; of computing then? I&apos;d say universality. The universality of computing makes it possible to bend it to reflect and amplify just about any kind of ideology or cultural construct. In the recent decades, some ideas have just been so overwhelming that they feel very essential even though they are not. In an alternate timeline, other ideas might be dominant.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Farnam Street Blog</title>
      <link>https://tedneward.github.io/Research/thinking/farnam-street-blog/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">thinking/farnam-street-blog/index.html</guid>
      	<description>
	&lt;p&gt;Eleven-plus years of thinking about thinking. I&apos;m in Heaven. Notes and quotes from each blog entry, most-recent first.&lt;/p&gt; 
&lt;hr&gt; 
&lt;h2&gt;&lt;a href=&quot;https://fs.blog/2020/11/how-julia-child-used-first-principles-thinking/&quot;&gt;How Julia Child Used First Principles Thinking&lt;/a&gt;&lt;/h2&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;There’s a big difference between knowing how to follow a recipe and knowing how to cook. If you can master the first principles within a domain, you can see much further than those who are just following recipes. That’s what Julia Child, &quot;The French Chef&quot;, did throughout her career.&lt;/p&gt; 
&lt;/blockquote&gt; 
&lt;p&gt;Adhering to recipes will only get you so far, and it certainly won’t result in you coming up with anything new or creative. ... People who know how to cook understand the basic principles that make food taste, look, and smell good. ... There’s a reason many cooking competition shows feature a segment where contestants need to design their own recipe from a limited assortment of ingredients. Effective improvisation shows the judges that someone can actually cook, not just follow recipes.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;If you want to learn how to think for yourself, you can’t just follow what someone else came up with.&lt;/strong&gt; You need to understand &lt;a href=&quot;https://fs.blog/2018/04/first-principles/&quot;&gt;first principles&lt;/a&gt; if you want to be able to solve complex problems or think in a unique, creative fashion. First principles are the building blocks of knowledge, the foundational understanding acquired from breaking something down into its most essential concepts. ... &lt;strong&gt;Once you understood how it actually worked, you could learn from mistakes instead of repeating them again and again. Looking for first principles is just a way of thinking. It’s a commitment to understanding the foundation that something is built on and giving yourself the freedom to adapt, develop, and create. Once you know the first principles, you can keep learning more advanced concepts as well as innovating for yourself.&lt;/strong&gt;&lt;/p&gt; 
&lt;hr&gt; 
&lt;h2&gt;&lt;a href=&quot;https://fs.blog/2020/11/learning-through-play/&quot;&gt;Learning Through Play&lt;/a&gt;&lt;/h2&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;Play is an essential way of learning about the world. Doing things we enjoy without a goal in mind leads us to find new information, better understand our own capabilities, and find unexpected beauty around us. Arithmetic is one example of an area we can explore through play.&lt;/p&gt; 
&lt;/blockquote&gt; 
&lt;p&gt;&lt;strong&gt;When the pressure mounts to be productive every minute of the day, we have much to gain from doing all we can to carve out time to play.&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Playing with symbols:&lt;/strong&gt; (Arithmetic, and using different representations for the numbers, etc.) &lt;strong&gt;When we start to play with the representations, we connect to the underlying reasoning behind what we are doing.&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Stepping away from requirements:&lt;/strong&gt; (Groupings of symbols, and groupings of groupings) &quot;“You might think there is no question about it; we chose four as our grouping size, so that’s that. Of course we will group our groups into fours—as opposed to what? Grouping things into fours and then grouping our groups into sixes? That would be insane! But it happens all the time. Inches are grouped into twelves to make feet, and then three feet make a yard. And the old British monetary system had twelve pence to the shilling and twenty shillings to the pound.”&quot; By reminding us of the options available in such a simple, everyday activity as counting, Lockhart opens a mental door. &lt;a href=&quot;https://fs.blog/2019/03/stormtrooper-problem/&quot;&gt;What other ways might we go about our tasks and solve our problems?&lt;/a&gt; It’s a reminder that most of our so-called requirements are ones that we impose on ourselves.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Have fun with the unfamiliar:&lt;/strong&gt; Getting stuck on anything can be incredibly useful. If forces you to stop and consider what it is you are really trying to achieve. Getting stuck can help you identify the first principles in your situation. In getting unstuck, we learn lessons that resonate and help us to grow. ... &lt;strong&gt;Play is often the exploration of the unfamiliar.&lt;/strong&gt;&lt;/p&gt; 
&lt;hr&gt; 
&lt;h2&gt;&lt;a href=&quot;https://fs.blog/2020/10/descriptions-arent-prescriptions/&quot;&gt;Descriptions Aren&apos;t Prescriptions&lt;/a&gt;&lt;/h2&gt; 
&lt;p&gt;(The Malagasy language: official rules described in 19th-century, taught faithfully, even as its practitioners spoke along different sets of rules. &quot; We find it dull to speak according to the official rules of our language. We seek out novelty in our everyday lives and do whatever it takes to avoid boredom. Even if each person only plays a little bit once in a while, the results compound. Graeber explains that &apos;this playing around will have cumulative effects.&apos;&quot; Languages still need conventions so people can understand each other. The higher the similarity between the versions of a language different people speak, the more they can communicate. At the same time, they cannot remain rigid. Trying to follow an unyielding set of strict rules will inevitably curtail the usefulness of a language and prevent it from developing in interesting and necessary ways. &lt;strong&gt;Languages need a balance: enough guidance to help everyone understand each other and provide an entry point for learners, and enough flexibility to keep updating the rules as actual usage changes.&lt;/strong&gt;)&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://fs.blog/2015/11/map-and-territory/&quot;&gt;“The map is not the territory”&lt;/a&gt; means that any representation of reality has to be a simplification that may contain errors, become outdated, or reflect biases. Maps remove details that aren’t necessary for their intended use. Representations of complex systems may show expected behavior or ideal behavior. ... &lt;strong&gt;Sometimes maps are descriptive, and sometimes they’re prescriptive; often they’re a bit of both.&lt;/strong&gt; We run into problems when we confuse one type for another and try to navigate an idealized territory or make the real territory fit an idealized image.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;When you encounter a representation of something, it’s useful to consider which parts are descriptive and which parts are prescriptive. Remember that both prescriptions and descriptions can and should change over time.&lt;/strong&gt;&lt;/p&gt; 
&lt;hr&gt; 
&lt;h2&gt;&lt;a href=&quot;https://fs.blog/2020/10/sharks-survivorship-bias/&quot;&gt;What Sharks Can Teach Us About Survivorship Bias&lt;/a&gt;&lt;/h2&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;Survivorship bias refers to the idea that we get a false representation of reality when we base our understanding only on the experiences of those who live to tell their story. Taking a look at how we misrepresent shark attacks highlights how survivorship bias distorts reality in other situations.&lt;/p&gt; 
&lt;/blockquote&gt; 
&lt;p&gt;We must be careful to not let a volume of survivors in one area blind us to the stories of a small number of survivors elsewhere. &lt;strong&gt;Most importantly, we need to ask ourselves what stories are not being told because no one is around to tell them.&lt;/strong&gt; The experiences of the dead are necessary if we want an accurate understanding of the world.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Survivorship bias crops up all over our lives and impedes us from accurately assessing danger.&lt;/strong&gt; ... &lt;strong&gt;Understanding survivorship bias prompts us to look for the stories of those who weren’t successful.&lt;/strong&gt; A lack of visible survivors with memorable stories might mean we view other fields as far safer and easier than they are. ... &lt;strong&gt;Survivorship bias prompts us to associate more risk with industries that exhibit more public failures.&lt;/strong&gt; ... &lt;strong&gt;If we don’t factor survivorship bias into our thinking we end up in a classic map is not the territory problem.&lt;/strong&gt; ... &lt;strong&gt;Not recognizing survivorship bias can lead to faulty decision making.&lt;/strong&gt;&lt;/p&gt; 
&lt;hr&gt; 
&lt;h2&gt;&lt;a href=&quot;https://fs.blog/2020/10/why-life-cant-be-simpler/&quot;&gt;Why Life Can&apos;t Be Simpler&lt;/a&gt;&lt;/h2&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;We’d all like life to be simpler. But we also don’t want to sacrifice our options and capabilities. &lt;a href=&quot;https://lawsofux.com/teslers-law&quot;&gt;Tesler’s law of the conservation of complexity&lt;/a&gt;, a rule from design, explains why we can’t have both. Here’s how the law can help us create better products and services by rethinking simplicity.&lt;/p&gt; 
&lt;/blockquote&gt; 
&lt;p&gt;In &lt;a href=&quot;https://www.amazon.com/Living-Complexity-Press-Donald-Norman/dp/0262528940/&quot;&gt;Living with Complexity&lt;/a&gt;, Donald A. Norman explains that complexity is all in the mind. Our perception of a product or service as simple or complex has its basis in the conceptual model we have of it. Norman writes that &quot;A conceptual model is the underlying belief structure held by a person about how something works . . . Conceptual models are extremely important tools for organizing and understanding otherwise complex things.&quot; ... &lt;strong&gt;When we want something to be simpler, what we truly need is a better conceptual model of it.&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;Removing functionality doesn’t make something simpler, because it removes options. Simple tools have a limited ability to simplify processes. Trying to do something complex with a simple tool is more complex than doing the same thing with a more complex tool.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;The total complexity of a system is a constant. If you make a user’s interaction with a system simpler, the complexity behind the scenes increases.&lt;/strong&gt; ... &lt;strong&gt;Complexity is like energy. It cannot be created or destroyed, only moved somewhere else.&lt;/strong&gt; &quot;What is simple on the surface can be incredibly complex inside: what is simple inside can result in an incredibly complex surface. So from whose point of view do we measure complexity?&quot;&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;From a user’s standpoint, the simplest products and services are those that are fully automated and do not require any intervention (unless something goes wrong.)&lt;/strong&gt; ... &lt;strong&gt;On the other end of the spectrum, we have products and services that require users to control every last step.&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;Lessons from the conservation of complexity:&lt;br&gt; * &lt;strong&gt;How simple something looks is not a reflection of how simple it is to use.&lt;/strong&gt; Perceived simplicity is not the same as operational (actual) simplicity.&lt;/p&gt; 
&lt;p&gt;&amp;gt; A very basic example of complexity trade-offs can be found in the history of arithmetic. For centuries, many counting systems all over the world employed tools using stones or beads like a tabula (the Romans) or soroban (the Japanese) to facilitate adding and subtracting numbers. They were easy to use, but not easily portable. Then the Hindu-Arabic system came along (the one we use today) and by virtue of employing columns, and thus not requiring any moving parts, offered a much more portable counting system. However, the portability came with a cost.&lt;/p&gt; 
&lt;p&gt;&amp;gt; Paul Lockhart explains in &lt;em&gt;Arithmetic&lt;/em&gt;, &quot;With the Hindu-Arabic system the writing and calculating are inextricably linked. Instead of moving stones or sliding beads, our manipulations become transmutations of the symbols themselves. That means we need to know things. We need to know that one more than 2 is 3, for instance. In other words, the price we pay [for portability] is massive amounts of memorization.&quot; Thus, there is a trade-off. The simpler arithmetic system requires more complexity in terms of the memorization required of the users. We all went through the difficult process of learning mathematical symbols early in life. Although they might seem simple to us now, that’s just because we’re so accustomed to them.&lt;/p&gt; 
&lt;p&gt;Norman writes: &quot;Perceived simplicity is not at all the same as simplicity of usage: operational simplicity. Perceived simplicity decreases with the number of visible controls and displays. Increase the number of visible alternatives and the perceived simplicity drops. The problem is that operational simplicity can be drastically improved by adding more controls and displays. The very things that make something easier to learn and to use can also make it be perceived as more difficult.&quot; Even if it receives a negative reaction before usage, operational simplicity is the more important goal.&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Things don’t always need to be incredibly simple for users.&lt;/strong&gt; People have an intuitive sense that complexity has to go somewhere. When using a product or service is too simple, users can feel suspicious or like they’ve been robbed of control.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Products and services are only as good as what happens when they break.&lt;/strong&gt;&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;There is an importance of thinking about how the level of control you give your customers or users influences your workload.&lt;/strong&gt;&lt;/p&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;hr&gt; 
&lt;h2&gt;&lt;a href=&quot;https://fs.blog/2020/09/being-smart-is-not-enough/&quot;&gt;Being Smart is not Enough&lt;/a&gt;&lt;/h2&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;When hiring a team, we tend to favor the geniuses who hatch innovative ideas, but overlook the butterflies, the crucial ones who share and implement them. Here’s why it’s important to be both smart AND social.&lt;/p&gt; 
&lt;/blockquote&gt; 
&lt;p&gt;In business, it’s never enough to have a great idea. For any innovation to be successful, it has to be shared, promoted, and bought into by everyone in the organization. Yet often we focus on the importance of those great ideas and seem to forget about the work that is required to spread them around. ... Joseph Henrich explores the role of culture in human evolution. One point he makes is that it’s not enough for a species to be smart. What counts far more is having the cultural infrastructure to share, teach, and learn:&lt;/p&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;Consider two very large prehuman populations, the Geniuses and the Butterflies. Suppose the Geniuses will devise an invention once in 10 lifetimes. The Butterflies are much dumber, only devising the same invention once in 1000 lifetimes. So, this means that the Geniuses are 100 times smarter than the Butterflies. However, the Geniuses are not very social and have only 1 friend they can learn from. The Butterflies have 10 friends, making them 10 times more social.&lt;/p&gt; 
 &lt;p&gt;Now, everyone in both populations tries to obtain an invention, both by figuring it out for themselves and by learning from friends. Suppose learning from friends is difficult: if a friend has it, a learner only learns it half the time. After everyone has done their own individual learning and tried to learn from their friends, do you think the innovation will be more common among the Geniuses or the Butterflies?&lt;/p&gt; 
&lt;/blockquote&gt; 
&lt;p&gt;? Well, among the Geniuses a bit fewer than 1 out of 5 individuals (18%) will end up with the invention. Half of those Geniuses will have figured it out all by themselves. Meanwhile, 99.9% of Butterflies will have the innovation, but only 0.1% will have figured it out by themselves.&lt;/p&gt; 
&lt;hr&gt;
	</description>
    </item>
    <item>
      <title>Mental models</title>
      <link>https://tedneward.github.io/Research/thinking/mental-models/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">thinking/mental-models/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://fs.blog/mental-models/&quot;&gt;Farnam Street Blog&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;A mental model is &lt;em&gt;a simplified explanation of how something works&lt;/em&gt;. Any idea, belief, or concept can be boiled down to its essence. Like a map, mental models highlight key information while ignoring irrelevant details. They’re tools for compressing complexity into manageable chunks. Mental models help us understand the world. For example, velocity shows that both speed and direction matter. Reciprocity reveals how being positive and taking initiative gets the world to do most of the work for you. Margin of Safety reminds us that things don’t always go as planned. Relativity exposes our blind spots and shows how a different perspective can reveal new information. These are just a few examples.&lt;/p&gt; 
&lt;h2&gt;General Thinking&lt;/h2&gt; 
&lt;h3&gt;&lt;a href=&quot;https://fs.blog/map-and-territory/&quot;&gt;The Map is Not the Territory&lt;/a&gt;&lt;/h3&gt; 
&lt;p&gt;The map is not the territory reminds us that our mental models of the world are not the same as the world itself. It cautions against confusing our abstractions and representations with the complex, ever-­shifting reality they aim to describe. It is dangerous to mistake the map for the territory. Consider the person with an outstanding résumé who checks all the boxes on paper but can’t do the job. Updating our maps is a difficult process of reconciling what we want to be true with what is true. In many areas of life, we are offered maps by other people. We are reliant on the maps provided by experts, pundits, and teachers. In these cases, the best we can do is to choose our mapmakers wisely and to seek out those who are rigorous, transparent, and open to revision. Ultimately, the map/territory distinction invites us to engage with the world as it is, not just as we imagine it. And remember, when you don’t make the map, choose your cartographer wisely.&lt;/p&gt; 
&lt;h3&gt;&lt;a href=&quot;https://fs.blog/circle-of-competence/&quot;&gt;Circle of Competence&lt;/a&gt;&lt;/h3&gt; 
&lt;p&gt;The first rule of competition is that you are more likely to win if you play where you have an advantage. Playing to your advantage requires a firm understanding of what you know and don’t know. Your circle of competence is your personal sphere of expertise, where your knowledge and skills are concentrated. It’s the domain where you have a deep understanding, where your judgments are reliable, and your decisions are sound. The size of your circle isn’t as important as knowing the boundaries. The wise person knows the limits of their knowledge and can confidently say, “This falls within my circle,” or “This is outside my area of expertise.” While operating within your circle of competence is a recipe for confidence and effectiveness, venturing outside your circle of competence is a recipe for trouble. You’re like a sailor navigating unfamiliar waters without a map, at the mercy of currents and storms you don’t fully understand. This isn’t to say that you should never venture outside your circle. Learning new things, gaining new skills, and mastering new domains is one of the most beautiful things about life.&lt;/p&gt; 
&lt;p&gt;Celebrate your expertise, but also acknowledge your limitations.&lt;/p&gt; 
&lt;h3&gt;&lt;a href=&quot;https://fs.blog/first-principles/&quot;&gt;First Principles Thinking&lt;/a&gt;&lt;/h3&gt; 
&lt;p&gt;First principles thinking is the art of breaking down complex problems into their fundamental truths. It’s a way of thinking that goes beyond the surface and allows us to see things from a new perspective. Thinking in first principles allows us to identify the root causes, strip away the layers of complexity, and focus on the most effective solutions. Reasoning from first principles allows us to step outside the way things have always been done and instead see what is possible. First principles thinking is not easy. It requires a willingness to challenge the status quo. This is why it’s often the domain of rebels and disrupters who believe there must be a better way. It’s the thinking of those willing to start from scratch and build from the ground up.&lt;/p&gt; 
&lt;h3&gt;&lt;a href=&quot;https://fs.blog/thought-experiment/&quot;&gt;Thought Experiment&lt;/a&gt;&lt;/h3&gt; 
&lt;p&gt;Thought experiments are the sandbox of the mind, the place where we can play with ideas without constraints. They’re a way of exploring the implications of our theories, of testing the boundaries of our understanding. They offer a powerful tool for clarifying our thinking, revealing hidden assumptions, and showing us unintended consequences.&lt;/p&gt; 
&lt;p&gt;The power of thought experiments lies in their ability to create a simplified model of reality where we can test our ideas. In the real world, confounding factors and messy details obscure the core principles at work. Thought experiments allow us to strip away the noise and focus on the essence of the problem.&lt;/p&gt; 
&lt;p&gt;Thought experiments remind us that some of the most profound insights and innovations start with a simple question: What if?&lt;/p&gt; 
&lt;h3&gt;&lt;a href=&quot;https://fs.blog/second-order-thinking/&quot;&gt;Second-Order Thinking&lt;/a&gt;&lt;/h3&gt; 
&lt;p&gt;Second-­order thinking is a method of thinking that goes beyond the surface level, beyond the knee-­jerk reactions and short-­term gains. It asks us to play the long game, to anticipate the ripple effects of our actions, and to make choices that will benefit us not just today but in the months and years to come. Second-order thinking demands we ask: And then what? Think of a chess master contemplating her next move. She doesn’t just consider how the move will affect the next turn but how it will shape the entire game. She’s thinking many steps ahead. She’s considering her own strategy and her opponent’s likely response. In our daily lives, we’re often driven by first-­order thinking. We make decisions based on what makes us happy now, what eases our current discomfort, or satisfies our immediate desires. Second-­order thinking asks us to consider the long-­term implications of our choices to make decisions based not just on what feels good now but on what will lead to the best outcomes over time. In the end, second-­order thinking is about playing the long game. It’s about making choices for the next move and the entire journey.&lt;/p&gt; 
&lt;h3&gt;&lt;a href=&quot;https://fs.blog/probabilistic-thinking/&quot;&gt;Probabilistic Thinking&lt;/a&gt;&lt;/h3&gt; 
&lt;p&gt;Probabilistic thinking is the art of navigating uncertainty. Successfully thinking in shades of probability means roughly identifying what matters, calculating the odds, checking our assumptions, and then deciding. The challenge of probabilistic thinking is that it requires constant updating. As new information emerges, the probabilities change. What seemed likely yesterday may seem unlikely today. This explains why probabilistic thinkers always revise their beliefs with new data and why it’s uncomfortable for many people. It’s much easier to believe something false is accurate than to deal with the fact that we might be wrong. Being a probabilistic thinker means being willing to say, “I don’t know for sure, but based on the evidence, I think there’s a 63 percent chance of X.” The rewards of probabilistic thinking are immense. By embracing uncertainty, we can make better decisions, avoid the pitfalls of overconfidence, and navigate complex situations with greater skill and flexibility. We can be more open-­ minded, more receptive to new ideas, and more resilient in the face of change.&lt;/p&gt; 
&lt;h3&gt;&lt;a href=&quot;https://fs.blog/inversion/&quot;&gt;Inversion&lt;/a&gt;&lt;/h3&gt; 
&lt;p&gt;Much of success comes from simply avoiding common paths to failure. Inversion is not the way we are taught to think. We are taught to identify what we want and explore things that will move us closer to our objective. However, avoiding things that ensure we don’t get what we want dramatically increases our odds of success. We can get fixated on solving problems one way, missing simpler solutions. Inversion breaks us out of this tunnel vision. Instead of “How do I solve this?”, inversion asks, “What would guarantee failure?” Rather than “How can I achieve this?”, it asks “What’s preventing me from achieving it?” This flip reveals insights our usual thinking overlooks. When facing a tricky problem or ambitious goal, try inverting. Ask how you’d guarantee failure. The answers may surprise you—and unlock new solutions.&lt;/p&gt; 
&lt;h3&gt;&lt;a href=&quot;https://fs.blog/occams-razor/&quot;&gt;Occam’s Razor&lt;/a&gt;&lt;/h3&gt; 
&lt;p&gt;Occam’s razor is the intellectual equivalent of “keep it simple.” When faced with competing explanations or solutions, Occam’s razor suggests that the correct explanation is most likely the simplest one, the one that makes the fewest assumptions. This doesn’t mean the simplest theory is always true, only that it should be preferred until proven otherwise. Sometimes, the truth is complex, and the simplest explanation doesn’t account for all the facts. The key to wielding this model is understanding when it works for you and against you. A theory that is too simple fails to capture reality, and one that is too complex collapses under its own weight.&lt;/p&gt; 
&lt;h3&gt;&lt;a href=&quot;https://fs.blog/mental-model-hanlons-razor/&quot;&gt;Hanlon’s Razor&lt;/a&gt;&lt;/h3&gt; 
&lt;p&gt;Hanlon’s razor is a mental safeguard against the temptation to label behavior as malicious when incompetence is the most common response. It’s a reminder that people are not out to get you, and it’s best to assume good faith and resist the urge to assign sinister motives without overwhelming evidence. This isn’t to say that genuine malice doesn’t exist. Of course, it does. But in most interactions, stupidity is a far more common explanation than malevolence. People make mistakes. They forget things. They speak without thinking. They prioritize short-­term wins over long-term wins. They act on incomplete information. They fall prey to bias and prejudice. These actions might appear like deliberate attacks from the outside, but the reality is far more mundane. Hanlon’s razor’s real power lies in how it shifts our perspective. When we assume stupidity rather than malice, we respond differently. Instead of getting defensive or lashing out, we approach the situation with empathy and clarity. For most daily frustrations and confusion, Hanlon’s razor is a powerful reminder to approach problems with a spirit of generosity. It’s a way to reduce drama and stress and find practical solutions instead of descending into blame and escalation.&lt;/p&gt; 
&lt;h2&gt;Systems Thinking&lt;/h2&gt; 
&lt;h3&gt;Feedback Loops&lt;/h3&gt; 
&lt;p&gt;Feedback loops are the engines of growth and change. They’re the mechanisms by which the output of a system influences its input.&lt;/p&gt; 
&lt;p&gt;Complex systems often have many feedback loops, and it can be hard to appreciate how adjusting to feedback in one part of the system will affect the rest.&lt;/p&gt; 
&lt;p&gt;Using feedback loops as a mental model begins with noticing the feedback you give and respond to daily. The model also provides insight into the value of iterations in adjusting based on the feedback you receive. With this lens, you gain insight into where to direct system changes based on feedback and the pace you need to go to monitor the impacts.&lt;/p&gt; 
&lt;p&gt;Feedback loops are what make systems dynamic. Without feedback, a system does the same thing over and over. Understand them, respect them, and use them wisely.&lt;/p&gt; 
&lt;h3&gt;Equilibrium&lt;/h3&gt; 
&lt;p&gt;Equilibrium is the state of balance, where opposing forces cancel each other out. It’s the calm in the storm’s center, the stable point around which the chaos swirls. In a system at equilibrium, there’s no net change. Everything is in a steady state, humming along at a constant pace.&lt;/p&gt; 
&lt;p&gt;However, systems are rarely static. They continuously adjust toward equilibrium but rarely stay in balance for long.&lt;/p&gt; 
&lt;p&gt;Equilibrium is a ­ double-edged sword, both stability and stagnation. In our lives, we often act like we can reach an equilibrium: once we get into a relationship, we’ll be happy; once we move, we’ll be productive; once X thing happens, we’ll be in Y state. But things are always in flux. We don’t reach a certain steady state and then stay there forever. The endless adjustments are our lives. The trick is to find the right balance, strive for equilibrium where it’s needed, and know when to break free and embrace the dis-equilibrium that drives progress.&lt;/p&gt; 
&lt;h3&gt;Bottlenecks&lt;/h3&gt; 
&lt;p&gt;Bottlenecks are the choke points, the narrow parts of the hourglass where everything slows down. They’re the constraints that limit the flow, the weakest links in the chain that determine the strength of the whole. In any system, the bottleneck is the part holding everything else back.&lt;/p&gt; 
&lt;p&gt;The tricky thing about bottlenecks is that they’re not always obvious. It’s easy to focus on the parts of the system that are moving quickly and assume everything is fine. But the real leverage is in finding and fixing the bottlenecks. Speed up the slowest part, and you speed up the whole system.&lt;/p&gt; 
&lt;p&gt;This is the theory of constraints in a nutshell. Figure out your bottleneck and focus all your efforts on alleviating it. Don’t waste time optimizing the parts that are already fast. They’re not the limiting factor.&lt;/p&gt; 
&lt;p&gt;However, bottlenecks aren’t always the villains we make them out to be. Sometimes, they’re a necessary part of the system. Think of a security checkpoint at an airport. It slows everything down, but it’s there for a reason. Remove it, and you might speed things up, but at the cost of safety.&lt;/p&gt; 
&lt;p&gt;The key is to be intentional about your bottlenecks. Choose them wisely, and make sure they’re serving a purpose. A deliberate bottleneck can be a powerful tool for focusing effort and maintaining quality. An accidental bottleneck is just a drag on the system.&lt;/p&gt; 
&lt;p&gt;Bottlenecks are leverage points where a little effort can go a long way.&lt;/p&gt; 
&lt;h3&gt;Scale&lt;/h3&gt; 
&lt;p&gt;Systems change as they scale up or down; neither is intrinsically better or worse. The right scale depends on your goals and the context. If you want to scale something up, you need to anticipate that new problems will keep ­ arising—​­ problems that didn’t exist on a smaller scale. Or you might need to keep solving the same problems in different ways.&lt;/p&gt; 
&lt;p&gt;Think about a recipe. If you’re making a cake for four people, you use a certain amount of ingredients. But if you want to make a cake for four hundred people, you don’t just multiply the ingredients by one hundred. That’s not how scale works. You need to change the process and use bigger mixers and bigger ovens. You need a system that can handle the increased volume without breaking down.&lt;/p&gt; 
&lt;p&gt;The challenge with scale is that it’s not always obvious how to achieve it. What works for a small system often breaks down at larger volumes. You have to anticipate the bottlenecks and the points where the system will strain under the increased load. And you have to be ready to re‑engineer your processes as you grow.&lt;/p&gt; 
&lt;p&gt;If you’re building something, always be thinking about scale. How will this work when you have ten times as many customers? One hundred times? One thousand times? Build with scale in mind from the start, and you’ll be ready for the growth when it comes.&lt;/p&gt; 
&lt;h3&gt;Margin of Safety&lt;/h3&gt; 
&lt;p&gt;Margin of safety is a secret weapon. It’s the buffer, the extra capacity, the redundancy that you build into a system to handle unexpected stress. It’s the difference between a bridge that can barely handle the expected load and one that can handle ten times that load without breaking a sweat.&lt;/p&gt; 
&lt;p&gt;You can apply a margin of safety to any area of life with uncertainty and risk. The key is always to ask yourself: What if I’m wrong? What if things don’t go as planned? How much extra capacity must I build to handle the unexpected?&lt;/p&gt; 
&lt;p&gt;But here’s the rub: margin of safety isn’t free. It means spending more upfront. In the short term, you’ll look overly cautious and leave immediate profits on the table. But in the long run, this apparent overcaution lets you survive when others break – and thrive when others merely survive.&lt;/p&gt; 
&lt;p&gt;Margin of safety is the unsung hero of ­ long-​­term success. It’s not flashy. It’s not exciting, but it’s the foundation on which everything else is built. Master it, and you’ll be well on your way to navigating the uncertainties of life with confidence and stability.&lt;/p&gt; 
&lt;h3&gt;Churn&lt;/h3&gt; 
&lt;p&gt;Churn is the silent killer of businesses. It’s the slow leak, the constant drip of customers slipping away, of users drifting off to find something new. The attrition eats away at your growth, forcing you to keep running just to stay in place. The thing about churn is that it’s often hidden. It’s not like a sudden crisis that grabs your attention. It’s a slow, quiet process that happens in the background.&lt;/p&gt; 
&lt;p&gt;Churn can present opportunity. Like a snake shedding its skin, replacing components of a system is a natural part of keeping it healthy. New parts can improve functionality.&lt;/p&gt; 
&lt;p&gt;When we use this model as a lens, we see that new people bring new ideas, and counterintuitively, some turnover allows us to maintain stability. Replacing what is worn out also allows us to upgrade and expand our capabilities, creating new opportunities. Some churn is inevitable. Too much can kill you.&lt;/p&gt; 
&lt;h3&gt;Algorithms&lt;/h3&gt; 
&lt;p&gt;Algorithms are recipes. A list of crisp, unambiguous steps that tell you how to get from point A to point B. But they’re more than just directions. Algorithms are if‑then machines for tuning out the noise and zeroing in on the signal. Have the specs been met? Fol- low the algorithm and find out. Thinking algorithmically means searching for processes that reliably spit out the desired results, like a vending machine dispensing the same candy bar every time someone punches in E4.&lt;/p&gt; 
&lt;h3&gt;Critical mass&lt;/h3&gt; 
&lt;p&gt;Critical mass isn’t just a science term; it’s a guide for understanding that often things happen slowly and then all at once. It’s the moment when a system goes from sputtering along to explosive growth. Like a nuclear chain reaction, once you hit critical mass, the reaction becomes self-sustaining.&lt;/p&gt; 
&lt;p&gt;Through this lens we gain insight into the amount of material needed for a system to change from one state to another. Material can be anything from people and effort to raw material. When enough material builds up, systems reach their tipping point. When we keep going, we get sustainable change.&lt;/p&gt; 
&lt;p&gt;Using critical mass as a lens for situations where you want different outcomes helps you identify both the design elements you need to change and the work you need to put in.&lt;/p&gt; 
&lt;h3&gt;Emergence&lt;/h3&gt; 
&lt;p&gt;Nearly everything is an emergent ­ effect—​­a table, a space shuttle, even ­ us—​­ combinations of ingredients that come together in a specific way to create something new. Emergence is the universe’s way of reminding us that when we combine different pieces in new ways, we get results that are more than the sum of their parts, often in the most unexpected and thrilling ways.&lt;/p&gt; 
&lt;p&gt;Using this mental model is not about predicting emergent properties but acknowledging they are possible. There is no need to stick with what you know; mix it up and see what happens. Learn new skills, interact with new people, read new things.&lt;/p&gt; 
&lt;h3&gt;Irreducibility&lt;/h3&gt; 
&lt;p&gt;Irreducibility is about essence. It’s the idea that some things can’t be broken down into smaller parts without losing what makes them tick. It’s the idea that not everything can be explained by looking at its components. Emergent properties arise from complex systems that can’t be predicted by studying the individual parts.&lt;/p&gt; 
&lt;p&gt;Grappling with irreducibility requires a shift in thinking. Instead of trying to break things down, sometimes you have to zoom out. Look at the big picture. Embrace the complexity. Because some problems don’t have neat, modular solutions. They’re irreducibly messy.&lt;/p&gt; 
&lt;p&gt;Using irreducibility as a lens helps you focus on what you can change by understanding what really matters&lt;/p&gt; 
&lt;h3&gt;Law of Diminishing Returns&lt;/h3&gt; 
&lt;p&gt;Diminishing returns is the idea that the easy wins usually come first. The more you optimize a system, the harder it gets to eke out additional improvements, like squeezing juice from a lemon. The first squeeze is easy. The second takes a bit more work. By the tenth squeeze, you’re fighting for every last drop.&lt;/p&gt; 
&lt;p&gt;Every bit of effort translates into significant gains when you’re a beginner. But as you level up, progress becomes more incremental. It takes more and more work to get better and better. That’s why going from good to great is much harder than going from bad to good.&lt;/p&gt; 
&lt;p&gt;Understanding diminishing returns is crucial for allocating resources efficiently. You want to focus on where you can get the biggest bang for your buck. Sometimes, that means knowing when to stop optimizing and move on to something else.&lt;/p&gt; 
&lt;h2&gt;The Mental Models of Military and War&lt;/h2&gt; 
&lt;h3&gt;Seeing the Front&lt;/h3&gt; 
&lt;p&gt;One of the most valuable military tactics is the habit of “personally seeing the front” before making decisions – not always relying on advisors, maps, and reports, all of which can be faulty or biased. The Map/Territory model, as does the incentive model, illustrates the problem of not seeing the front. Leaders of any organization can generally benefit from seeing the front, as it provides firsthand information and tends to improve the quality of secondhand information. (Also known as, &quot;Eating Your Own Dog Food&quot; or &quot;Working the Phones&quot;)&lt;/p&gt; 
&lt;h3&gt;Asymmetric Warfare&lt;/h3&gt; 
&lt;p&gt;The asymmetry model leads to an application in warfare whereby one side seemingly “plays by different rules” than the other side due to circumstance. Generally, this model is applied by an insurgency with limited resources. Unable to out-muscle their opponents, asymmetric fighters use other tactics, as with terrorism creating fear that’s disproportionate to their actual destructive ability.&lt;/p&gt; 
&lt;h3&gt;Two-Front War&lt;/h3&gt; 
&lt;p&gt;The Second World War was a good example of a two-front war. Once Russia and Germany became enemies, Germany was forced to split its troops and send them to separate fronts, weakening their impact on either front. Opening a two-front war can often be a useful tactic, as can solving a two-front war or avoiding one, as in the example of an organization tamping down internal discord to focus on its competitors.&lt;/p&gt; 
&lt;h3&gt;&lt;a href=&quot;https://fs.blog/counterinsurgency/&quot;&gt;Counterinsurgency&lt;/a&gt;&lt;/h3&gt; 
&lt;p&gt;Though asymmetric insurgent warfare can be extremely effective, competitors have developed counterinsurgency strategies over time. Recently and famously, General David Petraeus of the United States led the development of counterinsurgency plans involving no additional force but substantial gains. Tit-for-tat warfare or competition often leads to a feedback loop that demands insurgency and counterinsurgency.&lt;/p&gt; 
&lt;h3&gt;&lt;a href=&quot;https://fs.blog/mutually-assured-destruction/&quot;&gt;Mutually Assured Destruction&lt;/a&gt;&lt;/h3&gt; 
&lt;p&gt;Somewhat paradoxically, the stronger two opponents become, the less likely they may be to destroy one another. This process of mutually assured destruction occurs not just in warfare, as with the development of global nuclear warheads, but also in business, as with the avoidance of destructive price wars between competitors. However, in a fat-tailed world, it is also possible that mutually assured destruction scenarios simply make destruction more severe in the event of a mistake (pushing destruction into the “tails” of the distribution).&lt;/p&gt; 
&lt;h2&gt;Human Nature and Judgment&lt;/h2&gt; 
&lt;h3&gt;Trust&lt;/h3&gt; 
&lt;p&gt;Fundamentally, the modern world operates on trust. Familial trust is generally a given (otherwise we’d have a hell of a time surviving), but we also choose to trust chefs, clerks, drivers, factory workers, executives, and many others. A trusting system is one that tends to work most efficiently; the rewards of trust are extremely high.&lt;/p&gt; 
&lt;h3&gt;Bias from Incentives&lt;/h3&gt; 
&lt;p&gt;Highly responsive to incentives, humans have perhaps the most varied and hardest to understand set of incentives in the animal kingdom. This causes us to distort our thinking when it is in our own interest to do so. A wonderful example is a salesman truly believing that his product will improve the lives of its users. It’s not merely convenient that he sells the product; the fact of his selling the product causes a very real bias in his own thinking.&lt;/p&gt; 
&lt;h3&gt;Pavlovian Association&lt;/h3&gt; 
&lt;p&gt;Ivan Pavlov very effectively demonstrated that animals can respond not just to direct incentives but also to associated objects; remember the famous dogs salivating at the ring of a bell. Human beings are much the same and can feel positive and negative emotion towards intangible objects, with the emotion coming from past associations rather than direct effects.&lt;/p&gt; 
&lt;h3&gt;&lt;a href=&quot;https://fs.blog/mental-model-bias-envy-jealousy/&quot;&gt;Tendency to Feel Envy &amp;amp; Jealousy&lt;/a&gt;&lt;/h3&gt; 
&lt;p&gt;Humans have a tendency to feel envious of those receiving more than they are, and a desire “get what is theirs” in due course. The tendency towards envy is strong enough to drive otherwise irrational behavior, but is as old as humanity itself. Any system ignorant of envy effects will tend to self-immolate over time.&lt;/p&gt; 
&lt;h3&gt;&lt;a href=&quot;https://fs.blog/mental-model-bias-from-liking-loving/&quot;&gt;Tendency to Distort Due to Liking/Loving&lt;/a&gt; or &lt;a href=&quot;https://www.farnamstreetblog.com/2016/09/bias-from-disliking-hating/&quot;&gt;Disliking/Hating&lt;/a&gt;&lt;/h3&gt; 
&lt;p&gt;Based on past association, stereotyping, ideology, genetic influence, or direct experience, humans have a tendency to distort their thinking in favor of people or things that they like and against people or things they dislike. This tendency leads to overrating the things we like and underrating or broadly categorizing things we dislike, often missing crucial nuances in the process.&lt;/p&gt; 
&lt;h3&gt;Denial&lt;/h3&gt; 
&lt;p&gt;Anyone who has been alive long enough realizes that, as the saying goes, “denial is not just a river in Africa.” This is powerfully demonstrated in situations like war or drug abuse, where denial has powerful destructive effects but allows for behavioral inertia. Denying reality can be a coping mechanism, a survival mechanism, or a purposeful tactic.&lt;/p&gt; 
&lt;h3&gt;&lt;a href=&quot;https://fs.blog/mental-model-availability-bias/&quot;&gt;Availability Heuristic&lt;/a&gt;&lt;/h3&gt; 
&lt;p&gt;One of the most useful findings of modern psychology is what Daniel Kahneman calls the Availability Bias or Heuristic: We tend to most easily recall what is salient, important, frequent, and recent. The brain has its own energy-saving and inertial tendencies that we have little control over – the availability heuristic is likely one of them. Having a truly comprehensive memory would be debilitating. Some sub-examples of the availability heuristic include the Anchoring and Sunk Cost Tendencies.&lt;/p&gt; 
&lt;h3&gt;Representativeness Heuristic&lt;/h3&gt; 
&lt;p&gt;The three major psychological findings that fall under Representativeness, also defined by Kahneman and his partner Tversky, are:&lt;/p&gt; 
&lt;ol&gt; 
 &lt;li&gt;&lt;a href=&quot;https://fs.blog/mental-model-bias-from-insensitivity-to-base-rates/&quot;&gt;Failure to Account for Base Rates&lt;/a&gt;: An unconscious failure to look at past odds in determining current or future behavior.&lt;/li&gt; 
 &lt;li&gt;Tendency to Stereotype: The tendency to broadly generalize and categorize rather than look for specific nuance. Like availability, this is generally a necessary trait for energy-saving in the brain.&lt;/li&gt; 
 &lt;li&gt;Failure to See False Conjunctions: Most famously demonstrated by the Linda Test, the same two psychologists showed that students chose more vividly described individuals as more likely to fit into a predefined category than individuals with broader, more inclusive, but less vivid descriptions, even if the vivid example was a mere subset of the more inclusive set. These specific examples are seen as more representative of the category than those with the broader but vaguer descriptions, in violation of logic and probability.&lt;/li&gt; 
&lt;/ol&gt; 
&lt;h3&gt;&lt;a href=&quot;https://fs.blog/mental-model-social-proof/&quot;&gt;Social Proof&lt;/a&gt; (Safety in Numbers)&lt;/h3&gt; 
&lt;p&gt;Human beings are one of many social species, along with bees, ants, and chimps, among many more. We have a DNA-level instinct to seek safety in numbers and will look for social guidance of our behavior. This instinct creates a cohesive sense of cooperation and culture which would not otherwise be possible but also leads us to do foolish things if our group is doing them as well.&lt;/p&gt; 
&lt;h3&gt;&lt;a href=&quot;https://fs.blog/narrative-fallacy/&quot;&gt;Narrative Instinct&lt;/a&gt;&lt;/h3&gt; 
&lt;p&gt;Human beings have been appropriately called “the storytelling animal” because of our instinct to construct and seek meaning in narrative. It’s likely that long before we developed the ability to write or to create objects, we were telling stories and thinking in stories. Nearly all social organizations, from religious institutions to corporations to nation-states, run on constructions of the narrative instinct.&lt;/p&gt; 
&lt;h3&gt;Curiosity Instinct&lt;/h3&gt; 
&lt;p&gt;We like to call other species curious, but we are the most curious of all, an instinct which led us out of the savanna and led us to learn a great deal about the world around us, using that information to create the world in our collective minds. The curiosity instinct leads to unique human behavior and forms of organization like the scientific enterprise. Even before there were direct incentives to innovate, humans innovated out of curiosity.&lt;/p&gt; 
&lt;h3&gt;Language Instinct&lt;/h3&gt; 
&lt;p&gt;The psychologist Steven Pinker calls our DNA-level instinct to learn grammatically constructed language the Language Instinct. The idea that grammatical language is not a simple cultural artifact was first popularized by the linguist Noam Chomsky. As we saw with the narrative instinct, we use these instincts to create shared stories, as well as to gossip, solve problems, and fight, among other things. Grammatically ordered language theoretically carries infinite varying meaning.&lt;/p&gt; 
&lt;h3&gt;First-Conclusion Bias&lt;/h3&gt; 
&lt;p&gt;As Charlie Munger famously pointed out, the mind works a bit like a sperm and egg: the first idea gets in and then the mind shuts. Like many other tendencies, this is probably an energy-saving device. Our tendency to settle on first conclusions leads us to accept many erroneous results and cease asking questions; it can be countered with some simple and useful mental routines.&lt;/p&gt; 
&lt;h3&gt;&lt;a href=&quot;https://fs.blog/mental-model-bias-from-insensitivity-to-sample-size/&quot;&gt;Tendency to Overgeneralize from Small Samples&lt;/a&gt;&lt;/h3&gt; 
&lt;p&gt;It’s important for human beings to generalize; we need not see every instance to understand the general rule, and this works to our advantage. With generalizing, however, comes a subset of errors when we forget about the Law of Large Numbers and act as if it does not exist. We take a small number of instances and create a general category, even if we have no statistically sound basis for the conclusion.&lt;/p&gt; 
&lt;h3&gt;Relative Satisfaction/Misery Tendencies&lt;/h3&gt; 
&lt;p&gt;The envy tendency is probably the most obvious manifestation of the relative satisfaction tendency, but nearly all studies of human happiness show that it is related to the state of the person relative to either their past or their peers, not absolute. These relative tendencies cause us great misery or happiness in a very wide variety of objectively different situations and make us poor predictors of our own behavior and feelings.&lt;/p&gt; 
&lt;h3&gt;&lt;a href=&quot;https://fs.blog/commitment-consistency-bias/&quot;&gt;Commitment &amp;amp; Consistency Bias&lt;/a&gt;&lt;/h3&gt; 
&lt;p&gt;As psychologists have frequently and famously demonstrated, humans are subject to a bias towards keeping their prior commitments and staying consistent with our prior selves when possible. This trait is necessary for social cohesion: people who often change their conclusions and habits are often distrusted. Yet our bias towards staying consistent can become, as one wag put it, a “hobgoblin of foolish minds” – when it is combined with the first-conclusion bias, we end up landing on poor answers and standing pat in the face of great evidence.&lt;/p&gt; 
&lt;h3&gt;&lt;a href=&quot;https://fs.blog/what-is-hindsight-bias/&quot;&gt;Hindsight Bias&lt;/a&gt;&lt;/h3&gt; 
&lt;p&gt;Once we know the outcome, it’s nearly impossible to turn back the clock mentally. Our narrative instinct leads us to reason that we knew it all along (whatever “it” is), when in fact we are often simply reasoning post-hoc with information not available to us before the event. The hindsight bias explains why it’s wise to keep a journal of important decisions for an unaltered record and to re-examine our beliefs when we convince ourselves that we knew it all along.&lt;/p&gt; 
&lt;h3&gt;&lt;a href=&quot;https://fs.blog/kantian-fairness-tendency/&quot;&gt;Sensitivity to Fairness&lt;/a&gt;&lt;/h3&gt; 
&lt;p&gt;Justice runs deep in our veins. In another illustration of our relative sense of well-being, we are careful arbiters of what is fair. Violations of fairness can be considered grounds for reciprocal action, or at least distrust. Yet fairness itself seems to be a moving target. What is seen as fair and just in one time and place may not be in another. Consider that slavery has been seen as perfectly natural and perfectly unnatural in alternating phases of human existence.&lt;/p&gt; 
&lt;h3&gt;Tendency to Overestimate Consistency of Behavior (&lt;a href=&quot;https://fs.blog/fundamental-attribution-error/&quot;&gt;Fundamental Attribution Error&lt;/a&gt;)&lt;/h3&gt; 
&lt;p&gt;We tend to over-ascribe the behavior of others to their innate traits rather than to situational factors, leading us to overestimate how consistent that behavior will be in the future. In such a situation, predicting behavior seems not very difficult. Of course, in practice this assumption is consistently demonstrated to be wrong, and we are consequently surprised when others do not act in accordance with the “innate” traits we’ve endowed them with.&lt;/p&gt; 
&lt;h3&gt;Influence of Stress (Including Breaking Points)&lt;/h3&gt; 
&lt;p&gt;Stress causes both mental and physiological responses and tends to amplify the other biases. Almost all human mental biases become worse in the face of stress as the body goes into a fight-or-flight response, relying purely on instinct without the emergency brake of Daniel Kahneman’s “System 2” type of reasoning. Stress causes hasty decisions, immediacy, and a fallback to habit, thus giving rise to the elite soldiers’ motto: “In the thick of battle, you will not rise to the level of your expectations, but fall to the level of your training.”&lt;/p&gt; 
&lt;h3&gt;&lt;a href=&quot;https://fs.blog/survivorship-bias/&quot;&gt;Survivorship Bias&lt;/a&gt;&lt;/h3&gt; 
&lt;p&gt;A major problem with historiography – our interpretation of the past – is that history is famously written by the victors. We do not see what Nassim Taleb calls the “silent grave” – the lottery ticket holders who did not win. Thus, we over-attribute success to things done by the successful agent rather than to randomness or luck, and we often learn false lessons by exclusively studying victors without seeing all of the accompanying losers who acted in the same way but were not lucky enough to succeed.&lt;/p&gt; 
&lt;h3&gt;&lt;a href=&quot;https://fs.blog/do-something-syndrome/&quot;&gt;Tendency to Want to Do Something&lt;/a&gt; (Fight/Flight, Intervention, Demonstration of Value, etc.)&lt;/h3&gt; 
&lt;p&gt;We might term this Boredom Syndrome: Most humans have the tendency to need to act, even when their actions are not needed. We also tend to offer solutions even when we do not have knowledge to solve the problem.&lt;/p&gt; 
&lt;h3&gt;&lt;a href=&quot;https://fs.blog/peter-cathcart-wason-falsification/&quot;&gt;Falsification&lt;/a&gt; / &lt;a href=&quot;https://fs.blog/confirmation-bias/&quot;&gt;Confirmation Bias&lt;/a&gt;&lt;/h3&gt; 
&lt;p&gt;What a man wishes, he also believes. Similarly, what we believe is what we choose to see. This is commonly referred to as the confirmation bias. It is a deeply ingrained mental habit, both energy-conserving and comfortable, to look for confirmations of long-held wisdom rather than violations. Yet the scientific process – including hypothesis generation, blind testing when needed, and objective statistical rigor – is designed to root out precisely the opposite, which is why it works so well when followed.&lt;/p&gt; 
&lt;p&gt;The modern scientific enterprise operates under the principle of falsification: A method is termed scientific if it can be stated so that a certain defined result would cause it to be proved false. Pseudo-knowledge and pseudo-science operate and propagate by being unfalsifiable. As with astrology, we cannot prove them either correct or incorrect because the conditions under which they would be shown false are never stated.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Finite and Infinite Games</title>
      <link>https://tedneward.github.io/Research/thinking/finite-infinite-games/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">thinking/finite-infinite-games/index.html</guid>
      	<description>
	&lt;p&gt;(by James Carse, 1986)&lt;/p&gt; 
&lt;h2&gt;One: There Are at Least Two Kinds of Games&lt;/h2&gt; 
&lt;ol&gt; 
 &lt;li&gt; &lt;p&gt;A finite game is played for the purpose of winning, an infinite game for the purpose of continuing the play.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;If a finite game is to be won by someone it must come to a definitive end. It will come to an end when someone has won. We know that someone has won the game when all the players have agreed who among them is the winner. No other condition than the agreement of the players is absolutely required in determining who has won the game. … There is no finite game unless the players freely choose to play it. No one can play who is forced to play. It is an invariable principle of all play, finite and infinite, that whoever plays, plays freely. Whoever must play, cannot play.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;We can speak of finite games as having temporal boundaries. Players must agree to the establishment of spatial and numerical boundaries as well. That is, the game must be played within a marked area, and with specified players.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;To have such boundaries means that the date, place, and membership of each finite game are externally defined. The world is elaborately marked by boundaries of contest, its people finely classified as to their eligibilities.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Only one person or team can win a finite game, but the other contestants may well be ranked at the conclusion of play.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;In one respect, but only one, an infinite game is identical to a finite game: Of infinite players we can also say that if they play they play freely; if they must play, they cannot play. Otherwise, infinite and finite play stand in the sharpest possible contrast. Infinite players cannot say when their game began, nor do they care. There are no spatial or numerical boundaries to an infinite game. While finite games are externally defined, infinite games are internally defined. The time of an infinite game is not world time, but time created within the play itself. Since each play of an infinite game eliminates boundaries, it opens to players a new horizon of time.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Finite games can be played within an infinite game, but an infinite game cannot be played within a finite game. Infinite players regard their wins and losses in whatever finite games they play as but moments in continuing play.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;If finite games must be externally bounded by time, space, and number, they must also have internal limitations on what the players can do to and with each other. To agree on internal limitations is to establish rules of play. It is, in fact, by knowing what the rules are that we know what the game is. The rules of a finite game are the contractual terms by which players can agree who has won.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;The rules must be published prior to play, and the players must agree to them before play begins. The agreement of the players to the applicable rules constitutes the ultimate validation of those rules. They are valid only if and when players freely play by them.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;If the rules of a finite game are unique to that game it is evident that the rules may not change in the course of play--else a different game is being played. The rules of an infinite game must change in the course of play. The rules are changed when the players of an infinite game agree that the play is imperiled by a finite outcome--that is, by the victory of some players and the defeat of others. The rules of an infinite game are changed to prevent anyone from winning the game and to bring as many persons as possible into the play. If the rules of a finite game are the contractual terms by which the players can agree who has won, the rules of an infinite game are the contractual terms by which the players agree to continue playing.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;The rules of an infinite game are always designed to deal with specific threats to the continuation of play. Infinite players use the rules to regulate the way they will take the boundaries or limits being forced against their play into the game itself. The rule-making capacity of infinite players is often challenged by the impingement of powerful boundaries against their play--such as physical exhaustion, or the loss of material resources, or the hostility of nonplayers, or death. The task is to design rules that will allow the players to continue the game by taking these limits into play--even when death is one of the limits. Finite players play within boundaries; infinite players play with boundaries.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Although it may be evident enough in theory that whoever plays a finite game plays freely, it is often the case that finite players will be unaware of this absolute freedom and will come to thin that whatever they do they must do.&lt;/p&gt; &lt;/li&gt; 
&lt;/ol&gt; 
&lt;h2&gt;Two: No One Can Play a Game Alone&lt;/h2&gt; 
&lt;h2&gt;Three: I Am the Genius of Myself&lt;/h2&gt; 
&lt;h2&gt;Four: A Finite Game Occurs Within a World&lt;/h2&gt; 
&lt;h2&gt;Five: Nature Is the Realm of the Unspeakable&lt;/h2&gt; 
&lt;h2&gt;Six: We Control Nature for Societal Reasons&lt;/h2&gt; 
&lt;h2&gt;Seven: Myth Provokes Explanation but Accepts None of It&lt;/h2&gt;
	</description>
    </item>
    <item>
      <title>Thinking about Philosophy</title>
      <link>https://tedneward.github.io/Research/thinking/philosophy/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">thinking/philosophy/index.html</guid>
      	<description>
	&lt;h2&gt;Places&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://plato.stanford.edu/&quot;&gt;Stanford Encyclopedia of Philosophy&lt;/a&gt; | &lt;a href=&quot;https://plato.stanford.edu/contents.html&quot;&gt;Table of Contents&lt;/a&gt; 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://plato.stanford.edu/entries/gratitude/&quot;&gt;Gratitude&lt;/a&gt;: Gratitude is the proper or called-for response in a beneficiary to benefits or beneficence from a benefactor. It is a topic of interest in normative ethics, applied ethics, moral psychology, and political philosophy. Despite its ubiquity in everyday life, there is substantive disagreement among philosophers over the nature of gratitude and its relationship to other philosophical concepts. The sections of this article address five areas of debate about what gratitude is, when gratitude is called for, and how the answers to those questions bear on other topics in moral philosophy and philosophy generally.&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Brain Rules</title>
      <link>https://tedneward.github.io/Research/thinking/brain-rules/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">thinking/brain-rules/index.html</guid>
      	<description>
	&lt;p&gt;&lt;em&gt;(by John Medina; Pear Press, when?; ISBN ...)&lt;/em&gt;&lt;/p&gt; 
&lt;p&gt;1) Exercise boosts brain power&lt;br&gt; 2) The human brain evolved, too&lt;br&gt; 3) Every brain is wired differently&lt;br&gt; 4) We don&apos;t pay attention to boring things&lt;br&gt; 5) Repeat to remember&lt;br&gt; 6) Remember to repeat&lt;br&gt; 7) Sleep well, think well&lt;br&gt; 8) Stressed brains don&apos;t learn the same way&lt;br&gt; 9) Stimulate more of the senses&lt;br&gt; 10) Vision trumps all other senses&lt;br&gt; 11) Male and female brains are different&lt;br&gt; 12) We are powerful and natural explorers&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Economics</title>
      <link>https://tedneward.github.io/Research/thinking/economics/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">thinking/economics/index.html</guid>
      	<description>
	&lt;h2&gt;The Economist&lt;/h2&gt; 
&lt;p&gt;&lt;a href=&quot;https://www.economist.com/the-economist-reads/2022/08/09/what-to-read-to-understand-how-economists-think&quot;&gt;What to read to understand how economists think&lt;/a&gt;:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;strong&gt;&lt;em&gt;Capitalism and Freedom&lt;/em&gt;&lt;/strong&gt;. &lt;em&gt;By Milton Friedman. University of Chicago Press; 272 pages&lt;/em&gt; &quot;This book is perhaps the best way to learn to think about trade-offs, because that was how Friedman always thought about the world.&quot;&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;&lt;em&gt;The Worldly Philosophers&lt;/em&gt;&lt;/strong&gt;. &lt;em&gt;By Robert Heilbroner. Touchstone; 368 pages; $18.99. Simon &amp;amp; Schuster&lt;/em&gt; &quot;In a cheerful, conversational style, Heilbroner takes the reader through the writings of the earliest economists, explaining why their ideas were so revolutionary.&quot;&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;&lt;em&gt;Africa: Why Economists Get It Wrong&lt;/em&gt;&lt;/strong&gt;. &lt;em&gt;By Morten Jerven. Bloomsbury Academic; 176 pages&lt;/em&gt; &quot;A lot of economists plug data from Africa into huge statistical models, seeking to explain, for instance, why social trust is higher in one part of a country than another. But a lot of this research is based on shoddy data. ... One lesson from the book (which we reviewed in 2015) is to be upfront about the limitations of your data sources.&quot;&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;&lt;em&gt;Capitalism, Alone&lt;/em&gt;&lt;/strong&gt;. &lt;em&gt;By Branko Milanovic. Harvard University Press; 304 pages&lt;/em&gt; &quot;This is the book to read if you want to understand why capitalism—and economists’ way of thinking—has triumphed the world over. ... Capitalism is far from perfect, his book shows, yet it is hard to shake the notion that it is the only system that broadly works.&quot;&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;&lt;em&gt;Freakonomics: A Rogue Economist Explores the Hidden Side of Everything&lt;/em&gt;&lt;/strong&gt;. &lt;em&gt;By Stephen J. Dubner and Steven Levitt. HarperCollins; 352 pages&lt;/em&gt; &quot;This book is so famous that it seems a cliché to choose it, but if you haven’t read it, you really should.&quot;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;&lt;a href=&quot;https://www.economist.com/the-economist-reads/2022/07/04/what-to-read-to-understand-the-history-of-western-capitalism&quot;&gt;What to read to understand the history of Western capitalism&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Category Theory</title>
      <link>https://tedneward.github.io/Research/thinking/category-theory/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">thinking/category-theory/index.html</guid>
      	<description>
	&lt;p&gt;Because apparently this is now &quot;a thing&quot; among serious programmers....&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://arxiv.org/abs/1803.05316&quot;&gt;[1803.05316] Seven Sketches in Compositionality: An Invitation to Applied Category Theory&lt;/a&gt; [Mar 2018]&lt;/p&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;What’s neat is that no prior knowledge of category theory is assumed! They write for a broad audience: motivated HS students, machine learning researchers, retired programmers, pure math’ns…, &amp;amp; each ch. is based on real-world topics like electrical circuits and control theory. I love what they share in the Preface: “The motto at MIT is ‘mens et manus,’ Latin for ‘mind and hand.’ We believe that category theory—and pure math in general—has stayed in the realm of mind for too long; it is ripe to be brought to hand.” – &lt;a href=&quot;https://twitter.com/math3ma&quot;&gt;via Twitter&lt;/a&gt;&lt;/p&gt; 
&lt;/blockquote&gt; 
&lt;p&gt;&lt;a href=&quot;https://www.slideshare.net/JordanParmer/category-theory-in-10-minutes-77309719&quot;&gt;Category Theory in 10 Minutes&lt;/a&gt; | &lt;a href=&quot;http://rs.io/why-category-theory-matters/&quot;&gt;Why Category Theory Matters&lt;/a&gt; | &lt;a href=&quot;https://markkarpov.com/post/category-theory-part-1.html&quot;&gt;Category Theory Basics, Part I&lt;/a&gt; | &lt;a href=&quot;http://ncatlab.org/nlab/show/category+theory&quot;&gt;Notebook on category theory at nLab&lt;/a&gt; | &lt;a href=&quot;http://arxiv.org/abs/1302.6946&quot;&gt;Category Theory for Scientists&lt;/a&gt; by David Spivak. | &lt;a href=&quot;http://category-theory.mitpress.mit.edu/chapter001.html&quot;&gt;Category Theory for the sciences (book)&lt;/a&gt; by David Spivak. | &lt;a href=&quot;http://www.logicmatters.net/resources/pdfs/GentleIntro.pdf&quot;&gt;Category Theory - a gentle introduction (PDF)&lt;/a&gt; by Peter Smith of Cambridge university. 171 pages. | &lt;a href=&quot;http://plato.stanford.edu/entries/category-theory/bib.html&quot;&gt;Pragammatic Reading guide&lt;/a&gt; via &lt;a href=&quot;http://redd.it/1ht4mf&quot;&gt;this reddit thread&lt;/a&gt;. | &lt;a href=&quot;http://ct2015.web.ua.pt/talks.html&quot;&gt;CT 2015 conf&lt;/a&gt; | &lt;a href=&quot;http://www.logicmatters.net/categories/&quot;&gt;Reading lists&lt;/a&gt; | &lt;a href=&quot;https://mioalter.github.io/posts/2018-12-17-Yoneda.html&quot;&gt;Yoneda, Currying, and Fusion&lt;/a&gt;; Dec 2018.&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://bartoszmilewski.com/2014/10/28/category-theory-for-programmers-the-preface/&quot;&gt;Bartosz Milewski: Category Theory for Programmers&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://www.quantamagazine.org/with-category-theory-mathematics-escapes-from-equality-20191010/&quot;&gt;&quot;With Category Theory, Mathematics Escapes from Equality&quot;&lt;/a&gt;: &quot;Two monumental works have led many mathematicians to avoid the equal sign. Their goal: Rebuild the foundations of the discipline upon the looser relationship of “equivalence.” The process has not always gone smoothly.&quot;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Concept Maps</title>
      <link>https://tedneward.github.io/Research/thinking/concept-maps/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">thinking/concept-maps/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://cmap.ihmc.us/docs/learn.php&quot;&gt;Cmap&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Atomic Habits</title>
      <link>https://tedneward.github.io/Research/thinking/atomic-habits/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">thinking/atomic-habits/index.html</guid>
      	<description>
	&lt;p&gt;&lt;em&gt;(???)&lt;/em&gt;&lt;/p&gt; 
&lt;h2&gt;&lt;a href=&quot;https://www.chrisbehan.ca/posts/atomic-habits&quot;&gt;Quick Summary&lt;/a&gt;&lt;/h2&gt; 
&lt;p&gt;A habit is a routine or behavior that is performed so regularly it becomes automatic. From a biological perspective, the purpose of habits is to preserve energy by offloading the cognitive effort spent on repetitive tasks from the conscious to the subconscious. As you repeat a certain behavior, the connection between the neurons (the fundamental units of the brain) associated with that behavior become stronger. After enough repetitions, the connection becomes so strong that the behavior is automatic. When Stephen Curry picked up and shot a basketball for the first time, he had to focus on every aspect of the motion: hand position, balance, posture, and release. But after millions of practice shots, Curry can shoot the ball from anywhere on the court without thinking.&lt;/p&gt; 
&lt;p&gt;When used effectively, habits empower you to become whoever you want in life. A habit of daily reading will eventually make you knowledgeable, a habit of daily exercise will eventually make you strong. The difficult part is sticking with the habit long enough to reap the benefits. You won&apos;t develop a wealth of knowledge from reading one book, and you won&apos;t get jacked after going to the gym for a week. Only after years of reading will you be able to compare and build upon ideas from different disciplines. Only after months of workouts will you be able to fully activate all the muscles associated with a lift. A 1% improvement every day for a year results in a 37x improvement from where you started. The initial 1 percent improvements are difficult to notice, but after a while they become astronomical. All big things come from small beginnings.&lt;/p&gt; 
&lt;p&gt;Social media is filled with posts celebrating the achievements of individuals while glossing over the thousands of hours it took them to get there. What we don&apos;t see in pictures of Giannis Antetokounmpo hoisting the Larry O&apos;Brien trophy are the years of grueling practice that preceded his championship run. We&apos;ve been tricked into expecting instant results without putting in the reps. To effectively develop new habits, we need to break this mindset and acknowledge that the most powerful outcomes are delayed. We must shift our focus from achievement to trajectory. The strongest man in the world becomes weak if he stops using his muscles. The brightest man becomes dumb if he stops using his brain. It matters not where you were yesterday, but rather, where you&apos;re headed today.&lt;/p&gt; 
&lt;p&gt;Trajectory &amp;gt; Achievements&lt;/p&gt; 
&lt;h3&gt;The Three Layers of Behavior Change&lt;/h3&gt; 
&lt;p&gt;To effectively build new habits, you need to be aware of the three layers of behavior change:&lt;/p&gt; 
&lt;ol&gt; 
 &lt;li&gt;Identity&lt;/li&gt; 
 &lt;li&gt;Process&lt;/li&gt; 
 &lt;li&gt;Outcome&lt;/li&gt; 
&lt;/ol&gt; 
&lt;p&gt;Identity is what you believe, process is what you do, and outcome is what you get. The reason most people fall short of their aspirations in life is that they are solely focused on outcomes, without considering the systems that lead to those outcomes. Telling yourself &quot;I want to get rich&quot; or &quot;I want to lose weight&quot; will not contribute to either. Only through modifying our identity and processes can we change our behavior and bring about our desired outcomes.&lt;/p&gt; 
&lt;p&gt;Your behaviors are an expression of your identity. If you exercise every day, you are an active person. If you watch Netflix all day, you are a lazy person. To change your outcomes, you must first change your identity and processes.&lt;/p&gt; 
&lt;p&gt;To change your identity, start by asking how someone with your desired identity behaves. If you want to become an entrepreneur, ask &quot;Who is the type of person that becomes an entrepreneur?&quot; An entrepreneur is the type of person who creates things. An entrepreneur is the type of person who is willing to fail. An entrepreneur is the type of person who takes risks for what they believe in. Start acting like your desired identity, and eventually, you will become them. Write every day and you will become a writer. Program every day and you will become a programmer. Every action you take is a vote for the type of person you wish to become.&lt;/p&gt; 
&lt;p&gt;As you&apos;ve likely noticed, just telling yourself you&apos;re going to start doing something is not an effective way to change your behavior. Our brains are energy conservation machines, constantly analyzing the environment for ways to maximize immediate rewards while spending as little energy as possible. Effective processes manipulate your environment so that the energy required for the desirable behavior is less than the energy required for the undesirable behavior. It&apos;s tough to eat healthier if your fridge is stocked full of chocolate bars. But by manipulating your environment such that your fridge is filled with fruit and vegetables and eating a Cadbury requires a trip to the supermarket, you&apos;ve suddenly tipped the scale in your favor. Every goal is doomed to fail if it goes against the grain of human nature.&lt;/p&gt; 
&lt;h3&gt;The Four Steps of Habit Formation&lt;/h3&gt; 
&lt;p&gt;There are four steps involved in the formation of every habit:&lt;/p&gt; 
&lt;ol&gt; 
 &lt;li&gt;Cue&lt;/li&gt; 
 &lt;li&gt;Craving&lt;/li&gt; 
 &lt;li&gt;Response&lt;/li&gt; 
 &lt;li&gt;Reward&lt;/li&gt; 
&lt;/ol&gt; 
&lt;p&gt;The cue is the initial signal that triggers the behavior (ex. the sight of a chocolate bar). The craving is the desired change in state that results from the cue (ex. a desire for the taste of chocolate). The response is the behavior that is performed to satisfy the craving (ex. eating the chocolate bar). The reward is the outcome delivered by the response (ex. the sugar rush from eating the chocolate bar). If a behavior is insufficient in any of the above steps, it will not become a habit. Remove the cue and the habit will never start. Reduce the craving and you won&apos;t be motivated enough to act. If you don&apos;t respond, there will be no reward. And if there is no reward, or it doesn&apos;t live up to your expectations, you won&apos;t repeat the behavior in the future.&lt;/p&gt; 
&lt;h3&gt;The Four Laws of Behavior Change&lt;/h3&gt; 
&lt;p&gt;The four laws of behavior change are a set of actionable principles for building habits. The laws are:&lt;/p&gt; 
&lt;ol&gt; 
 &lt;li&gt;Make it obvious&lt;/li&gt; 
 &lt;li&gt;Make it attractive&lt;/li&gt; 
 &lt;li&gt;Make it easy&lt;/li&gt; 
 &lt;li&gt;Make it satisfying&lt;/li&gt; 
&lt;/ol&gt; 
&lt;p&gt;Each law maps to one of the four steps of habit formation:&lt;/p&gt; 
&lt;ol&gt; 
 &lt;li&gt;Make it obvious → Cue&lt;/li&gt; 
 &lt;li&gt;Make it attractive → Craving&lt;/li&gt; 
 &lt;li&gt;Make it easy → Response&lt;/li&gt; 
 &lt;li&gt;Make it satisfying → Reward&lt;/li&gt; 
&lt;/ol&gt; 
&lt;h3&gt;Make it Obvious&lt;/h3&gt; 
&lt;p&gt;To effectively build a new habit, make the cue for that habit blatantly obvious. If you want to start running every morning, place your runners next to your bed the night before. When you wake up, the first thing you&apos;ll see is your sneakers, signaling to your brain that it&apos;s time to get active. If you want to build a habit of reading before bed, place a book on your pillow every morning. When it&apos;s time for bed, the book will be waiting for you. Design your environment around the habits you wish to develop. The more clear and consistent the cues in your environment, the more likely you will be to develop the habit associated with the cue.&lt;/p&gt; 
&lt;h4&gt;Implementation Intentions&lt;/h4&gt; 
&lt;p&gt;Implementation intentions are used to increase your likelihood of performing a habit. The idea behind implementation intentions is to eliminate ambiguity around when and where you will perform a habit. Instead of just telling yourself &quot;I&apos;m going to start running&quot;, grab a piece of paper and write down &quot;I will run at 7am in my neighborhood&quot;. The format of implementation intentions is:&lt;/p&gt; 
&lt;p&gt;I will [BEHAVIOUR] at [TIME] in/at [LOCATION]&lt;/p&gt; 
&lt;p&gt;Examples:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;I will write at 9 am in my home office&lt;/li&gt; 
 &lt;li&gt;I will play basketball at 6 pm at the University&lt;/li&gt; 
 &lt;li&gt;I will read at 9 pm on my balcony&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;Write down a list of implementation intentions for all the habits you wish to develop and place the list somewhere you&apos;ll see every day (ex. on your bedroom door or the lock screen of your phone).&lt;/p&gt; 
&lt;h4&gt;Habit Stacking&lt;/h4&gt; 
&lt;p&gt;Habit stacking is a technique in which you consistently perform some behavior immediately after another behavior. The technique leverages the Diderot effect: the human phenomenon where one purchase leads to another (ex. buying a new desk prompts you to get a new keyboard, mouse, and monitor), and attempts to apply it to habits. Habit stacking works by explicitly tieing behaviors together. Say you currently have the habit of making coffee every morning but also wish to develop a habit of writing. You would use habit stacking by affirming &quot;After I make coffee, I will sit down at my desk and write.&quot; The key behind habit stacking is to tie the desired behavior to something you already do. The format of habit stacking is:&lt;/p&gt; 
&lt;p&gt;After [CURRENT HABIT], I will [NEW HABIT]&lt;/p&gt; 
&lt;p&gt;Think of habit stacking as the connections between implementation intentions.&lt;/p&gt; 
&lt;h4&gt;Habit Scorecard&lt;/h4&gt; 
&lt;p&gt;You need to be aware of your habits before you can change them. The habit scorecard is a system for identifying and categorizing your existing habits as bad, neutral, or good. To create your scorecard, keep a pen and paper on you for an entire day and write down everything you do (ex. wake up, check phone, make coffee, shower, etc). At the end of the day, mark each behavior as either bad, neutral, or good.&lt;/p&gt; 
&lt;p&gt;Example:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Wake up - Neutral&lt;/li&gt; 
 &lt;li&gt;Check phone - Bad&lt;/li&gt; 
 &lt;li&gt;Make Coffee - Neutral&lt;/li&gt; 
 &lt;li&gt;Shower - Good&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;To determine whether or not a habit is good, ask yourself it&apos;s helping you become the type of person you wish to be.&lt;/p&gt; 
&lt;h4&gt;Make it Invisible&lt;/h4&gt; 
&lt;p&gt;To break a bad habit, remove the cues associated with that habit from your environment. This is an inversion of the first law of behavior change.&lt;/p&gt; 
&lt;p&gt;&quot;Make it obvious&quot; → &quot;Make it invisible&quot;&lt;/p&gt; 
&lt;p&gt;To watch less YouTube, uninstall the app from your phone. To eat less sugar, remove all the sweets from your fridge. The purpose of &quot;Making it invisible&quot; is to eliminate the times when a behavior is initialized without intent - unlocking your phone and mindlessly clicking the YouTube Icon or opening your fridge and catching your eye on the KitKat wrapper.&lt;/p&gt; 
&lt;h3&gt;The Behavior Function&lt;/h3&gt; 
&lt;p&gt;Behavior is a function of a person in their environment:&lt;/p&gt; 
&lt;p&gt;B = f(P,E)&lt;/p&gt; 
&lt;p&gt;Put more precisely, our behavior results from the combination of our personal traits and the environment we inhabit. We react differently than others to the same environment depending on our relationships with that environment. The living room couch could be where one person relaxes or where another does their most intellectually demanding work. When you try to develop a new habit in a familiar environment, you have to contend with the habits that you&apos;ve already developed in that environment. It&apos;s more difficult to develop a habit of reading in the area where you play video games than it is in a new environment that you&apos;ve yet to connotate with any habits. You can&apos;t easily modify the P in f(P,E), but you can change the E. Build new habits in new environments, and whenever possible, avoid mixing the environment of one habit with another.&lt;/p&gt; 
&lt;h4&gt;The Influence of Vision&lt;/h4&gt; 
&lt;p&gt;The average human has 11 million sensory receptors in their body, 10 million of which are dedicated to sight. Because of this, visual cues in our environment are the most effective at influencing our behavior. When designing your environment, make the cues for good habits highly visible and the cues for bad habits invisible. Supermarkets already leverage the influence of vision by placing brand name products with the highest margins at eye level, while hiding away their lower margin alternatives in hard to reach places. A small shift in what you see can lead to a big shift in what you do.&lt;/p&gt; 
&lt;h4&gt;Environment &amp;gt; Discipline&lt;/h4&gt; 
&lt;p&gt;During the Vietnam War it was discovered that 35% of US soldiers stationed in Vietnam had tried heroin and that 20% were addicted. However, upon returning to the US, only 5% became re-addicted within a year and only 12% relapsed within three years. This contradicted the commonly held belief at the time that heroin addiction was permanent and irreversible. State-side, 90% of heroin users become re-addicted when they return home from rehab. In the presence of a radically new environment devoid of the cues associated with their addiction, US soldiers quit heroin almost overnight.&lt;/p&gt; 
&lt;p&gt;&quot;Disciplined&quot; people do not possess heroic willpower and self-control. Instead, they structure their lives in a way that reduces their exposure to negative temptations. It&apos;s easier to practice self-restraint when you don&apos;t have to use it very often. Anyone can become &quot;Disciplined&quot; if they architect their environment in such a way that the cues associated with bad habits are invisible and the cues associated with good habits are clear and abundant. We all have a finite amount of willpower. The more you have to practice self-restraint, the less you will be able to resist the next temptation. Each act of self-restraint drains your tank of willpower. Instead of spending energy on self-restraint, invest in eliminating temptations from your environment. Self-control is a short-term strategy, environment design is a long-term one.&lt;/p&gt; 
&lt;h3&gt;Make it Attractive&lt;/h3&gt; 
&lt;p&gt;The second law of behavior change is &quot;Make it attractive&quot;. The more attractive an opportunity is, the more likely it will become habit-forming.&lt;/p&gt; 
&lt;h4&gt;The Outdated Utility of Dopamine&lt;/h4&gt; 
&lt;p&gt;Dopamine is the chemical in our brain that causes the feeling of pleasure. The pleasure from eating calorically dense foods and having sex motivated our ancestors to take actions that were essential for the survival of the human race. But we no longer live in a resource-scarce environment. We have the brains of our ancestors, but temptations that they could have never imagined. It&apos;s no surprise that over 40% of adults in the US are obese; food is abundant, yet our brains continue to crave it like it&apos;s scarce.&lt;/p&gt; 
&lt;h4&gt;Exaggerated Reality&lt;/h4&gt; 
&lt;p&gt;All animals, humans included, have certain behaviors wired into their brains through evolution. Baby herring gulls, for example, peck at the red spot on their parent&apos;s beak when they&apos;re hungry, signaling the parent to throw up food for the infant gull. Researchers found that exposing baby herring gulls to artificial beaks with extremely large red dots caused the infant gulls to peck like crazy. This is known as a supernormal stimuli, an exaggerated cue that elicits a strong reaction from the target creature. Modern industry is filled with supernormal stimuli that overwhelm our primitive instincts and motivate us to consume. Junk food has far more sugar than the naturally occurring foods that our brain&apos;s reward system evolved on. Video games have more visual and auditory stimulus than one would ever encounter in the wild. The modern environment is filled with exaggerated versions of reality that overwhelm our senses.&lt;/p&gt; 
&lt;h4&gt;Anticipation Drives Action&lt;/h4&gt; 
&lt;p&gt;Habits are dopamine-driven feedback loops. During the four steps involved with habit formation (cue, craving, response, reward), we experience two dopamine spikes, one during the craving phase and one during the reward phase. It&apos;s the dopamine spike that occurs during the craving phase that motivates us to act. The anticipation of the reward drives us to action, not the reward itself. Additionally, our brains have more neural circuitry allocated for wanting rewards than actually liking rewards. This is why the thought of Christmas morning as a child is more enjoyable than the morning itself, and why the research you perform on a product you want to buy brings you more enjoyment than the product itself.&lt;/p&gt; 
&lt;h4&gt;Temptation Bundling&lt;/h4&gt; 
&lt;p&gt;Temptation bundling is a strategy that leverages the motivating powers of anticipation in order to maximize the likelihood of performing good habits. Some habits, like eating healthy or reading, have lackluster immediate rewards. With temptation bundling, you follow-up a good habit with a habit that you enjoy, causing your brain to associate the good habit with the reward of the enjoyable habit. When performed enough times, you&apos;ll experience a dopamine spike in the craving phase of your good habit in anticipation of the reward from the enjoyable habit that follows. For example, only listening to podcasts at the gym will associate the good habit of exercise with the enjoyable habit of listening to your favorite podcast. Temptation bundling generally has the form of:&lt;/p&gt; 
&lt;p&gt;After [HABIT I NEED], I will [HABIT I WANT].&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;After I get on the spin bike, I will start listening to my favorite podcast.&lt;/li&gt; 
 &lt;li&gt;After I finish all my homework, I will play my favorite video game.&lt;/li&gt; 
 &lt;li&gt;After I open the book I&apos;m reading, I will drink a cup of coffee.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Leverage the desire to belong&lt;/h4&gt; 
&lt;p&gt;Humans are social creatures with an innate desire for belonging. This innate desire is an artifact of our evolution as a species; early humans that belonged to a group had a far greater chance of survival than the lone wolf. We communicate this desire for belonging through imitation. In particular, we imitate three groups of people&lt;/p&gt; 
&lt;ol&gt; 
 &lt;li&gt;The close (friends and family)&lt;/li&gt; 
 &lt;li&gt;The many (people in our society)&lt;/li&gt; 
 &lt;li&gt;The powerful (people with status and prestige)&lt;/li&gt; 
&lt;/ol&gt; 
&lt;p&gt;The first group we imitate are those closest to us. As an infant, you copy the sounds your parents make, as a child, you copy how your peers play with one another, and as an adult, you copy how your colleagues work. The closer you are to someone, the more likely you will be to imitate their behaviors. As Jim Rohn says &quot;You are the average of the five people you spend the most time with.&quot;&lt;/p&gt; 
&lt;p&gt;One study that tracked 12 thousand people for 32 years found that the chances of someone becoming obese increased by 57% if they had a friend who become obese. On the other end of the spectrum, groups of exceptional people often achieve disproportionately exceptional results. A few such examples include the friendship of Warren Buffet and Charlie Munger, brothers Patrick and John Collison, and the Paypal Mafia. One of the most effective things you can do to build better habits is to join a culture where your desired behavior is the normal behavior. Surround yourself with people who already have the habits that you&apos;re trying to develop.&lt;/p&gt; 
&lt;p&gt;The second group we imitate is society as a whole. This large-scale imitation can be observed through the fashion trends or popular music of a certain era. Humans have a strong urge to conform to the behaviors and preferences of the masses. A famous experiment that illustrates the pressures of social conformity was performed by psychologist Solomon Asch. In the experiment, a test subject would unknowingly be placed in a room full of actors, where they would be given 2 cards with lines of various lengths. The subjects were then asked to identify which line on the right card had the same length as the line on the left card.&lt;/p&gt; 
&lt;p&gt;&lt;img src=&quot;https://upload.wikimedia.org/wikipedia/commons/thumb/d/d3/Asch_experiment.svg/270px-Asch_experiment.svg.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt; 
&lt;p&gt;The actors would purposely select the wrong answer (B). When the test subject was in the room with one other actor, they would select the correct answer, even after seeing the actor&apos;s incorrect selection. But as the number of actors increased, all of whom selected the same wrong answer, the subject would begin to also select the wrong answer in order to conform. The lesson learned from this experiment is that the normal behavior of the tribe often overpowers the desired behavior of the individual. We will do or say something we know to be wrong in order to fit in. We do this because the reward to fit in is often greater than the reward of being right.&lt;/p&gt; 
&lt;p&gt;The last group of people we imitate is the powerful. We do so in hopes that our imitation will bring about the prestige and power that this group possesses. The desire for prestige and power is again rooted in our evolution as a species; individuals with more power and status have historically had greater access to resources, and thus had a greater chance of survival and finding a mate. If a behavior can get us approval, respect, and praise, we find it attractive.&lt;/p&gt; 
&lt;h4&gt;Underlying Motives&lt;/h4&gt; 
&lt;p&gt;Every behavior has a surface-level craving and a deeper underlying motive. For example, a surface-level craving could be &quot;I want a piece of pizza&quot;. The underlying motive for this craving is the desire to obtain food and water. Other underlying motives of human behavior include:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Conserve energy&lt;/li&gt; 
 &lt;li&gt;Find love and reproduce&lt;/li&gt; 
 &lt;li&gt;Connect and bond with others&lt;/li&gt; 
 &lt;li&gt;Win social acceptance and approval&lt;/li&gt; 
 &lt;li&gt;Reduce uncertainty&lt;/li&gt; 
 &lt;li&gt;Achieve status and prestige&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;Our cravings are just arbitrary manifestations of a deeper underlying motive. Our brains didn&apos;t evolve with a desire to smoke cigarettes or to check Instagram or to play video games. These are simply manifestations of our underlying motives to reduce uncertainty, win social acceptance and approval, or achieve status and prestige. Modern-day products don&apos;t create new motivations, they latch onto the underlying motives of human behavior.&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Find love and reproduce = Using Tinder&lt;/li&gt; 
 &lt;li&gt;Connect and bond with others = Browsing Facebook&lt;/li&gt; 
 &lt;li&gt;Win social acceptance and approval = Posting on Instagram&lt;/li&gt; 
 &lt;li&gt;Reduce uncertainty = Searching on google&lt;/li&gt; 
 &lt;li&gt;Achieve status and prestige = Playing video games&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;Our habits are modern solutions to ancient desires.&lt;/p&gt; 
&lt;h4&gt;Predictive, Not Reactive&lt;/h4&gt; 
&lt;p&gt;Our behavior is heavily dependent on how we interpret the events that happen to us, not necessarily the objective reality of the events themselves. Two people may experience the exact same event but react in entirely different ways. This is because right before reacting to the event, the two individuals make different predictions on the outcome of their actions. These predictions are based on their past experiences and world-views. In response to being offered a cigarette, one person may predict that smoking it will relieve their anxiety, while the other may predict that it will create a foul odor and increase their odds of getting lung cancer. The difference in these two predictions is what causes one individual to smoke and the other not to.&lt;/p&gt; 
&lt;h4&gt;Make it Unattractive&lt;/h4&gt; 
&lt;p&gt;The inversion of the second law of behavior change is to &quot;make it unattractive&quot;. To break a bad habit, you need to eliminate the craving for that bad habit. This can be done in one of two ways:&lt;/p&gt; 
&lt;ol&gt; 
 &lt;li&gt;Exposing how the bad habit inadequately addresses the underlying motive that caused its formation.&lt;/li&gt; 
 &lt;li&gt;Replacing the bad habit with a good habit that more effectively addresses the underlying motive.&lt;/li&gt; 
&lt;/ol&gt; 
&lt;p&gt;As mentioned previously, habits are just attempts to address the underlying motives of human behavior. To break a bad habit, analyze how the behavior associated with a bad habit inadequately addresses the underlying motive. For example, someone who smokes to calm their nerves may analyze their habit and realize that smoking does not relieve their nerves, it destroys them. Clearly describe the negative consequences of your bad habits to make them as unattractive as possible. In addition, find a good habit that addresses the same underlying motive as the bad habit. In the case of smoking to calm one&apos;s nerves, a healthy alternative could be running, which increases one&apos;s physical fitness and cardiovascular health.&lt;/p&gt; 
&lt;h4&gt;How To Enjoy Hard Habits&lt;/h4&gt; 
&lt;p&gt;Simple shifts in mindset can have profound effects on how we interpret the world. Instead of telling yourself that you &quot;have to&quot; do a hard habit, tell yourself that you &quot;get to&quot; do a hard habit. This simple shift in words changes your interpretation of the habit, highlighting how the difficult behavior is an opportunity instead of a burden. Telling yourself &quot;I have to go to the gym&quot; subtly implies that going to the gym is an inconvenient and painful experience. But telling yourself &quot;I get to go to the gym&quot; implies that going to the gym is a positive opportunity to improve one&apos;s own health and physique.&lt;/p&gt; 
&lt;p&gt;&quot;I have to&quot; → &quot;I get to&quot;&lt;/p&gt; 
&lt;h3&gt;Make it Easy&lt;/h3&gt; 
&lt;p&gt;The third law of behavior change is &quot;Make it easy.&quot; Easy behaviors require less motivation to act and are more likely to be performed consistently.&lt;/p&gt; 
&lt;h4&gt;Quantity Over Quality&lt;/h4&gt; 
&lt;p&gt;A professor at the University of Florida divided his photography class into two groups: the quality group and the quantity group. The quantity group was told that they would be graded solely on the amount of work they produced. The more photos they took, the higher the grade they would receive. The quality group was told that they would be graded solely on the excellence of their work. This group only needed to produce a single image for the entire semester. At the end of the semester, the professor was surprised to find that all of the highest quality photos had been submitted by the quantity group. Throughout the semester, the quantity group was constantly experimenting with different techniques, incrementally improving the quality of the photos they captured. Meanwhile, the quality group sat around speculating about what the perfect photo might look like. The iterative technique of the quantity group produced far greater results than the speculation and theorizing of the quality group. If you want to master a habit, the key is to start with repetition, not perfection.&lt;/p&gt; 
&lt;p&gt;&quot;The best is the enemy of the good.&quot; - Voltaire&lt;/p&gt; 
&lt;h4&gt;Motion vs Action&lt;/h4&gt; 
&lt;p&gt;Motion is when you&apos;re planning, strategizing, or learning. Action is when you&apos;re performing a behavior that actually delivers results. Reading a book on programming is motion. Actually programming is action. Researching effective core workouts is motion. Working out is action. We&apos;re attracted to motion because it gives us the illusion of progress without the risk of failure. Action is more difficult than motion, but it&apos;s also more rewarding.&lt;/p&gt; 
&lt;h4&gt;Neuroplasticity&lt;/h4&gt; 
&lt;p&gt;Neurons that fire together wire together - Hebb&apos;s Law&lt;/p&gt; 
&lt;p&gt;The more you repeat an activity, the more the structure of your brain changes to become efficient at that activity. This is because of a phenomenon known as neuroplasticity: the brain&apos;s ability to modify and adapt both structure and function in response to experiences. As you repeat some behavior, the connections between the neurons associated with that behavior strengthen. This repetition leads to clear physical changes in the brain. For example, the cerebellum (a component of the brain that&apos;s critical for precise muscle movements) is much larger in musicians than in non-musicians.&lt;/p&gt; 
&lt;h4&gt;How long does it take to build a new habit?&lt;/h4&gt; 
&lt;p&gt;Habits are formed through repetitions, not time. The amount of time you&apos;ve been performing a habit is less important than how many times you&apos;ve performed the habit. There will come a point where you&apos;ve performed so many repetitions of a particular behavior that you no longer have to think about each step involved. This is known as the point of automaticity. Reaching the point of automaticity, and thus forming a habit, is dependent on how many repetitions you&apos;ve performed, not how long you&apos;ve been performing them.&lt;/p&gt; 
&lt;h4&gt;The Law of Least Effort&lt;/h4&gt; 
&lt;p&gt;Our brains are energy conservation machines, constantly searching for ways to minimize the amount of effort they expend. When deciding between two similar options, people will naturally gravitate towards the easier one. Our brains have evolved to preserve energy and avoid expenditure whenever possible. This is why telling yourself to just &quot;try harder&quot; is rarely effective for developing new habits; It goes against the grain of human nature.&lt;/p&gt; 
&lt;h4&gt;Eliminate Friction&lt;/h4&gt; 
&lt;p&gt;Every habit is an obstacle to getting what you really want. Exercising is an obstacle to getting fit. Writing is an obstacle to thinking clearly. You don&apos;t want the habit itself, you want what the habit delivers. The greater the obstacle, the more friction there is between you and your desired state. The key to building new habits is reducing this friction as much as possible. Trying to perform hard habits by increasing your motivation is like trying to force more water through a bent hose. Instead, design your environment to reduce the friction associated with performing your habits, unbending the hose. You&apos;re more likely to start working out if you join a gym that&apos;s on the way to work. You&apos;re more likely to eat healthier if your fridge is filled with meat and vegetables, whilst being void of sugar. Removing the friction associated with your habits allows you to do more with less time and effort. Think addition by subtraction.&lt;/p&gt; 
&lt;h4&gt;Prime for next use&lt;/h4&gt; 
&lt;p&gt;Prepare your environment for performing a particular habit ahead of time. If you want to start going to the gym every morning, pack your bag the night before. If you want to eat healthier, wash and pre-cut your fruits and vegetables. If you want to read before bed, place a book on your pillowcase every morning. Preparing your environment for the performance of a habit serves as both a reminder and a mechanism for making the habit as convenient as possible.&lt;/p&gt; 
&lt;h4&gt;Decisive Moments&lt;/h4&gt; 
&lt;p&gt;Every day we encounter decisive moments that deliver an outsized impact. Choosing to order takeout or to cook dinner. Choosing to go to the gym or to stay home and watch tv. Choosing to study or to play video games. These split-second decisions result in outcomes that consume hours of our time and drastically change the course of our days. The difference between a good day and a bad day is the result of the choices we make during decisive moments.&lt;/p&gt; 
&lt;h4&gt;The 2 Minute Rule&lt;/h4&gt; 
&lt;p&gt;When you start a new habit, it should take 2 minutes or less. We often overcommit to new habits from the get-go. We promise ourselves that we&apos;re going to run 5k a day, or read for an hour. But when the time rolls around to perform our new habit, we feel overwhelmed by the lofty goals we&apos;ve set for ourselves, and end up doing nothing at all. The 2 minute rule solves this problem by leveraging the fact that it&apos;s easier to continue what you&apos;re doing than to start something new. The hardest part of performing a new behavior is starting it. By making your new habit as small as possible, you increase the likelihood of performing the habit in the first place. Instead of committing to an hour of reading each day, commit to a page. You&apos;ll be more likely to start reading, and will inevitably read more. Remember that something is better than nothing. Doing 10 pushups is better than doing none at all. Reading 1 page is better than reading 0. Action, no matter how small, is infinitely superior to inaction.&lt;/p&gt; 
&lt;h4&gt;Ritualize The Process&lt;/h4&gt; 
&lt;p&gt;The more you ritualize the beginning of a process, the more likely you are to slip into a state of focus for performing the process. Examples of this include basketball players who perform the same dribbling ritual before every free throw.&lt;/p&gt; 
&lt;h4&gt;Make it Difficult&lt;/h4&gt; 
&lt;p&gt;&quot;Sometimes success is less about making good habits easy and more about making bad habits hard.&quot; - James Clear&lt;/p&gt; 
&lt;p&gt;The inversion of the third law of behavior change is to &quot;Make it Difficult&quot;. Make your bad habits difficult by using commitment devices: actions you take in the present that control how you behave in the future. A good example of a commitment device is to pay in advance, incentivizing you to follow through with whatever service you paid for since not doing so has an associated cost.&lt;/p&gt; 
&lt;h4&gt;Onetime actions with longtime rewards&lt;/h4&gt; 
&lt;p&gt;There exists some onetime actions you can take that produce consistent long-term rewards. Here are a few examples:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Buying smaller plates to reduce caloric intake&lt;/li&gt; 
 &lt;li&gt;Purchasing a comfortable mattress to increase sleep quality&lt;/li&gt; 
 &lt;li&gt;Installing blackout curtains to increase sleep quality&lt;/li&gt; 
 &lt;li&gt;Turning off notifications to reduce distractions&lt;/li&gt; 
 &lt;li&gt;Getting a dog to increase companionship in your life&lt;/li&gt; 
 &lt;li&gt;Asking service providers to lower your bills to save money&lt;/li&gt; 
 &lt;li&gt;Buying a high-quality chair or standing desk to improve your posture&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;Taking as many of these actions as possible is an easy way to positively impact your future self.&lt;/p&gt; 
&lt;h3&gt;Make it Satisfying&lt;/h3&gt; 
&lt;p&gt;The fourth law of behavior change is to &quot;Make it Satisfying&quot;. You&apos;re more likely to repeat a behavior if the experience is pleasurable. The previous three laws, &quot;Make it obvious&quot;, &quot;Make it attractive&quot; and &quot;Make it easy&quot; increase the likelihood of a behavior being performed. The fourth law increases the likelihood of a behavior being repeated.&lt;/p&gt; 
&lt;h4&gt;Immediate-return environment to delayed-return environment&lt;/h4&gt; 
&lt;p&gt;Humans have been around for approximately 200 thousand years. And for the first 195 thousand of those years (97.5% of our existence), we inhabited an immediate-return environment. Our thoughts and actions were focused exclusively on the present. Our primary concerns revolved around what to eat, where to sleep, and how to avoid predators. Our wild environment necessitated an intense focus on the immediate results of our actions. But in the last 5 thousand years, civilizations were born and we transitioned to a delayed-return environment. An environment where the rewards of our actions may not be delivered for days, weeks, months, or even years. We work today but don&apos;t get paid for 2 weeks. We study now but don&apos;t graduate for 4 years. Innovation in science and technology has minimized our risk of immediate peril and made acting on behalf of our future selves a necessity. The problem is that this environmental change from an immediate-return environment to a delayed-return environment has happened faster than our brains can adapt. We have evolved to prefer rewards that are guaranteed in the present over possible rewards in the future. This is why relying on willpower alone to make the right decision doesn&apos;t work. It&apos;s human nature to gravitate towards the choice that delivers immediate satisfaction.&lt;/p&gt; 
&lt;h4&gt;The Paradox of Instant Gratification&lt;/h4&gt; 
&lt;p&gt;Bad habits almost always feel good in the moment but bad in the future. Conversely, good habits often feel difficult in the moment but good in the future. It feels good to get drunk on Friday night, but the morning that follows is absolutely dreadful. A hard workout may be difficult in the moment, but it leaves you feeling calm and revitalized afterwards. Always be suspicious of immediately pleasurable behaviors, for they are likely to be detrimental in the long term. From the wise words of Frédéric Bastiat &quot;It almost always happens that when the immediate consequence is favorable, the later consequences are disastrous, and vice versa..&quot;&lt;/p&gt; 
&lt;h4&gt;The Road Less Traveled&lt;/h4&gt; 
&lt;p&gt;The abundance of resources in modern society coupled with the advent of the smartphone has turned most of us into hopeless dopamine fiends. We constantly seek instant gratification in the form of sugary snacks or likes on social media and our environment is capable of providing both indefinitely. But the road less traveled, and far more rewarding, is the road of delayed gratification. Individuals who can tolerate delayed gratification are better at responding to stress, have lower levels of substance abuse, and are less likely to become obese. The road less traveled is the one that requires persevering through the struggles of the present, knowing that they&apos;ll make you better off in the future.&lt;/p&gt; 
&lt;h4&gt;Treat Yourself&lt;/h4&gt; 
&lt;p&gt;Some of the most powerful habits, like reading and exercise, can take months to deliver noticeable results. To combat demotivation and prolong your patience, end your difficult habits with a behavior you find satisfying. An example could be rewarding yourself with a delicious smoothie after a hard workout. The only thing to keep in mind is that the reward should reinforce the identity that is associated with the habit. A healthy smoothie reinforces the identity created by working out: a healthy person. But if you were to end your hard workouts with a Big Mac, you&apos;d be conflicting your desired identities. This self-rewarding will only be necessary until you start to reap the long-term rewards of your good habits. The improved aesthetic and increased wellbeing that comes after months of exercising will be satisfying enough to maintain the habit, without the reward of a smoothie.&lt;/p&gt; 
&lt;h4&gt;Track Your Progress&lt;/h4&gt; 
&lt;p&gt;Progress is the most effective form of motivation. Use a habit tracking app to track your progress and maintain motivation for your habits. The visual indicators in habit tracking applications make progress more enjoyable. Whether it be the flaming streak in Duolingo or the checkmarks in your habit tracker, these subtle visual cues make the act of performing and maintaining a habit more satisfying. Habit tracking applications also act as motivation for days where you don&apos;t feel like performing the habit since doing so would end your streak or pause your progress. Lastly, habit tracking shifts your focus from the end goal to the process that will get you there.&lt;/p&gt; 
&lt;h4&gt;Never Miss Twice&lt;/h4&gt; 
&lt;p&gt;A simple mental trick for maintaining habits is to tell yourself that you&apos;ll never miss twice. Life is full of surprises and we will inevitably miss performing our habits one day. The trick is to not let this slip up get you down. Habit building is not an all-or-nothing endeavor. When you miss a habit, focus on rebounding as soon as possible. It&apos;s okay to miss a workout every once and a while, just don&apos;t miss two in a row.&lt;/p&gt; 
&lt;h4&gt;Bad &amp;gt; None&lt;/h4&gt; 
&lt;p&gt;A bad workout is infinitely better than no workout at all. In fact, the days where you perform a habit when you don&apos;t feel like it are the most valuable. By doing so you are identifying as the type of person who performs habit X through thick and thin. Anyone can work out when they&apos;re well-rested and feeling energized. But it takes a special commitment to hit the gym on 2 hours of sleep. Cherish the days where you don&apos;t feel like performing a habit, for they provide an opportunity to strengthen your desired identity like no other.&lt;/p&gt; 
&lt;h4&gt;Naïve Metrics&lt;/h4&gt; 
&lt;p&gt;&quot;When a measure becomes a target, it ceases to be a good measure&quot; - Charles Goodhart. When it comes to tracking habits, keep the bigger picture in mind. If you become too obsessed with the metric you&apos;ve chosen to track your progress, you might lose sight of why you&apos;re doing the habit in the first place. Choosing weight as a measurement of health could have inadvertent effects, particularly if you engage in unhealthy behaviors like taking fat-loss pills or starving yourself to lose weight. Remember why you&apos;re doing performing a habit in the first place and don&apos;t get too obsessed with the metrics.&lt;/p&gt; 
&lt;h4&gt;Make it Unsatisfying&lt;/h4&gt; 
&lt;p&gt;The inversion of the fourth law of behavior change is to make it unsatisfying. The more painful a behavior the more likely we are to avoid it. The trick to stopping our bad habits is to make their consequences occur as soon as possible, be clearly visible, and be more painful than their worth. Imagine if you were instantly issued a speeding ticket every time you sped. This would surely squash your habit of joyriding, as the cost of the ticket would far outweigh the momentary thrill of speeding.&lt;/p&gt; 
&lt;h4&gt;Accountability Partners&lt;/h4&gt; 
&lt;p&gt;Create clear and immediate consequences for your bad habits through the use of a habit contract. A habit contract is a written or verbal agreement in which you state your commitment to a particular habit and the punishment that will occur if you don&apos;t follow through with it. Get a friend or family member to sign off on the contract with you and hold you accountable. If the habit contract seems overly formal, try to at least find an accountability partner who will challenge you to stick to your habits. Knowing that you&apos;re being monitored and judged can be a powerful motivator.&lt;/p&gt; 
&lt;h4&gt;Listen to Yourself&lt;/h4&gt; 
&lt;p&gt;We all have different natural abilities and inclinations. The most important piece of advice when building new habits is to pick habits that you want to develop, not one&apos;s that you&apos;re told you should develop. Almost every goal has different variations of habits that lead to it. You will be most likely to develop and stick to a habit if you shape it to match your inclinations. For example, say you want to get fit and you enjoy rock climbing but hate lifting weights. You&apos;ll be much more likely to achieve and maintain the habit you enjoy, rock climbing, than the one you dislike, weightlifting. Pick the right habit and progress is easy, pick the wrong habit and life is a struggle.&lt;/p&gt; 
&lt;h4&gt;How to find your habits&lt;/h4&gt; 
&lt;p&gt;Habits that are aligned with your natural inclinations will be easier to develop and more enjoyable to practice. To find these habits, try answering the following questions:&lt;/p&gt; 
&lt;ol&gt; 
 &lt;li&gt; &lt;p&gt;What feels like fun to me but like work to others?&lt;br&gt; Enjoying a habit is the biggest indicator that it aligns with your natural inclinations. If you enjoy a habit that feels like work to others, you&apos;ll likely excel in the domain associated with that habit. It&apos;s extremely difficult to compete with someone who&apos;s having fun.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;What makes me lose track of time?&lt;br&gt; Losing track of time when engaged in a behavior is an indication that you&apos;ve entered a state of flow. It&apos;s nearly impossible to enter this state if you don&apos;t find the task at least moderately satisfying.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt;Where do I experience greater returns than the average person?&lt;br&gt; We constantly compare and contrast our outcomes with those around us. If your progress in a domain is greater than that of your peers, you&apos;re going to feel motivated and be more likely to stick with and excel in that domain.&lt;/li&gt; 
 &lt;li&gt;What comes natural to me?&lt;br&gt; What&apos;s the first thought that came to your mind after reading the above question?&lt;/li&gt; 
&lt;/ol&gt; 
&lt;h4&gt;Escape competition by combining your interests&lt;/h4&gt; 
&lt;p&gt;If you&apos;re unable to find a domain that caters to your natural inclinations, create one. Scott Adams, the creator of the comic series Dilbert, combined his above-average drawing skills with his above-average comedian skills to develop an exceptional skill of creating funny comics. Adams attributes the profound success of Dilbert to the unique intersection of comedy and art.&lt;/p&gt; 
&lt;p&gt;The modern environment is incredibly competitive. Almost every mainstream domain is populated with millions of competitors fighting for supremacy. Instead of trying to win at one of these ultra-competitive domains, escape competition by combining your skills to create a new domain. You are far more likely to succeed at the intersection of your two favorite hobbies than either one alone. And the rarer the combination, the greater the odds your work will stand out.&lt;/p&gt; 
&lt;h4&gt;The Goldilocks Zone&lt;/h4&gt; 
&lt;p&gt;We experience maximum motivation when the task we are performing is just on the outskirts of what we&apos;re capable of doing. If the task is too easy, well quickly become bored and demotivated. If the task is too difficult, we&apos;ll feel overwhelmed and quit. The key to sustaining motivation is to take on tasks that lie in the middle, in the &quot;Goldilocks Zone&quot;. As you practice and improve you&apos;ll need to constantly adjust the goldilocks zone to sustain the challenge and prevent things from becoming too easy, whilst also not over-adjusting to make them too hard.&lt;/p&gt; 
&lt;h4&gt;Embrace boredom&lt;/h4&gt; 
&lt;p&gt;The greatest threat to success is boredom, not failure. To fail you have to be acting and thus, making progress. But what follows boredom is inaction, and with inaction progress is impossible. No matter how much you enjoy a particular habit there will come days where you don&apos;t feel like doing it. One day-off quickly turns into a week, which then cascades into a month. The difference between professionals and amateurs is that professionals show up every day, even when they don&apos;t feel like it, even when they&apos;re bored. To become truly great at something you have to embrace boredom.&lt;/p&gt; 
&lt;h4&gt;Avoiding Complacency&lt;/h4&gt; 
&lt;p&gt;It&apos;s easy to become complacent once you&apos;ve reached the point of automaticity with a habit. But if you wish to attain and maintain mastery in any domain, you&apos;ll need to continually improve. Studies have shown that once an individual masters a skill, their performance declines over time. This is because they can now perform the skill on autopilot and are no longer cognoscente of whether or not they are actually performing the skill optimally. For example, you may have mastered the skill of dribbling a basketball and can do so without thinking about it, but over time you may begin to use your palm instead of the pads of your fingers, limiting your overall control of the ball. To master a domain and avoid complacency, you need to reflect on and review your performance, and to reflect and review, you need to measure your outcomes. It takes effort to record your performance and periodically reflect on it, but it is often the distinguishing factor between those who continually develop and those who plateau.&lt;/p&gt; 
&lt;h4&gt;Keep Your Identity Small&lt;/h4&gt; 
&lt;p&gt;The more you let your beliefs define you, the less adaptive you&apos;ll be to change. Life is full of surprises and you never know when unforeseen circumstances alter what you can and can&apos;t do. If your identity is brittle, changes beyond your control may break you. If your main identity is being a programmer and new developments in artificial intelligence render human programmers obsolete, you&apos;ll have an identity crisis. Instead of identifying with your particular role, identify with the fundamental aspects of your role. &quot;I&apos;m a programmer&quot; becomes &quot;I&apos;m a problem solver&quot;. The more fundamental and wide-reaching your identity is, the less susceptible it is to change.&lt;/p&gt; 
&lt;p&gt;&quot;Men are born soft and supple; dead, they are stiff and hard. Plants are born tender and pliant; dead, they are brittle and dry. Thus whoever is stiff and inflexible is a disciple of death. Whoever is soft and yielding is a disciple of life. The hard and stiff will be broken. The soft and supple will prevail.&quot; --Lao Tzu&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Crucial Conversations</title>
      <link>https://tedneward.github.io/Research/thinking/crucial-conversations/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">thinking/crucial-conversations/index.html</guid>
      	<description>
	&lt;p&gt;&lt;em&gt;(by Kerry Patterson, Joseph Grenny, Ron McMillan, and Al Switzler)&lt;/em&gt;&lt;/p&gt; 
&lt;h3&gt;Chapter 1: What is a Crucial Conversation?&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;Crucial conversations are when opinions vary, stakes are high, and emotions run strong.&lt;/li&gt; 
 &lt;li&gt;Such conversations have results that can have a huge impact on your quality of life.&lt;/li&gt; 
 &lt;li&gt;When we face crucial conversations, we can avoid them, or we can face them and handle them poorly, or we can face them and handle them well.&lt;/li&gt; 
 &lt;li&gt;Countless generations of genetic shaping drive us to handle crucial conversations with flying fists and fleet feet, not intelligent persuasion and gentle attentiveness.&lt;/li&gt; 
 &lt;li&gt;Such conversations are extraordinarily difficult also because they are spontaneous, are difficult to rehearse for, and cause us to act in self-defeating ways.&lt;/li&gt; 
 &lt;li&gt;The Law of Crucial Conversations says that the key skill of effective leaders, teammates, parents, and loved ones is the capacity to skillfully address emotionally and politically risky issues.&lt;/li&gt; 
 &lt;li&gt;In the workplace, the individuals who are the most influential, or who can get things done and at the same time build on relationships, are those who master their crucial conversations.&lt;/li&gt; 
 &lt;li&gt;Most leaders think organizational productivity and performance are simply about policies, processes, structures, or systems. But really it&apos;s about employee behavior, where crucial conversations beget accountability.&lt;/li&gt; 
 &lt;li&gt;In every relationship, the partners argue about important issues; but not everyone breaks up. It&apos;s how you argue that matters.&lt;/li&gt; 
 &lt;li&gt;People fall into three categories: Those who digress into threats and name-calling, those who revert to silent fuming, and those who speak openly, honestly, and effectively.&lt;/li&gt; 
 &lt;li&gt;The negative feelings we hold in, the emotional pain we suffer, and the constant battering we endure as we stumble our way through unhealthy conversations slowly eat away at our health.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Chapter 2: Mastering Crucial Conversations&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;Those who master crucial conversations avoid the Fool&apos;s Choice, where we think we must choose between telling the truth and keeping a friend, or between candor and kindness.&lt;/li&gt; 
 &lt;li&gt;When it comes to risky, controversial, and emotional conversations, skilled people find a way to get all relevant information out into the open. We call this free flow of meaning dialogue.&lt;/li&gt; 
 &lt;li&gt;Our opinions, feelings, theories, and experiences of a topic fill our personal pool of meaning. People who are skilled at dialogue do their best to make it safe for everyone to add their meaning to the shared pool.&lt;/li&gt; 
 &lt;li&gt;As the pool of shared meaning grows, it exposes individuals to more accurate and relevant information, and so they make better choices. It is a measure of the group&apos;s intelligence.&lt;/li&gt; 
 &lt;li&gt;The pool of shared meaning is also the birthplace of synergy. From a free flow of meaning, we can create a whole that is truly greater than the sum of its original parts.&lt;/li&gt; 
 &lt;li&gt;Because the meaning is shared, and everyone takes part in the free flow of meaning, people act on whatever decisions they make with both unity and conviction.&lt;/li&gt; 
 &lt;li&gt;The time you spend up front establishing a shared pool of meaning is more than paid for by faster, more unified, and more committed action later on.&lt;/li&gt; 
 &lt;li&gt;Whenever we find ourselves arguing, debating, running away, or otherwise acting in an ineffective way, it&apos;s because we don&apos;t know how to share meaning.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Chapter 3: Start with Heart&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;The first step of achieving the results that we really want is to fix the problem of believing that others are the source of all that ails us.&lt;/li&gt; 
 &lt;li&gt;People who are best at dialogue realize that the only person we can continually inspire, prod, and shape with any degree of success is the person in the mirror.&lt;/li&gt; 
 &lt;li&gt;Skilled people Start with Heart; that is, they begin high-risk discussions with the right motives, and they stay focused no matter what happens.&lt;/li&gt; 
 &lt;li&gt;These people maintain focus by: sticking with their goals and what they want; and not making Fool&apos;s Choices, and so they believe that dialogue is an option regardless of the circumstances.&lt;/li&gt; 
 &lt;li&gt;When faced with pressure and strong opinions, we often stop worrying about the goal of adding to the pool of meaning and start looking for ways to win, punish, or keep the peace.&lt;/li&gt; 
 &lt;li&gt;Our motives usually change without any conscious thought on our part. To move back to motives that allow for dialogue, we must step away from the interaction and look at ourself.&lt;/li&gt; 
 &lt;li&gt;Ask what you want for yourself, what you want for others, and what you want for the relationship. Then ask how you would behave if you really wanted those results.&lt;/li&gt; 
 &lt;li&gt;These questions remind us of our goal and original purpose, and also affect our physiology by sending blood to the brain which in turn keeps us focused.&lt;/li&gt; 
 &lt;li&gt;Restructure the Fool&apos;s Choice: Clarify what you don&apos;t want, add it to it what you do want, and then begin searching for healthy options to bring you to dialogue.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Chapter 4: Learn to Look&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;We have trouble watching both content and conditions in a crucial conversation: We are so caught up in what we&apos;re trying to say that we don&apos;t see what&apos;s happening to ourselves and others.&lt;/li&gt; 
 &lt;li&gt;In a conversation, look for the moment when it turns crucial, signs that people don&apos;t feel safe (silence or violence), and your own Style under Stress.&lt;/li&gt; 
 &lt;li&gt;To spot when a conversation turns crucial, look to yourself for a physical signal, a change in emotions, or a behavioral cue.&lt;/li&gt; 
 &lt;li&gt;People who are gifted at dialogue keep a constant vigil on safety. They pay attention to the content and they watch for signs that people are becoming fearful.&lt;/li&gt; 
 &lt;li&gt;Dialogue calls for the free flow of meaning, and nothing stops the flow of meaning like fear. Fear can cause you to both push too hard and to withdraw.&lt;/li&gt; 
 &lt;li&gt;People rarely become defensive because of what you&apos;re saying, but moreso because they no longer feel safe. The problem is not the content of your message, but the condition of the conversation.&lt;/li&gt; 
 &lt;li&gt;Watching for safety violations allows you to restore the peripheral vision that narrows when you feel genuinely threatened, and to reengage your brain and its centers of higher reasoning.&lt;/li&gt; 
 &lt;li&gt;Do not allow the actions of those who feel unsafe to beget fight or flight. Instead, recode the signs of violence or silence that people feel unsafe, and do something to create safety.&lt;/li&gt; 
 &lt;li&gt;Silence is characterized by &lt;em&gt;masking&lt;/em&gt; (such as sarcasm, sugarcoating, or couching), &lt;em&gt;avoiding&lt;/em&gt; sensitive subjects, or &lt;em&gt;withdrawing&lt;/em&gt; from the conversation altogether.&lt;/li&gt; 
 &lt;li&gt;Violence consists of &lt;em&gt;controlling&lt;/em&gt; (such as cutting others off, overstating facts, speaking in absolutes, etc.), &lt;em&gt;labeling&lt;/em&gt; to dismiss others under a stereotype or category, or &lt;em&gt;attacking&lt;/em&gt; through belittling or threatening.&lt;/li&gt; 
 &lt;li&gt;You must also self-monitor. Pay close attention to what you&apos;re doing and the impact it&apos;s having, and then alter your strategy if necessary. Check whether you&apos;re having a good or bad impact on safety.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Chapter 5: Make It Safe&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;The &lt;em&gt;good&lt;/em&gt; fix safety issues by sugarcoating their message, but this avoids the real problem. The &lt;em&gt;best&lt;/em&gt; don&apos;t play games; they step out of the content of the conversation, make it safe, and then step back in.&lt;/li&gt; 
 &lt;li&gt;Crucial conversations often go awry not because others dislike the content of the message, but because they believe the content suggests a malicious intent, thereby subverting safety.&lt;/li&gt; 
 &lt;li&gt;Mutual Purpose is required to begin dialogue: Where others perceive that you&apos;re working toward a common outcome, and that you care about their goals, interests, and values. And vice versa.&lt;/li&gt; 
 &lt;li&gt;When Mutual Purpose is at risk, we end up in debate. Other signs include defensiveness, hidden agendas, accusations, and circling back to the same topic.&lt;/li&gt; 
 &lt;li&gt;If you enter a conversation to get what you want, you will appear critical and selfish. Instead, find the Mutual Purpose: to draw someone willingly into a crucial conversation, see their point point of view.&lt;/li&gt; 
 &lt;li&gt;Mutual Respect is required to continue dialogue: If someone perceives disrespect in the conversation, it is no longer about its original purpose, but about defending dignity.&lt;/li&gt; 
 &lt;li&gt;When Mutual Purpose is at risk, emotions become charged and fear turns to anger. Then people resort to name-calling, yelling, and making threats.&lt;/li&gt; 
 &lt;li&gt;Recognize that we all have weaknesses; this creates a kinship and connection to others, which creates a Mutual Respect and eventually enables us to stay in dialogue with virtually anyone.&lt;/li&gt; 
 &lt;li&gt;When you&apos;ve made a mistake that hurts others, start with a sincere apology. You must give up saving face, being right, or winning in order to achieve healthy dialogue and better results.&lt;/li&gt; 
 &lt;li&gt;Contrasting is a skill that first addresses others&apos; concerns that you don&apos;t respect them or that you have a malicious purpose, and then confirms your respect or clarifies your real purpose.&lt;/li&gt; 
 &lt;li&gt;Contrasting is not apologizing. It is not a way of taking back something we&apos;ve said that hurt others&apos; feelings, but a way of ensuring that what we said didn&apos;t hurt more than it should have.&lt;/li&gt; 
 &lt;li&gt;Use contrast to provide context and proportion for your words, and to also bolster safety when you are about to drop into the pool of meaning something that could cause a splash of defensiveness.&lt;/li&gt; 
 &lt;li&gt;If you are in the middle of a debate because each side has a different purpose, seek to create Mutual Purpose using the four skills in the acronym CRIB.&lt;/li&gt; 
 &lt;li&gt;&lt;em&gt;Commit&lt;/em&gt; to seek a mutual purpose: Commit to stay in the conversation until we invent a solution that serves a purpose we both share. Verbalize this even if the other person seems committed to winning.&lt;/li&gt; 
 &lt;li&gt;&lt;em&gt;Recognize&lt;/em&gt; the purpose behind the strategy: Separate strategies, or what you&apos;re asking for, from the purpose, or what you actually want. This can create new options that can serve both of your interests.&lt;/li&gt; 
 &lt;li&gt;&lt;em&gt;Invent&lt;/em&gt; a mutual purpose: If you cannot discover a Mutual Purpose for dialogue, invent one by moving to more encompassing goals. Find an objective that is more meaningful or more rewarding.&lt;/li&gt; 
 &lt;li&gt;&lt;em&gt;Brainstorm&lt;/em&gt; new strategies: Once committed to finding something that everyone can support and surfaced what you really want, you&apos;ll no longer be spending your time on unproductive conflict.&lt;/li&gt; 
 &lt;li&gt;Before a crucial conversation begins, think about which skills will help you must. A little progress can produce a lot of benefit.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Chapter 6: Master My Stories&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;Others don&apos;t create emotions for you; you create your own emotions. And then, when you create strong emotions, you either find a way to master them or fall hostage to them.&lt;/li&gt; 
 &lt;li&gt;The worst at dialogue treat their emotions as the only valid response, falling hostage to their emotions without even realizing it.&lt;/li&gt; 
 &lt;li&gt;The best at dialogue act on their emotions, influencing and often changing their emotions by thinking them out, thereby making it possible to choose behaviors that create better results.&lt;/li&gt; 
 &lt;li&gt;After we observe what others do and before we feel an emotion, we tell ourselves a story, adding meaning, guessing at motive, and adding judgment before responding with emotion.&lt;/li&gt; 
 &lt;li&gt;Stories are our interpretations of the facts, providing a rationale for what&apos;s going on. We use them to explain the &lt;em&gt;why&lt;/em&gt;, &lt;em&gt;how&lt;/em&gt;, and &lt;em&gt;what&lt;/em&gt;.&lt;/li&gt; 
 &lt;li&gt;Any set of facts can be used to tell an infinite number of stories; by taking control of our stories, they won&apos;t control us.&lt;/li&gt; 
 &lt;li&gt;To take control, first take an honest look at your behavior. If an unhelpful story is driving you to silence or violence, stop and consider how others would see your actions.&lt;/li&gt; 
 &lt;li&gt;Next, stop and think about your feelings. Most people are emotionally illiterate; expand your vocabulary to better know how you feel, and more understand what is going on and why.&lt;/li&gt; 
 &lt;li&gt;Then, question your feelings, thereby allowing you to question your stories. This will allow you to develop new stories, and thereby develop new feelings.&lt;/li&gt; 
 &lt;li&gt;Separate stories from facts. Test whether you can see or hear what you&apos;re calling a &quot;fact,&quot; and look in stories for words that express judgments and attributions that create strong emotions.&lt;/li&gt; 
 &lt;li&gt;When we feel a need to justify our ineffective behavior or disconnect ourselves in bad results, we tend to tell ourselves one of three &quot;clever stories.&quot;&lt;/li&gt; 
 &lt;li&gt;&quot;Victim stories&quot; make us innocent while ignoring our own role in the problem; &quot;villain stories&quot; assume the worst motives or grossest incompetence for others while ignoring any possible good intentions or skills.&lt;/li&gt; 
 &lt;li&gt;These stories form a double standard: When we make mistakes, we tell a victim story; when others make mistakes, we tell a villain story.&lt;/li&gt; 
 &lt;li&gt;&quot;Helpless stories&quot; make us out to be powerless to do anything healthy or helpful, thereby justifying the action we&apos;re about to take.&lt;/li&gt; 
 &lt;li&gt;Villain stories and victim stories look back to explain the situation we&apos;re in, while helpless stories look forward to explain why we can&apos;t do anything to change our situation.&lt;/li&gt; 
 &lt;li&gt;We often tell clever stories to excuse ourselves of any responsibility, or to justify our actions when we consciously act against our own sense of what&apos;s right.&lt;/li&gt; 
 &lt;li&gt;Clever stories are incomplete and omit information about us, others, and our options. To add details, turn victims into actors, villains into humans, and the helpless into the able.&lt;/li&gt; 
 &lt;li&gt;These details create a &lt;em&gt;useful&lt;/em&gt; story, which creates emotions that lead to healthy action, such as dialogue.&lt;/li&gt; 
 &lt;li&gt;When humanizing &quot;villains,&quot; we relax our absolute certainty long enough to allow for dialogue, which is the only reliable way to discover others&apos; genuine emotions.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Chapter 7: STATE My Path&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;The best at dialogue speak their minds completely and do it in a way that makes it safe for others to hear what they have to say and respond to it as well.&lt;/li&gt; 
 &lt;li&gt;To maintain safety in dialogue, be confident in what you say and your ability to say it without causing offense, and be humble to encourage others&apos; input.&lt;/li&gt; 
 &lt;li&gt;Rely on STATE to discuss sensitive topics: State your facts, Tell your story, Ask for others&apos; paths, Talk tentatively, and Encourage testing.&lt;/li&gt; 
 &lt;li&gt;Starting with facts shows that you are reasonable and rational; starting with a story could easily surprise and insult others, thereby killing safety and muting the facts.&lt;/li&gt; 
 &lt;li&gt;Lead others down your Path to Action, starting with the facts and then moving to your story. The story conveys the severity of the implications.&lt;/li&gt; 
 &lt;li&gt;Encourage others to share their facts, stories, and feelings, and be willing to abandon or shape your story as more information pours into the pool of shared meaning.&lt;/li&gt; 
 &lt;li&gt;Speaking in absolute and overstated terms decreases your influence, while the more tentatively you speak, the more open people become to your opinions.&lt;/li&gt; 
 &lt;li&gt;When you begin your story with a complete disclaimer and do use a tone that suggests you&apos;re consumed with doubt, you do the message a disservice.&lt;/li&gt; 
 &lt;li&gt;Invite opposing views. If no one speaks up, play devil&apos;s advocate and model disagreeing by disagreeing with your own view.&lt;/li&gt; 
 &lt;li&gt;You can argue as vigorously as you want for your point of view, provided you are even more vigorous at encouraging, or even pleading with, others to disprove it.&lt;/li&gt; 
 &lt;li&gt;When you find yourself being forceful in your views, stop and think about what you really want for yourself, others, and the relationship, and ask if your behavior is congruent with that.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Chapter 8: Explore Others&apos; Paths&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;When someone retreats to the security of silence or violence, you can&apos;t force others to dialogue, but you can take steps to make it safer for them to do so.&lt;/li&gt; 
 &lt;li&gt;The cure to silence or violence is to get at the underlying source; this calls for genuine curiosity at a time when you&apos;re likely feeling frustrated or angry.&lt;/li&gt; 
 &lt;li&gt;To avoid overreacting to others&apos; stories, ask yourself &quot;Why would a reasonable, rational, and decent person say this?&quot;&lt;/li&gt; 
 &lt;li&gt;When others are in silence or violence, we&apos;re joining their Path to Action &lt;em&gt;already in progress&lt;/em&gt;. We must encourage them to share not their conclusions, but their observations.&lt;/li&gt; 
 &lt;li&gt;Helping others retrace their Path to Action helps us curb or emotion, and returns us to the facts and story behind the emotion, where feelings can be resolved.&lt;/li&gt; 
 &lt;li&gt;To encourage others to share, we must listen. We must employ the power listening tools of AMPP: Ask, Mirror, Paraphrase, and Prime.&lt;/li&gt; 
 &lt;li&gt;Ask: Stop filling the pool with your meaning, step back, and invite the other person to talk about his or her view.&lt;/li&gt; 
 &lt;li&gt;Mirror: Describe how the other person looks or acts, creating safety by using a tone that says that you&apos;re okay with them feeling how they&apos;re feeling.&lt;/li&gt; 
 &lt;li&gt;Paraphrase: Once you get a clue as to why the person is feeling the way he or she does, you can paraphrase to build additional safety.&lt;/li&gt; 
 &lt;li&gt;Instead of pushing too hard, ask what the other person wants to see happen. This moves his or her brain to problem solving and away from attacking or avoiding.&lt;/li&gt; 
 &lt;li&gt;Prime: When there is still no safety, offer your best guess as to what the other person is thinking or feeling. Only do this as a last resort.&lt;/li&gt; 
 &lt;li&gt;Remember that you are trying to understand the other person&apos;s point of view; not necessarily agree with it or support it.&lt;/li&gt; 
 &lt;li&gt;If you completely agree with the other person&apos;s path, say so and move on; don&apos;t turn an agreement into an argument.&lt;/li&gt; 
 &lt;li&gt;If you agree with what has been said but the information is incomplete build. Point out areas of agreement, and then add elements that were left out of the discussion.&lt;/li&gt; 
 &lt;li&gt;If you disagree, do not suggest that he or she is wrong, but suggest that you differ. Then share your path using the STATE skills.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Chapter 9: Move to Action&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;The end of a crucial conversation is risky because if you aren&apos;t careful about how you classify the conclusion and decisions, you can violate expectations.&lt;/li&gt; 
 &lt;li&gt;This manifests by people not understanding how decisions are going to be made, or by no decision ever being made.&lt;/li&gt; 
 &lt;li&gt;When the line of authority for making decisions is clear, it is that authority who decides what method of decision-making to employ.&lt;/li&gt; 
 &lt;li&gt;When the line of authority for making decisions is unclear, use your best dialogue skills to get meaning into the pool. Jointly decide how to decide.&lt;/li&gt; 
 &lt;li&gt;Make decisions by command, consult, vote, and consensus. These represent increased involvement, which increases commitment but decreases efficiency.&lt;/li&gt; 
 &lt;li&gt;With command decisions, either outside forces place demands on us, or we turn decisions over to others and then follow their lead.&lt;/li&gt; 
 &lt;li&gt;In the case of external forces, it&apos;s not our job to decide what to do; it&apos;s our job to decide how to make it work.&lt;/li&gt; 
 &lt;li&gt;Consulting is where decision makers invite others to influence before they make a choice. It permits gaining ideas and support without bogging down the decision-making process.&lt;/li&gt; 
 &lt;li&gt;Voting is best suited to situations where efficiency is the highest value, and you&apos;re selecting from a number of good options.&lt;/li&gt; 
 &lt;li&gt;Consensus can either produce tremendous unity and high-quality decisions, or can be a horrible waste of time.&lt;/li&gt; 
 &lt;li&gt;Reserve consensus for high-stakes and complex issues, or issues where everyone must absolutely support the final choice.&lt;/li&gt; 
 &lt;li&gt;Don&apos;t involve people who don&apos;t care, omit people who contribute no new information, but involve those whose authority or influence you need.&lt;/li&gt; 
 &lt;li&gt;Create assignments by specifying who, does what, by when, and how will you follow up?&lt;/li&gt; 
 &lt;li&gt;When passing out assignments, &quot;we&quot; can lead someone to believe that others are taking on the responsibility. Assign a name to every responsibility.&lt;/li&gt; 
 &lt;li&gt;To help clarify deliverables, use Contrasting to explain what you don&apos;t want. Or make things concrete by pointing to a prototype or sample.&lt;/li&gt; 
 &lt;li&gt;Assignments without deadlines are far better at producing guilt than stimulating action.&lt;/li&gt; 
 &lt;li&gt;If you want people to feel accountable, then you must give them opportunity to account. Build expectation for follow-up into every assignment.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Chapter 10: Yeah, But&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;With sexual or other harassment, own up to tolerating the behavior for too long, and then establish Mutual Purpose and then STATE your path.&lt;/li&gt; 
 &lt;li&gt;With a sensitive spouse, use contrasting, tentatively explain consequences, and use testing. Look for signs that safety is at risk, then make it safe.&lt;/li&gt; 
 &lt;li&gt;When a teammate fails to live up to agreements, speak up and hold each other accountable.&lt;/li&gt; 
 &lt;li&gt;When experiencing deference to authority, either you are creating fear or you are living with the ghosts of past bosses, or both.&lt;/li&gt; 
 &lt;li&gt;If you are the problem, solicit peer feedback. If it stems from ghosts, go public and reward risk-takers, encourage testing, and thank people for contrary opinions.&lt;/li&gt; 
 &lt;li&gt;With lack of trust, bring up your concerns, and STATE what you see happening. Do not tell a Villain Story that exaggerates others&apos; untrustworthiness.&lt;/li&gt; 
 &lt;li&gt;With someone who won&apos;t talk about anything serious, Make It Safe, use tentative language, Explore Others&apos; Paths, and be patient.&lt;/li&gt; 
 &lt;li&gt;When you see signs of improvement, invite talking about how you talk or don&apos;t talk about important issues, building safety by establishing Mutual Purpose.&lt;/li&gt; 
 &lt;li&gt;When faced with subtle and unacceptable actions, retrace your Path to Action to its source, and if the behaviors are worthy of dialogue STATE Your Path.&lt;/li&gt; 
 &lt;li&gt;With someone shows no initiative, establish new and higher expectations. Deal with the overall pattern, not a specific instance.&lt;/li&gt; 
 &lt;li&gt;With a problem shows a pattern, STATE Your Path. Talk about the pattern; talking about any one instance will make your concern seem trivial.&lt;/li&gt; 
 &lt;li&gt;When you need to calm down, suggest that you need some time alone and that you&apos;d like to pick up the conversation later.&lt;/li&gt; 
 &lt;li&gt;Suggesting someone else needs to calm down is patronizing. To get back to the source of their anger, retrace their Path to Action.&lt;/li&gt; 
 &lt;li&gt;When faced with endless excuses, gain commitment to solving the overall problem, not simply the stated cause.&lt;/li&gt; 
 &lt;li&gt;Insubordination catches most leaders by surprise. They buy time to figure out what to do, which lets the person get away with it.&lt;/li&gt; 
 &lt;li&gt;When you catch insubordination, speak up immediately but respectfully. Change topics from the issue at hand to how the person is currently acting.&lt;/li&gt; 
 &lt;li&gt;Stories left unattended don&apos;t get better with time, they ferment. Then when we can&apos;t take it anymore, we say something that we regret.&lt;/li&gt; 
 &lt;li&gt;Use your STATE skills before a story turns too ugly, or if you&apos;ve let the problem build, use your STATE skills and tell the most simple and least offensive story.&lt;/li&gt; 
 &lt;li&gt;With touchy and personal issues, use contrasting, establish Mutual Purpose to show honorable intentions, and tentatively describe the problem.&lt;/li&gt; 
 &lt;li&gt;When faced with word games, STATE the pattern of playing games, discuss both behaviors and outcomes, and then hold them accountable to results.&lt;/li&gt; 
 &lt;li&gt;With someone who delivers surprises, clarify that one needs to complete the assignment as planned or immediately inform you if they run into a problem.&lt;/li&gt; 
 &lt;li&gt;With someone who violates all the dialogue principles, choose your targets carefully: Focus on what bothers you the most, and what is easiest to work on.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Chapter 11: Putting It All Together&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;The first lever for getting to dialogue is asking whether you&apos;re playing games or in dialogue. If you&apos;ve moved away, don&apos;t be afraid to express that sentiment.&lt;/li&gt; 
 &lt;li&gt;The second lever is making it safe. Asking a question, showing interest, an appropriate touch, an apology, a smile, or a request for a &quot;time out&quot; all build safety.&lt;/li&gt; 
 &lt;li&gt;For &quot;Start with Heart&quot;, focus on what you really want, and refuse the Sucker&apos;s Choice.&lt;/li&gt; 
 &lt;li&gt;For &quot;Learn to Look,&quot; look for when the conversation becomes crucial, and look for safety problems.&lt;/li&gt; 
 &lt;li&gt;For &quot;Make It Safe,&quot; apologize when appropriate, contrast to fix misunderstanding, and CRIB to get Mutual Purpose.&lt;/li&gt; 
 &lt;li&gt;For &quot;Master My Stories,&quot; retrace your path to action, separate fact from story, and watch for the Three Clever Stories.&lt;/li&gt; 
 &lt;li&gt;For &quot;STATE My Path,&quot; Share your facts, Tell your story, Ask for others&apos; paths, Talk tentatively, and Encourage testing.&lt;/li&gt; 
 &lt;li&gt;For &quot;Explore Others&apos; Paths,&quot; use AMPP, or Ask, Mirror, Paraphrase, and Prime, and then Agree, Build, and Compare.&lt;/li&gt; 
 &lt;li&gt;For &quot;Move to Action,&quot; decide how you will decide, and then document decisions and follow up.&lt;/li&gt; 
 &lt;li&gt;The current quality of your leadership and your life is fundamentally a function of how you are presently handling crucial conversations.&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>50 Philosophy Ideas</title>
      <link>https://tedneward.github.io/Research/thinking/50-philosophy-ideas/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">thinking/50-philosophy-ideas/index.html</guid>
      	<description>
	&lt;h3&gt;The Brain in a vat&lt;/h3&gt; 
&lt;p&gt;&lt;em&gt;(are you an envatted brain?)&lt;/em&gt;&lt;br&gt; scepticism: how do we know what we know?&lt;/p&gt; 
&lt;p&gt;the philosophical skeptic doesn&apos;t claim that we know nothing--not least because to do so would be obviously self-defeating (one thing we could not know is that we know nothing). Rather the skeptic&apos;s position is to challenge our right to make claims to knowledge. We think we know lots of things, but how can we defend those claims? What grounds can we produce to justify any particular claim of knowledge? Our supposed knowledge of the world is based on perceptions gained via our senses, usually mediated by our use of reason. But are not such perceptions always open to error? Can we ever be sure we&apos;re not hallucinating or dreaing, or that our memory isn&apos;t playing tricks? [Epistemology]&lt;/p&gt; 
&lt;h3&gt;Plato&apos;s cave&lt;/h3&gt; 
&lt;p&gt;&lt;em&gt;(earthly knowledge&apos;s but a shadow)&lt;/em&gt;&lt;/p&gt; 
&lt;p&gt;the cave represents &apos;the realm of becoming&apos;--the visible world of our everyday experience, where everything is imperfect and constantly changing. The chained captives (us) live in a world of conjecture and illusion, while the former prisoner, free to roam within the cave, attains the most accurate view of reality possible, within the ever-changing world of perception and experience. By contrast, the world outside the cave represents the &apos;realm of being&apos;--the intelligible world of truth populated by the objects of knowledge, which are perfect, eternal and unchanging.&lt;/p&gt; 
&lt;p&gt;what is known must not only be true but also perfect and unchanging. Nothing in the empirical world (represented by life within the cave) fits this description: a tall person is short next to a tree; an apple that appears red at noon looks black at dusk; and so on. As nothing in the empirical world is an object of knowledge, Plato proposed that there must be another ream (the world outside the cave) of perfect and unchanging ideas which he called &apos;Forms&apos; or Ideas.&lt;/p&gt; 
&lt;p&gt;the problem of universals: realists/Platonists believe that universals such as redness and tallness exist independently of particular red and tall things; and the anti-realists/nominalists hold that they are mere names or labels that are attached to objects to highlight particular similarities between them. Modern debate continues: realists hold that there are entities &apos;out there&apos; in the world--physical things or ethical facts or mathematical properties--that exist independently of our knowing/experiencing them. Anti-realists there must be a necessary and internal link or relation between what is known and our knowledge of it.&lt;/p&gt; 
&lt;h3&gt;The veil of perception&lt;/h3&gt; 
&lt;p&gt;&lt;em&gt;(what lies beyond the veil?)&lt;/em&gt;&lt;/p&gt; 
&lt;p&gt;most of us uncritically suppose that physical objects around us are more or less what we perceive them to be, but some question that--in their view we have direct access to inner &apos;ideas&apos;, &apos;impressions&apos; or &apos;sense data&apos;; human understanding is like a closet wholly shut from light, with only some little openings left, to let in external visible resemblances, or ideas of things without. Our ideas, which are all that we have direct access to, form an impenetrable &apos;veil of perception&apos; between us and the outside world. &apos;Representational&apos; models of perception: any such model that involves intermediate ideas or sense data drives a wedge between us and the external world, and it is in the fissure so formed that skepticism about our claims to knowledge really exist. It is only by re-establishing a direct link between observer and external object that the veil can be torn and the skeptic vanquished. So, given that the model causes such problems, why adopt it in the first place? Locke hoped that by distinguishing between &apos;primary&apos; and &apos;secondary&apos; characteristics (one being intrinsic, the other perceptionally-influenced) he could disarm the skeptic.&lt;/p&gt; 
&lt;p&gt;Berkeley refuted it by saying that Locke could never actually check whether his supposed resemblances actually resembled the external things themselves, then took it to its conclusion and said that reality consists in the &apos;ideas&apos; or sensations themselves; with these, we are already fully and properly connected, so the dangers of skepticism are evaded, but only at the price of the denial of an external, physical world. Berkeley&apos;s idealist (or immaterialist) theory states &quot;to exist is to be perceived&quot;, and since God perceives all things, it remains in existence even when passing out of human perception.&lt;/p&gt; 
&lt;h3&gt;&lt;em&gt;cogito ergo sum&lt;/em&gt;&lt;/h3&gt; 
&lt;p&gt;&lt;em&gt;(I am thinking therefore I exist)&lt;/em&gt;&lt;/p&gt; 
&lt;h3&gt;Reason &amp;amp; experience&lt;/h3&gt; 
&lt;p&gt;&lt;em&gt;(How do we know?)&lt;/em&gt;&lt;/p&gt; 
&lt;h3&gt;The tripartite theory of knowledge&lt;/h3&gt; 
&lt;p&gt;&lt;em&gt;(When do we really know?)&lt;/em&gt;&lt;/p&gt; 
&lt;h3&gt;The mind-body problem&lt;/h3&gt; 
&lt;p&gt;&lt;em&gt;(Mind boggles)&lt;/em&gt;&lt;/p&gt; 
&lt;h3&gt;What is it like to be a bat?&lt;/h3&gt; 
&lt;p&gt;&lt;em&gt;(Inside a bat&apos;s mind?)&lt;/em&gt;&lt;/p&gt; 
&lt;h3&gt;The Turing test&lt;/h3&gt; 
&lt;p&gt;&lt;em&gt;(&quot;Did you ever take that test yourself?&quot;)&lt;/em&gt;&lt;/p&gt; 
&lt;h3&gt;The ship of Theseus&lt;/h3&gt; 
&lt;p&gt;&lt;em&gt;(What makes you, you?)&lt;/em&gt;&lt;/p&gt; 
&lt;h3&gt;Other minds&lt;/h3&gt; 
&lt;p&gt;&lt;em&gt;(Is there anybody there?)&lt;/em&gt;&lt;/p&gt; 
&lt;h3&gt;Hume&apos;s guillotine&lt;/h3&gt; 
&lt;p&gt;&lt;em&gt;(The is-ought gap)&lt;/em&gt;&lt;/p&gt; 
&lt;h3&gt;One man&apos;s meat&lt;/h3&gt; 
&lt;p&gt;&lt;em&gt;(Is it all relative?)&lt;/em&gt;&lt;/p&gt; 
&lt;h3&gt;The divine command theory&lt;/h3&gt; 
&lt;p&gt;&lt;em&gt;(Because God says so)&lt;/em&gt;&lt;/p&gt; 
&lt;h3&gt;The boo/hooray theory&lt;/h3&gt; 
&lt;p&gt;&lt;em&gt;(Expressing moral judgements)&lt;/em&gt;&lt;/p&gt; 
&lt;h3&gt;Ends &amp;amp; means&lt;/h3&gt; 
&lt;p&gt;&lt;em&gt;(The least bad option)&lt;/em&gt;&lt;/p&gt; 
&lt;h3&gt;The experience machine&lt;/h3&gt; 
&lt;p&gt;&lt;em&gt;(Is happiness enough?)&lt;/em&gt;&lt;/p&gt; 
&lt;h3&gt;The categorical imperative&lt;/h3&gt; 
&lt;p&gt;&lt;em&gt;(Duty at any cost)&lt;/em&gt;&lt;/p&gt; 
&lt;h3&gt;The Golden Rule&lt;/h3&gt; 
&lt;p&gt;&lt;em&gt;(Do as you would be done by)&lt;/em&gt;&lt;/p&gt; 
&lt;h3&gt;Acts &amp;amp; omissions&lt;/h3&gt; 
&lt;p&gt;&lt;em&gt;(To do or not to do?)&lt;/em&gt;&lt;/p&gt; 
&lt;h3&gt;Slippery slopes&lt;/h3&gt; 
&lt;p&gt;&lt;em&gt;(If you give an inch...)&lt;/em&gt;&lt;/p&gt; 
&lt;h3&gt;Beyond the call of duty&lt;/h3&gt; 
&lt;p&gt;&lt;em&gt;(Should we all be heroes?)&lt;/em&gt;&lt;/p&gt; 
&lt;h3&gt;Is it bad to be unlucky?&lt;/h3&gt; 
&lt;p&gt;&lt;em&gt;(Does Fortune favor the good?)&lt;/em&gt;&lt;/p&gt; 
&lt;h3&gt;Virtue ethics&lt;/h3&gt; 
&lt;p&gt;&lt;em&gt;(Who you are, not what you do)&lt;/em&gt;&lt;/p&gt; 
&lt;h3&gt;Do animals feel pain?&lt;/h3&gt; 
&lt;p&gt;&lt;em&gt;(Animal cruelty)&lt;/em&gt;&lt;/p&gt; 
&lt;h3&gt;Do animals have rights?&lt;/h3&gt; 
&lt;p&gt;&lt;em&gt;(Human wrongs?)&lt;/em&gt;&lt;/p&gt; 
&lt;h3&gt;Forms of argument&lt;/h3&gt; 
&lt;p&gt;&lt;em&gt;(Infallible reasoning?)&lt;/em&gt;&lt;/p&gt; 
&lt;h3&gt;The barber paradox&lt;/h3&gt; 
&lt;p&gt;&lt;em&gt;(If it is, it isn&apos;t)&lt;/em&gt;&lt;/p&gt; 
&lt;h3&gt;The gambler&apos;s fallacy&lt;/h3&gt; 
&lt;p&gt;&lt;em&gt;(Against the odds)&lt;/em&gt;&lt;/p&gt; 
&lt;h3&gt;The Sorites Paradox&lt;/h3&gt; 
&lt;p&gt;&lt;em&gt;(How many grains make a heap?)&lt;/em&gt;&lt;/p&gt; 
&lt;h3&gt;The King of France is bald&lt;/h3&gt; 
&lt;p&gt;&lt;em&gt;(Language and logic)&lt;/em&gt;&lt;/p&gt; 
&lt;h3&gt;The beetle in the box&lt;/h3&gt; 
&lt;p&gt;&lt;em&gt;(Language games)&lt;/em&gt;&lt;/p&gt; 
&lt;h3&gt;Science &amp;amp; pseudoscience&lt;/h3&gt; 
&lt;p&gt;&lt;em&gt;(Evidence falsifying hypothesis)&lt;/em&gt;&lt;/p&gt; 
&lt;h3&gt;Paradigm shifts&lt;/h3&gt; 
&lt;p&gt;&lt;em&gt;(science--evolution and revolution)&lt;/em&gt;&lt;/p&gt; 
&lt;h3&gt;Occam&apos;s Razor&lt;/h3&gt; 
&lt;p&gt;&lt;em&gt;(Keep it simple)&lt;/em&gt;&lt;/p&gt; 
&lt;h3&gt;What is art?&lt;/h3&gt; 
&lt;p&gt;&lt;em&gt;(Aesthetic values)&lt;/em&gt;&lt;/p&gt; 
&lt;h3&gt;The intentional fallacy&lt;/h3&gt; 
&lt;p&gt;&lt;em&gt;(Meanings in art)&lt;/em&gt;&lt;/p&gt; 
&lt;h3&gt;The argument from design&lt;/h3&gt; 
&lt;p&gt;&lt;em&gt;(The divine watchmaker)&lt;/em&gt;&lt;/p&gt; 
&lt;h3&gt;The cosmological argument&lt;/h3&gt; 
&lt;p&gt;&lt;em&gt;(The first and uncaused cause)&lt;/em&gt;&lt;/p&gt; 
&lt;h3&gt;The ontological argument&lt;/h3&gt; 
&lt;p&gt;&lt;em&gt;(The greatest imaginable being)&lt;/em&gt;&lt;/p&gt; 
&lt;h3&gt;The problem of evil&lt;/h3&gt; 
&lt;p&gt;&lt;em&gt;(Why does God let bad things happen?)&lt;/em&gt;&lt;/p&gt; 
&lt;h3&gt;The freewill defense&lt;/h3&gt; 
&lt;p&gt;&lt;em&gt;(Freedom to do wrong)&lt;/em&gt;&lt;/p&gt; 
&lt;h3&gt;Faith &amp;amp; reason&lt;/h3&gt; 
&lt;p&gt;&lt;em&gt;(The leap of faith)&lt;/em&gt;&lt;/p&gt; 
&lt;h3&gt;Positive &amp;amp; negative freedom&lt;/h3&gt; 
&lt;p&gt;&lt;em&gt;(Divided loyalties)&lt;/em&gt;&lt;/p&gt; 
&lt;h3&gt;The difference principle&lt;/h3&gt; 
&lt;p&gt;&lt;em&gt;(Justice as fairness)&lt;/em&gt;&lt;/p&gt; 
&lt;h3&gt;Leviathan&lt;/h3&gt; 
&lt;p&gt;&lt;em&gt;(The social contract)&lt;/em&gt;&lt;/p&gt; 
&lt;h3&gt;The prisoner&apos;s dilemma&lt;/h3&gt; 
&lt;p&gt;&lt;em&gt;(Playing the game)&lt;/em&gt;&lt;/p&gt; 
&lt;h3&gt;Theories of punishment&lt;/h3&gt; 
&lt;p&gt;&lt;em&gt;(Does the punishment fit the crime?)&lt;/em&gt;&lt;/p&gt; 
&lt;h3&gt;Lifeboat Earth&lt;/h3&gt; 
&lt;p&gt;&lt;em&gt;(Is there more room in the boat?)&lt;/em&gt;&lt;/p&gt; 
&lt;h3&gt;Just war&lt;/h3&gt; 
&lt;p&gt;&lt;em&gt;(Fight the good fight)&lt;/em&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>50 Psychology Ideas</title>
      <link>https://tedneward.github.io/Research/thinking/50-psychology-ideas/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">thinking/50-psychology-ideas/index.html</guid>
      	<description>
	&lt;p&gt;&lt;em&gt;(Furnham, Adrian (2009-03-02). 50 Psychology Ideas You Really Need to Know (50 Ideas You Really Need to Know Series) )&lt;/em&gt;&lt;/p&gt; 
&lt;h3&gt;Abnormal behavior&lt;/h3&gt; 
&lt;p&gt;&quot;For clinical psychology, the issue is not so much whether the behaviour is abnormal, as whether it is maladaptive, causing a person distress and social impairment. If a person’s behaviour seems irrational or potentially harmful to themselves and others, we tend to think of that as abnormal. For the psychologist it is called psychopathology.&quot;&lt;br&gt; &quot;Today, psychological definitions of abnormality revolve around a handful of generally agreed-upon criteria. These have been classified as the 4Ds: distress, deviance, dysfunction, danger. … A very common criterion is irrationality -- bizarre, illogical beliefs about the physical or social world as well as, very often, the spiritual world.&quot;&lt;br&gt; * Subjective: Uses ourselves, our behavior, our values as the criteria of normality&lt;br&gt; * Normative: There is an ideal, desirable state of how one should think and behave&lt;br&gt; * Clinical: &quot;Social scientists and medical clinicians attempt to assess the effectiveness, organization and adaptiveness of a person’s functioning. Much depends on which dimension is being assessed. Clinicians also accept that the normal–abnormal distinctions are grey and somewhat subjective, though they strive for reliable diagnosis. Abnormality is usually associated with poor adaptations, pain or bizarre behaviours.&quot;&lt;br&gt; * Cultural: &quot;Culture dictates trends in everything from dress to demeanour, language to love. Culture prescribes and proscribes behaviours. Certain things are taboo, others are illegal.&quot;&lt;br&gt; * Statistical: &quot;All statisticians know the concept of the bell curve or the normal distribution. It has particular properties and is best known in the world of intelligence. Thus a score of 100 is average and 66 per cent of the population score between 85 and 115, and around 97 per cent between 70 and 130. Thus if you score below 70 and over 130 you are unusual, though the word ‘abnormal’ would not be applied. This model has drawbacks in the fact that behaviour that occurs frequently does not necessarily make it healthy or desirable.&quot;&lt;/p&gt; 
&lt;h3&gt;Placebo effect&lt;/h3&gt; 
&lt;p&gt;&quot;A placebo is simply defined as a preparation with no medicinal value and no pharmacological effects. An active placebo is one that mimics the side-effects of the drug under investigation but lacks its specific, assumed therapeutic affect. … Modern research in the area is usually attributed to a paper written in the American Dental Association Journal over 50 years ago. Henry Beecher shocked the medical world by claiming that just placebo procedures like giving sugar pills or even sympathetically physically examining the patient would lead to an improvement in 30 per cent of patients. Today that estimate has increased to between a half to three-quarters of patients, with all sorts of problems from asthma to Parkinson’s showing real lasting improvements from a range of treatments.&quot;&lt;/p&gt; 
&lt;p&gt;&quot;More serious, ‘major’ or invasive procedures do appear to have stronger placebo effects. Injections per se appear to have a greater impact than pills, and even placebo surgery (where people are cut open and sewn up with little or nothing done) has yielded high positive response rates. The style of treatment administration and other qualities of the therapist appear to contribute substantially to the impact of the treatment itself. Those therapists who also exhibit greater interest in their patients, greater confidence in their treatments, and higher professional status, all appear to promote stronger placebo effects in their patients.&quot;&lt;/p&gt; 
&lt;h3&gt;Kicking the habit&lt;/h3&gt; 
&lt;p&gt;&lt;em&gt;(addiction)&lt;/em&gt;&lt;br&gt; &quot;Addiction involves the exposure to something and then the behaviour seeking to repeat the experience very often. Over time the addiction becomes established. There is regular and increasing consumption, with the takers knowing their habit is expensive, unhealthy and possibly illegal but seemingly being unable to give it up.&quot;&lt;/p&gt; 
&lt;p&gt;&quot;With regard to drugs, the psychiatric literature distinguishes between substance dependence and abuse. Both have technical meaning. Dependence has very specific characteristics like tolerance (people take more and more for limited effect); withdrawal symptoms (on not taking the drug); obsessions with trying to get hold of the drug; a deterioration in all social, occupational and recreational activities; and continued use with full knowledge of all the damage that is being done. … Abuse means using the drug despite the need to fulfil various school, home and work obligations; use in dangerous situations (driving, at work); use despite illegal behaviour; use despite persistent negative side-effects.&quot;&lt;/p&gt; 
&lt;h3&gt;Lost touch&lt;/h3&gt; 
&lt;p&gt;&lt;em&gt;(schizophrenia)&lt;/em&gt;&lt;br&gt; &quot;Schizophrenia is a psychotic illness characterized by a disorder of thoughts and perceptions, behaviours and moods. … They tend to have various manifestations of thought disorders (disorganized, irrational thinking), delusions and hallucinations. They tend to lack energy, initiative and social contacts. They are emotionally very flat, have few pleasures and are withdrawn.&quot;&lt;/p&gt; 
&lt;p&gt;&quot;The classification of schizophrenia remains complex because of the diversity of symptoms. These include delusions; hallucinations; disorganized speech (incoherence, loose association, use of nonsense words); disorganized behaviour (dress, body posture, personal hygiene); negative, flat emotions; poor insight into their problems; and depression. Because of complications with the diagnosis, various subtypes have been named. Thus there is paranoid and catatonic schizophrenia. Catatonics (from the Greek ‘to stretch or draw tight’) often adopt odd, stationary poses for long periods of time. Paranoid schizophrenics have delusions of control, grandeur and persecution and are consistently suspicious of all around them. Disorganized schizophrenics manifest bizarre thoughts and language, with sudden inappropriate emotional outbursts. Some psychiatrists mention simple or undifferentiated schizophrenia. Others have distinguished between acute (sudden, severe onset) and chronic (prolonged, gradual onset). Another distinction is between Type I (mostly positive symptoms) and Type II (mostly negative symptoms).&quot;&lt;/p&gt; 
&lt;p&gt;&quot;There is still no complete agreement about the subtypes or the precise ‘deficits’ in functioning, though these usually come under four headings: cognitive or thinking; perceptual or seeing; motor or moving; emotional or feeling.&quot;&lt;/p&gt; 
&lt;h3&gt;Not neurotic, just different&lt;/h3&gt; 
&lt;p&gt;&lt;em&gt;(anti-psychiatry)&lt;/em&gt;&lt;br&gt; &quot;Anti-psychiatry critics questioned three things: the medicalization of madness; the existence of mental illness; and the power of psychiatrists to diagnose and treat certain individuals with compulsion. Anti-psychiatry was more than anti-custodial: it was often anti-state, almost anarchic. It saw many state institutions, particularly mental hospitals, as distorting and repressing the human spirit and potential in various groups.&quot;&lt;/p&gt; 
&lt;p&gt;&quot;One of the most famous anti-psychiatry studies was done in the early 1970s. Eight ‘normal’, mentally healthy researchers tried to gain admission, through diagnosis, to a number of American mental hospitals. The only symptom they reported was hearing voices. Seven were diagnosed as schizophrenic and admitted. Once in the hospital they behaved normally and were ignored when they politely asked for information. They later reported that their diagnostic label of schizophrenia meant they had low status and power in the hospital. Then they ‘came clean’ and admitted they had no symptoms and felt fine. But it took nearly three weeks before they were discharged, often with the diagnosis ‘schizophrenia in remission’. So normal, healthy people could easily be diagnosable as ‘abnormal’. But could the reverse happen? The same researchers told psychiatric hospital staff that fake or pseudopatients pretending to be schizophrenics may try to gain access to their hospital. They then found that 19 genuine patients were suspected as frauds by two or more members of staff, including a psychiatrist.&quot;&lt;/p&gt; 
&lt;h3&gt;Seem sane&lt;/h3&gt; 
&lt;p&gt;&lt;em&gt;(psychopathy/sociopathy)&lt;/em&gt;&lt;br&gt; &quot;Psychopathy is a personality disorder characterized by people who have no conscience and are incapable of empathy, guilt or loyalty to anyone but themselves. Sociopathy is a non-psychiatric condition and refers to those who are anti-social and criminal and follow the norms of a particular subculture.&quot;&lt;/p&gt; 
&lt;p&gt;&quot;Overall psychopaths tend to be impulsive and irresponsible, with few clear life goals. They have a history of problems with authority and poor behavioural controls. They lack empathy and remorse and never accept responsibility for their actions. … The first response to being found out is to escape, leaving colleagues, family or debtors to pick up the pieces. They do so without a qualm. The next response is to lie with apparent candour and sincerity even under oath and even to parents and loved ones. They behave as if social rules and regulations do not really apply to them. They have no respect for authorities and institutions, families and traditions.&quot;&lt;/p&gt; 
&lt;ol&gt; 
 &lt;li&gt;Psychopaths show a disregard for, and violation of, the rights of others. They often have a history of being difficult, delinquent or dangerous.&lt;/li&gt; 
 &lt;li&gt;They fail to conform to social norms with respect to lawful behaviours (repeatedly performing acts that are grounds for arrest, imprisonment and serious detention). This includes, lying, stealing and cheating.&lt;/li&gt; 
 &lt;li&gt;They are always deceitful, as indicated by repeated lying, use of aliases, or conning others for personal profit or pleasure. They are nasty, aggressive, con artists – the sort who often get profiled on business crime programmes.&lt;/li&gt; 
 &lt;li&gt;They are massively impulsive and fail to plan ahead. They live only in, and for, the present.&lt;/li&gt; 
 &lt;li&gt;They show irritability and aggressiveness, as indicated by repeated physical fights or assaults. They can’t seem to keep still – ever.&lt;/li&gt; 
 &lt;li&gt;They manifest a reckless disregard for the physical and psychological safety of others.&lt;/li&gt; 
 &lt;li&gt;They are consistently irresponsible. Repeated failure to sustain consistent work behaviour or to honour financial obligations are their hallmark.&lt;/li&gt; 
 &lt;li&gt;They show a lack of remorse. They are indifferent to, or rationalize, having hurt, mistreated or stolen from another. They never learn from their mistakes. It can seem that labelling them as anti-social is a serious understatement.&quot;&lt;/li&gt; 
&lt;/ol&gt; 
&lt;p&gt;&quot;They avoid group/committee meetings because they say very different things to different people and can’t present a single façade or voice that is coherent. Co-workers, colleagues and reports are frequently abandoned when their usefulness is at an end. They deliberately create conflict between individuals to try to prevent them sharing information about them. All detractors are ‘neutralized’ not so much by violence or threats but by raising doubts about their integrity and loyalty as well as their competence. Psychopaths seek out organizations in flux or change as well as those with poor monitoring systems so that they are rarely threatened or challenged.&quot;&lt;/p&gt; 
&lt;h3&gt;Stress&lt;/h3&gt; 
&lt;p&gt;Challenge and support at work:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Much support, little challenge People in this situation are in the fortunate position of good technical and social support, but the fact they are under-challenged probably means that they underperform. They may actually be stressed by boredom and monotony.&lt;/li&gt; 
 &lt;li&gt;Much support, much challenge This combination tends to get the most out of people as they are challenged by superiors, subordinates, shareholders and customers to ‘work smarter’ but are given the appropriate support to succeed.&lt;/li&gt; 
 &lt;li&gt;Little support, much challenge This unfortunate, but very common, situation is a major cause of stress for any manager because he or she is challenged to work consistently hard but only offered minimal emotional, informational (feedback) and physical (equipment) support.&lt;/li&gt; 
 &lt;li&gt;Little support, little challenge People in some bureaucracies lead a quiet and unstressed life because they are neither challenged nor supported, which usually means neither they nor their organization benefit.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;&quot;Three components: Firstly, stress can be a function of the make-up of the individual, particularly their personality, ability and biography. Secondly, there are features about the environment (job, family, organization), usually but not exclusively considered in terms of the work environment. Thirdly, there is how the individual and the environment perceive, define but more importantly try to cope with stress, strains and pressures.&quot;&lt;/p&gt; 
&lt;p&gt;&quot;Coping One distinction that has been made is between problem-focused coping (aimed at problem-solving or doing something to alter the source of stress) and emotion-focused coping (aimed at reducing or managing the emotional distress that is associated with, or cued by, a particular set of circumstances). Emotion-focused responses can involve denial; others involve positive reinterpretation of events; and still others involve the seeking out of social support. Similarly, problem-focused coping can potentially involve several distinct activities, such as planning, taking direct action, seeking assistance, screening out particular activities, and sometimes stopping acting for an extended period.&lt;br&gt; * Optimism: a buffer against stress Optimists are hopeful in their outlook on life, interpret a wide range of situations in a positive light, and tend to expect favourable outcomes and results. Pessimists, by contrast, interpret many situations negatively, and expect unfavourable outcomes and results. Optimists concentrate on problem-focused coping – making and enacting specific plans for dealing with sources of stress. In addition, they seek social support – the advice and help of friends and others – and refrain from engaging in other activities until current problems are solved and stress is reduced.&lt;br&gt; * Hardiness: viewing stress as a challenge Hardy people appear to differ from others in three respects. They show a higher level of commitment – deeper involvement in their jobs and other life activities; control – the belief that they can, in fact, influence important events in their lives and the outcomes they experience; and challenge – they perceive change as a challenge and an opportunity to grow rather than as a threat to their security.&quot;&lt;/p&gt; 
&lt;h3&gt;Visual illusions&lt;/h3&gt; 
&lt;p&gt;&quot;It has been suggested that all illusions fall into one of four groups: ambiguities, distortions, paradoxes and factions. Of course illusions are of particular interest to visual scientists and cognitive psychologists because they give an important insight into the process of perception.&lt;/p&gt; 
&lt;h3&gt;Psychophysics (physics of the mind)&lt;/h3&gt; 
&lt;p&gt;&quot;A simple psychophysics question becomes ‘What is the chain of events that begins with a stimulus and leads up to reports such as “a bright red”, or “a loud noise”?’ The details of this sequence obviously differ for each sense but there are always three basic steps: a stimulus to a sense receptor; a neural chain of events caused by this stimulus – it is changed into an electric signal and then into a nerve impulse; a psychological response to the message (sensation).&quot;&lt;/p&gt; 
&lt;h3&gt;Hallucinations&lt;/h3&gt; 
&lt;h3&gt;Delusions&lt;/h3&gt; 
&lt;h3&gt;Are you conscious?&lt;/h3&gt; 
&lt;h3&gt;Positive psychology&lt;/h3&gt; 
&lt;h3&gt;Emotional intelligence&lt;/h3&gt; 
&lt;h3&gt;What are emotions for?&lt;/h3&gt; 
&lt;h3&gt;Cognitive therapy&lt;/h3&gt; 
&lt;h3&gt;IQ and you&lt;/h3&gt; 
&lt;h3&gt;Flynn effect&lt;/h3&gt; 
&lt;h3&gt;Multiple intelligences&lt;/h3&gt; 
&lt;h3&gt;Cognitive differences&lt;/h3&gt; 
&lt;h3&gt;Rorschach inkblot test&lt;/h3&gt; 
&lt;h3&gt;Detecting lies&lt;/h3&gt; 
&lt;h3&gt;Authoritarian personality&lt;/h3&gt; 
&lt;h3&gt;Obedience to authority&lt;/h3&gt; 
&lt;h3&gt;Fitting in&lt;/h3&gt; 
&lt;h3&gt;Self-sacrifice or selfishness&lt;/h3&gt; 
&lt;h3&gt;Cognitive dissonance&lt;/h3&gt; 
&lt;h3&gt;Gambler&apos;s fallacy&lt;/h3&gt; 
&lt;h3&gt;Judgement and problem-solving&lt;/h3&gt; 
&lt;h3&gt;Too much invested to quit&lt;/h3&gt; 
&lt;h3&gt;Rational decision-making&lt;/h3&gt; 
&lt;h3&gt;Remembrance of things past&lt;/h3&gt; 
&lt;h3&gt;What the witness saw&lt;/h3&gt; 
&lt;h3&gt;Artificial intelligence&lt;/h3&gt; 
&lt;h3&gt;Perchance to dream&lt;/h3&gt; 
&lt;h3&gt;Try to forget&lt;/h3&gt; 
&lt;h3&gt;Tip-of-the-tongue phenomenon&lt;/h3&gt; 
&lt;h3&gt;Psychosexual stages&lt;/h3&gt; 
&lt;h3&gt;Cognitive stages&lt;/h3&gt; 
&lt;h3&gt;Ducks in a row&lt;/h3&gt; 
&lt;h3&gt;Tabula rasa&lt;/h3&gt; 
&lt;h3&gt;Stay hungry&lt;/h3&gt; 
&lt;h3&gt;Behaviorism&lt;/h3&gt; 
&lt;h3&gt;Reinforcement schedules&lt;/h3&gt; 
&lt;h3&gt;Mastering complexity&lt;/h3&gt; 
&lt;h3&gt;Phrenology&lt;/h3&gt; 
&lt;h3&gt;Breaking up is hard to do&lt;/h3&gt; 
&lt;h3&gt;Aphasia&lt;/h3&gt; 
&lt;h3&gt;Dyslexia&lt;/h3&gt; 
&lt;h3&gt;Who&apos;s that?&lt;/h3&gt;
	</description>
    </item>
    <item>
      <title>8 Pillars of Greek Philosophy</title>
      <link>https://tedneward.github.io/Research/thinking/8-pillars-of-greek-philosophy/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">thinking/8-pillars-of-greek-philosophy/index.html</guid>
      	<description>
	&lt;ol&gt; 
 &lt;li&gt;Humanism 
  &lt;ol&gt; 
   &lt;li&gt;The Challenges of Humanness 
    &lt;ol&gt; 
     &lt;li&gt;Proper posture for humanity is upright and tall&lt;/li&gt; 
     &lt;li&gt;Man as potentially superior to the gods; it is man who must die, it’s only man who can most truly live. Gods are static and unchanging, but humanity possesses the capacity for growth.&lt;/li&gt; 
     &lt;li&gt;Achilles chose the short life of unending fame. Only in that way could he achieve the immortality he had been denied by birth. We all have a weakness we cannot see, but without which we would cease to be human.&lt;/li&gt; 
     &lt;li&gt;Our lives exist in order that we may compete an unfinished task, and it is by that task, that our lives are given meaning whatever the peri. Ulysses could not stay with Calypso because to do would have been to hide from himself, from the self he could be&lt;/li&gt; 
    &lt;/ol&gt; &lt;/li&gt; 
   &lt;li&gt;In Praise of Life: Humanism is the proud affirmation of both our promise and our duty. Greeks celebrated the human enterprise with all of their talent and might in pictures and stories. They expended great time and energy in endowing their pottery and coins with symmetrical form and harmonious decoration.&lt;/li&gt; 
   &lt;li&gt;The Test of Humanism: The modern world provides its own share of challenges; we must decide how we respond to these challenges. Anything humanly conceived, the Greeks are quick to remind us, can be humanly changed.&lt;/li&gt; 
   &lt;li&gt;Practicing Humanism: 
    &lt;ol&gt; 
     &lt;li&gt;Putting humanism into practice requires we define the term accurately. Implicit in &quot;humane&quot; is the notion that there are latent sensibilities in our character that must be cultivated if we are to attain our fullest stature. That task is the moral imperative of our existence.&lt;/li&gt; 
     &lt;li&gt;Humanism thus implies a commitment to the special abilities and talents we possess as human beings. To practical humanism in a personal way means first to look into ourselves to discover the particular abilities and talents that are ours. The second step is to actively apply them to our everyday lives.&lt;/li&gt; 
     &lt;li&gt;In taking the self-assessment, we come to see that our fulfillment as individuals depends, at least in part, on our engagement with the outside world. Becoming fully humane thus means opening ourselves to the needs of other human beings.&lt;/li&gt; 
     &lt;li&gt;&quot;Freedom and life are only earned by those who conquer them each day anew.&quot; (Geothe, end of Faust). Until we recognize our own intrinsic worth as human beings we will not make such an effort.&lt;/li&gt; 
    &lt;/ol&gt; &lt;/li&gt; 
   &lt;li&gt;Humanism is a philosophy of limitless possibilities tempered by the fact that we must someday die. It is marked as the tension between these two forces, passionate delight in life, and clear apprehension of its unalterable framework.&lt;/li&gt; 
  &lt;/ol&gt; &lt;/li&gt; 
 &lt;li&gt;Pursuit of Excellence 
  &lt;ol&gt; 
   &lt;li&gt;In the grammar of the Greek universe, humanity was not a noun, but a verb: moving, changing, evolving toward a fuller realization of its inner potential. Humanism implied a dynamic and progressive process of spiritual growth: the pursuit of excellence.&lt;/li&gt; 
   &lt;li&gt;Heroic Code: the compulsion to be the best&lt;/li&gt; 
   &lt;li&gt;From Olympus to Olympia: the Olympic games were really all about showing the gods what human beings were capable of doing if they bent mind and muscle to the task. The Games were meant to honor Zeus by human achievement, energized by the principle that man could best serve the gods by developing his own innate talents, in the process expanding the definition of what it means to be human. This is the inner justification for the Greek pursuit of excellence: the belief that within the human soul is a divine spark, and it is the duty of each of us to fan that spark into a flame.&lt;/li&gt; 
   &lt;li&gt;Wine and Inspiration: the Greeks also revered intellectual competition. Like the drinking of too much wine, the pursuit of excellence does not guarantee a happy outcome. Competitive striving also implied the risk of loss, but the ancient Greeks were congenial risk-takers. Heroism often courts tragedy. This is because the hero&apos;s life is a life lived at the outer edge of experience. At such an extremity, success becomes an intoxicant that can cause the individual to lose perspective on his own human limitations and in the end pay a higher price than he would ever have imagined. But to dare less would be to know less and to be less, an alternative the Greek culture rejected.&lt;/li&gt; 
   &lt;li&gt;The Meaning of Excellence: We cannot all be winners, but neither were the Greeks. Winning is not what life asks of us; it asks us to discover those things we are capable of doing well, and then to do them with all our heart and soul. The ancient Greeks never mistook winning for heroism. To be a hero, to pursue excellence, is to be a loving mother, to be a compassionate husband, to do our job well, with honor, integrity, and passion. To do so is to fulfill our finest nature; to do less is to lose our chance to experience the full meaning of being alive.&lt;/li&gt; 
   &lt;li&gt;The Price of Excellence: To pursue excellence, however, inevitably means to encounter frustration (the cruelest punishment of all, to the Greeks). Greek Hell was about being frustrated, not physical torture, because they were a race of achievers. Just being in the land of the dead constituted punishment because nothing could be accomplished there. In its dark and dank environment, the dead dwelt as disembodied ghosts, devoid of substance and purpose. If the price of excellence was frustration in the here and now, it was a price worth paying--without the savor of success the rest would be empty indeed. It is the choice of Achilles, but it is our choice, too, individually and collectively, to wallow in the warm mud of mediocrity, or climb to the mountain&apos;s cold and rocky heights.&lt;/li&gt; 
   &lt;li&gt;The Cost of Success: Achievement installs pride, but pride goeth before a fall. The myths of Niobe, Arachne; the arrogance of Agamemnon.&lt;/li&gt; 
  &lt;/ol&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Practice of Moderation&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Self-Knowledge&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Rationalism&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Restless Curiosity&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Love of Freedom&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Individualism&lt;/p&gt; &lt;/li&gt; 
&lt;/ol&gt;
	</description>
    </item>
    <item>
      <title>50 Big Ideas</title>
      <link>https://tedneward.github.io/Research/thinking/50-big-ideas/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">thinking/50-big-ideas/index.html</guid>
      	<description>
	&lt;h3&gt;Platonism&lt;/h3&gt; 
&lt;p&gt;&lt;em&gt;(towards transcendent reality)&lt;/em&gt;&lt;/p&gt; 
&lt;h3&gt;Aristotelianism&lt;/h3&gt; 
&lt;p&gt;&lt;em&gt;(&quot;The Master of Those Who Know&quot;)&lt;/em&gt;&lt;/p&gt; 
&lt;h3&gt;The Golden Rule&lt;/h3&gt; 
&lt;p&gt;&lt;em&gt;(Do as you would be done by)&lt;/em&gt;&lt;/p&gt; 
&lt;h3&gt;Altruism&lt;/h3&gt; 
&lt;p&gt;&lt;em&gt;(Selfless or selfish?)&lt;/em&gt;&lt;/p&gt; 
&lt;h3&gt;Liberty&lt;/h3&gt; 
&lt;p&gt;&lt;em&gt;(something worth dying for?)&lt;/em&gt;&lt;/p&gt; 
&lt;h3&gt;Tolerance&lt;/h3&gt; 
&lt;p&gt;&lt;em&gt;(a troubled and paradoxical virtue)&lt;/em&gt;&lt;/p&gt; 
&lt;h3&gt;Scepticism&lt;/h3&gt; 
&lt;p&gt;&lt;em&gt;(the scourge of drama)&lt;/em&gt;&lt;/p&gt; 
&lt;h3&gt;Reason&lt;/h3&gt; 
&lt;p&gt;&lt;em&gt;(Master or slave of the passions?)&lt;/em&gt;&lt;/p&gt; 
&lt;h3&gt;Punishment&lt;/h3&gt; 
&lt;p&gt;&lt;em&gt;(a necessary evil?)&lt;/em&gt;&lt;/p&gt; 
&lt;h3&gt;Materialism&lt;/h3&gt; 
&lt;p&gt;&lt;em&gt;(Matter over mind)&lt;/em&gt;&lt;/p&gt; 
&lt;h3&gt;Relativism&lt;/h3&gt; 
&lt;p&gt;&lt;em&gt;(anything goes?)&lt;/em&gt;&lt;/p&gt; 
&lt;h3&gt;Utilitarianism&lt;/h3&gt; 
&lt;p&gt;&lt;em&gt;(The greatest happiness principle)&lt;/em&gt;&lt;/p&gt; 
&lt;h3&gt;Existentialism&lt;/h3&gt; 
&lt;p&gt;&lt;em&gt;(Condemned to be free)&lt;/em&gt;&lt;/p&gt; 
&lt;h3&gt;Evil&lt;/h3&gt; 
&lt;p&gt;&lt;em&gt;(Is evil good for us?)&lt;/em&gt;&lt;/p&gt; 
&lt;h3&gt;Fate&lt;/h3&gt; 
&lt;p&gt;&lt;em&gt;(The iron hand of destiny)&lt;/em&gt;&lt;/p&gt; 
&lt;h3&gt;Soul&lt;/h3&gt; 
&lt;p&gt;&lt;em&gt;(A mystery no mind can hope to unravel)&lt;/em&gt;&lt;/p&gt; 
&lt;h3&gt;Faith&lt;/h3&gt; 
&lt;p&gt;&lt;em&gt;(belief that is blind to reason)&lt;/em&gt;&lt;/p&gt; 
&lt;h3&gt;Fundamentalism&lt;/h3&gt; 
&lt;p&gt;&lt;em&gt;(when faith becomes fanatic)&lt;/em&gt;&lt;/p&gt; 
&lt;h3&gt;Atheism&lt;/h3&gt; 
&lt;p&gt;&lt;em&gt;(beyond belief)&lt;/em&gt;&lt;/p&gt; 
&lt;h3&gt;Secularism&lt;/h3&gt; 
&lt;p&gt;&lt;em&gt;(not doing God)&lt;/em&gt;&lt;/p&gt; 
&lt;h3&gt;Creationism&lt;/h3&gt; 
&lt;p&gt;&lt;em&gt;(when world-views collide)&lt;/em&gt;&lt;/p&gt; 
&lt;h3&gt;War&lt;/h3&gt; 
&lt;p&gt;&lt;em&gt;(politics by other means)&lt;/em&gt;&lt;/p&gt; 
&lt;h3&gt;Duty&lt;/h3&gt; 
&lt;p&gt;&lt;em&gt;(thou shalt not... come what may?)&lt;/em&gt;&lt;/p&gt; 
&lt;h3&gt;Utopia&lt;/h3&gt; 
&lt;p&gt;&lt;em&gt;(Heaven or hell on earth)&lt;/em&gt;&lt;/p&gt; 
&lt;h3&gt;Liberalism&lt;/h3&gt; 
&lt;p&gt;&lt;em&gt;(Social progress and individual freedom)&lt;/em&gt;&lt;/p&gt; 
&lt;h3&gt;Democracy&lt;/h3&gt; 
&lt;p&gt;&lt;em&gt;(Bludgeoning of the people by the people?)&lt;/em&gt;&lt;/p&gt; 
&lt;h3&gt;Conservatism&lt;/h3&gt; 
&lt;p&gt;&lt;em&gt;(adherence to the old and tried)&lt;/em&gt;&lt;/p&gt; 
&lt;h3&gt;Imperialism&lt;/h3&gt; 
&lt;p&gt;&lt;em&gt;(to enslave or to set free?)&lt;/em&gt;&lt;/p&gt; 
&lt;h3&gt;Nationalism&lt;/h3&gt; 
&lt;p&gt;&lt;em&gt;(the measles of the human race)&lt;/em&gt;&lt;/p&gt; 
&lt;h3&gt;Multiculturalism&lt;/h3&gt; 
&lt;p&gt;&lt;em&gt;(melting pot or salad bowl?)&lt;/em&gt;&lt;/p&gt; 
&lt;h3&gt;The social contract&lt;/h3&gt; 
&lt;p&gt;&lt;em&gt;(society by consent)&lt;/em&gt;&lt;/p&gt; 
&lt;h3&gt;Republicanism&lt;/h3&gt; 
&lt;p&gt;&lt;em&gt;(Government of laws, not of men)&lt;/em&gt;&lt;/p&gt; 
&lt;h3&gt;Communism&lt;/h3&gt; 
&lt;p&gt;*(&quot;Workers of the world, unite!&quot;)&lt;br&gt; *&lt;/p&gt; 
&lt;h3&gt;Fascism&lt;/h3&gt; 
&lt;p&gt;&lt;em&gt;(a toxic synthesis of left &amp;amp; right)&lt;/em&gt;&lt;/p&gt; 
&lt;h3&gt;Racism&lt;/h3&gt; 
&lt;p&gt;&lt;em&gt;(the starless midnight of racism)&lt;/em&gt;&lt;/p&gt; 
&lt;h3&gt;Feminism&lt;/h3&gt; 
&lt;p&gt;&lt;em&gt;(equal, not the same)&lt;/em&gt;&lt;/p&gt; 
&lt;h3&gt;Islamism&lt;/h3&gt; 
&lt;p&gt;&lt;em&gt;(a clash of civilizations)&lt;/em&gt;&lt;/p&gt; 
&lt;h3&gt;Capitalism&lt;/h3&gt; 
&lt;p&gt;&lt;em&gt;(the unequal sharing of blessings)&lt;/em&gt;&lt;/p&gt; 
&lt;h3&gt;Globalization&lt;/h3&gt; 
&lt;p&gt;&lt;em&gt;(life in the global village)&lt;/em&gt;&lt;/p&gt; 
&lt;h3&gt;Classicism&lt;/h3&gt; 
&lt;p&gt;&lt;em&gt;(Rome&apos;s ancient genius)&lt;/em&gt;&lt;/p&gt; 
&lt;h3&gt;Romanticism&lt;/h3&gt; 
&lt;p&gt;&lt;em&gt;(The addition of strangeness to beauty)&lt;/em&gt;&lt;/p&gt; 
&lt;h3&gt;Modernism&lt;/h3&gt; 
&lt;p&gt;&lt;em&gt;(the shock of the new)&lt;/em&gt;&lt;/p&gt; 
&lt;h3&gt;Surrealism&lt;/h3&gt; 
&lt;p&gt;&lt;em&gt;(the omnipotence of dreams)&lt;/em&gt;&lt;/p&gt; 
&lt;h3&gt;Censorship&lt;/h3&gt; 
&lt;p&gt;&lt;em&gt;(protecting the servants)&lt;/em&gt;&lt;/p&gt; 
&lt;h3&gt;Evolution&lt;/h3&gt; 
&lt;p&gt;&lt;em&gt;(survival of the fittest)&lt;/em&gt;&lt;/p&gt; 
&lt;h3&gt;Gaia&lt;/h3&gt; 
&lt;p&gt;&lt;em&gt;(the quest for mother earth)&lt;/em&gt;&lt;/p&gt; 
&lt;h3&gt;Chaos&lt;/h3&gt; 
&lt;p&gt;&lt;em&gt;(the butterfly effect)&lt;/em&gt;&lt;/p&gt; 
&lt;h3&gt;Relativity&lt;/h3&gt; 
&lt;p&gt;&lt;em&gt;(the meaning of space &amp;amp; time)&lt;/em&gt;&lt;/p&gt; 
&lt;h3&gt;Quantum Mechanics&lt;/h3&gt; 
&lt;p&gt;&lt;em&gt;(the strange poetry of atoms)&lt;/em&gt;&lt;/p&gt; 
&lt;h3&gt;The Big Bang&lt;/h3&gt; 
&lt;p&gt;&lt;em&gt;(the beginning of space &amp;amp; time)&lt;/em&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Datasets</title>
      <link>https://tedneward.github.io/Research/teaching/datasets/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">teaching/datasets/index.html</guid>
      	<description>
	&lt;p&gt;From &lt;a href=&quot;https://www.linkedin.com/posts/ravena-o-04b39b68_10-free-datasets-to-start-building-your-activity-7072183693087322112-Azwy/&quot;&gt;Ravenna O&lt;/a&gt;:&lt;/p&gt; 
&lt;ol&gt; 
 &lt;li&gt; &lt;p&gt;Supermarket Sales: Historical record of sales data in 3 different supermarkets &lt;a href=&quot;https://lnkd.in/e86UpCMv&quot;&gt;https://lnkd.in/e86UpCMv&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Credit Card Fraud Detection: Anonymized credit card transactions labeled as fraudulent or genuine. &lt;a href=&quot;https://lnkd.in/eFTsZDCW&quot;&gt;https://lnkd.in/eFTsZDCW&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;FIFA 22 complete player dataset: The datasets provided include the players data for the Career Mode from FIFA 15 to FIFA 22. The data allows multiple comparisons for the same players across the last 8 version of the videogame. &lt;a href=&quot;https://lnkd.in/eDScdUUM&quot;&gt;https://lnkd.in/eDScdUUM&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Walmart Store Sales Forecasting: Use historical markdown data to predict store sales. &lt;a href=&quot;https://lnkd.in/eVT6h-CT&quot;&gt;https://lnkd.in/eVT6h-CT&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Netflix Movies and TV Shows: Listings of movies and tv shows on Netflix - Regularly Updated &lt;a href=&quot;https://lnkd.in/eZ3cduwK&quot;&gt;https://lnkd.in/eZ3cduwK&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;LinkedIn Data Analyst jobs listings: More than 8400 rows of data analyst jobs from USA, Canada and Africa. &lt;a href=&quot;https://lnkd.in/ezqxcmrE&quot;&gt;https://lnkd.in/ezqxcmrE&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Top 50 Fast-Food Chains in USA: The key features of this Dataset are - Fast-Food Chains, U.S. Systemwide Sales (Millions - U.S Dollars), Average Sales per Unit (Thousands - U.S Dollars), Franchised Stores, Company Stores, 2021 Total Units, Total Change in Units from 2020. &lt;a href=&quot;https://lnkd.in/esBjf5u4&quot;&gt;https://lnkd.in/esBjf5u4&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Amazon and Best Buy Electronics: This is a list of over 7,000 online reviews for 50 electronic products from websites like Amazon and Best Buy provided by Datafiniti&apos;s Product Database. The dataset includes the review date, source, rating, title, reviewer metadata, and more. &lt;a href=&quot;https://lnkd.in/e4fBZvJ3&quot;&gt;https://lnkd.in/e4fBZvJ3&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Forecasting Book Sales: Forecast sales of 8 book titles in 2418 locations &lt;a href=&quot;https://lnkd.in/eXHN2XsQ&quot;&gt;https://lnkd.in/eXHN2XsQ&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Real / Fake Job Posting Prediction: This dataset contains 18K job descriptions out of which about 800 are fake. The data consists of both textual information and meta-information about the jobs. The dataset can be used to create classification models which can learn the job descriptions which are fraudulent. &lt;a href=&quot;https://lnkd.in/e5SDDW9G&quot;&gt;https://lnkd.in/e5SDDW9G&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
&lt;/ol&gt;
	</description>
    </item>
    <item>
      <title>ScrollSets</title>
      <link>https://tedneward.github.io/Research/storage/scrollsets/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/scrollsets/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://breckyunits.com/scrollsets.html&quot;&gt;Website&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>SpiceDb</title>
      <link>https://tedneward.github.io/Research/storage/spicedb/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/spicedb/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://authzed.com/docs&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/authzed/spicedb&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Storj</title>
      <link>https://tedneward.github.io/Research/storage/storj/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/storj/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.storj.io/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/storj/storj&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>TDengine</title>
      <link>https://tedneward.github.io/Research/storage/tdengine/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/tdengine/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://tdengine.com/?en&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/taosdata/TDengine&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>TingoDB</title>
      <link>https://tedneward.github.io/Research/storage/tingodb/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/tingodb/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;http://www.tingodb.com/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/sergeyksv/tingodb&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>TypeDB</title>
      <link>https://tedneward.github.io/Research/storage/typedb/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/typedb/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://vaticle.com/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/vaticle/typedb&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://github.com/vaticle/typeql&quot;&gt;TypeQL Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Example schema for a social network graph:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;define

title sub attribute, value string;

event-date sub attribute, abstract, value datetime;
approved-date sub event-date;

## an abstract relation, only to be subtyped by other relations
request sub relation,
  abstract,
  owns approved-date,
  relates subject,
  relates requester,
  relates respondent;

friendship sub relation,
    relates friend,
    plays friend-request:friendship,
    plays friendship-list:listed;

## an example of subtyping in TypeDB
friend-request sub request,
    relates friendship as subject,
    relates friend-requester as requester,
    relates friend-respondent as respondent;

friendship-list sub relation,
    owns title,
    relates owner,
    relates listed;

person sub entity,
    plays friendship:friend,
    plays friend-request:friend-requester,
    plays friend-request:friend-respondent,
    plays friendship-list:owner;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Java client:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;package com.vaticle.doc.examples;

import com.vaticle.typedb.client.TypeDB;
import com.vaticle.typedb.client.api.connection.TypeDBClient;
import com.vaticle.typedb.client.api.connection.TypeDBOptions;
import com.vaticle.typedb.client.api.connection.TypeDBSession;
import com.vaticle.typedb.client.api.connection.TypeDBTransaction;

import static com.vaticle.typeql.lang.TypeQL.*;

import com.vaticle.typeql.lang.query.*;
import com.vaticle.typedb.client.api.answer.ConceptMap;

import java.util.stream.Stream;

import java.util.List;

public class SocialNetworkQuickstartQuery {
    public static void main(String[] args) {
        TypeDBClient client = TypeDB.coreClient(&quot;localhost:1729&quot;);
        try (TypeDBSession session = client.session(&quot;social_network&quot;, TypeDBSession.Type.DATA)) {
            
            TypeDBOptions options = TypeDBOptions.core().infer(true); // enable reasoning
            try (TypeDBTransaction transaction = session.transaction(TypeDBTransaction.Type.WRITE, options)) {
                
                TypeQLMatch query = match(
                        var().rel(&quot;employer&quot;, var(&quot;org&quot;)).rel(&quot;employee&quot;, var(&quot;per&quot;)).isa(&quot;employment&quot;),
                        var(&quot;per&quot;).has(&quot;full-name&quot;, var(&quot;per-fn&quot;)),
                        var(&quot;org&quot;).has(&quot;name&quot;, var(&quot;org-n&quot;))
                );

                Stream&amp;lt;ConceptMap&amp;gt; answers = transaction.query().match(query);

                answers.forEach(answer -&amp;gt; {
                    System.out.println(answer.get(&quot;per-fn&quot;).asAttribute().getValue());
                    System.out.println(answer.get(&quot;org-n&quot;).asAttribute().getValue());
                    System.out.println(&quot; - - - - - - - - &quot;);
                });
            }
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
	</description>
    </item>
    <item>
      <title>VelocityDB</title>
      <link>https://tedneward.github.io/Research/storage/velocitydb/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/velocitydb/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;http://velocitydb.com/&quot;&gt;Website&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Commercial with a free trial.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Weaver</title>
      <link>https://tedneward.github.io/Research/storage/weaver/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/weaver/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/dubey/weaver&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>YugaByteDB</title>
      <link>https://tedneward.github.io/Research/storage/yugabytedb/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/yugabytedb/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.yugabyte.com/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/yugabyte&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;It allows you to host your database on multiple clouds at the same time thereby giving you more control over your database system and eliminating vendor lock-in. This also enables you to deploy your cloud instance in different regions which in turn provides you with a higher degree of fail tolerance for your database. YugaByte supports both SQL and NoSQL APIs. This gives developers the flexibility and freedom to choose the type of API that works best with respect to their familiarity and use case. Besides ensuring high performance and scalability, it also provides high availability.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>sharedb</title>
      <link>https://tedneward.github.io/Research/storage/sharedb/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/sharedb/index.html</guid>
      	<description>
	&lt;p&gt;&quot;ShareDB is a realtime database backend based on Operational Transformation (OT) of JSON documents. It is the realtime backend for the DerbyJS web application framework.&lt;/p&gt; 
&lt;p&gt;&quot;Features:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Realtime synchronization of any JSON document&lt;/li&gt; 
 &lt;li&gt;Concurrent multi-user collaboration&lt;/li&gt; 
 &lt;li&gt;Synchronous editing API with asynchronous eventual consistency&lt;/li&gt; 
 &lt;li&gt;Realtime query subscriptions&lt;/li&gt; 
 &lt;li&gt;Simple integration with any database - MongoDB, PostgresQL (experimental)&lt;/li&gt; 
 &lt;li&gt;Horizontally scalable with pub/sub integration&lt;/li&gt; 
 &lt;li&gt;Projections to select desired fields from documents and operations&lt;/li&gt; 
 &lt;li&gt;Middleware for implementing access control and custom extensions&lt;/li&gt; 
 &lt;li&gt;Ideal for use in browsers or on the server&lt;/li&gt; 
 &lt;li&gt;Offline change syncing upon reconnection&lt;/li&gt; 
 &lt;li&gt;In-memory implementations of database and pub/sub for unit testing&quot;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;&lt;a href=&quot;https://github.com/share/sharedb&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>SQLite</title>
      <link>https://tedneward.github.io/Research/storage/sqlite/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/sqlite/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://sqlite.org/index.html&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://sqlite.org/c3ref/intro.html&quot;&gt;C/C++ Interface&lt;/a&gt; | &lt;a href=&quot;https://sqlite.org/tclsqlite.html&quot;&gt;TCL Interface&lt;/a&gt; | &lt;a href=&quot;https://sqlite.org/src&quot;&gt;Source&lt;/a&gt; | &lt;a href=&quot;https://www.sqlite.org/fileformat.html&quot;&gt;File format for SQLite databases&lt;/a&gt; and &lt;a href=&quot;https://sqlite.org/fileformat2.html&quot;&gt;here?&lt;/a&gt; | &lt;a href=&quot;https://sqlite.org/appfileformat.html&quot;&gt;SQLite as an &quot;application format&quot;&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://www.tutorialspoint.com/sqlite&quot;&gt;SQLite Tutorial&lt;/a&gt; | &lt;a href=&quot;https://sqlite-internal.pages.dev/&quot;&gt;SQLite File Format Viewer&lt;/a&gt; (&lt;a href=&quot;https://github.com/invisal/sqlite-internal&quot;&gt;Source&lt;/a&gt;)&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://github.com/proofrock/ws4sqlite&quot;&gt;WS4SQLite&lt;/a&gt;: Query sqlite via http&lt;/p&gt; 
&lt;h2&gt;Articles&lt;/h2&gt; 
&lt;p&gt;How does SQLite work? &lt;a href=&quot;https://jvns.ca/blog/2014/09/27/how-does-sqlite-work-part-1-pages/&quot;&gt;Part 1&lt;/a&gt; | &lt;a href=&quot;https://jvns.ca/blog/2014/10/02/how-does-sqlite-work-part-2-btrees/&quot;&gt;Part 2&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://fly.io/blog/sqlite-virtual-machine/&quot;&gt;How the SQLite VM works&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://jlongster.com/future-sql-web&quot;&gt;&quot;A future for SQL on the Web&quot;&lt;/a&gt;: Using &lt;a href=&quot;/storage/indexeddb&quot;&gt;IndexedDB&lt;/a&gt; in the browser as a &quot;file system&quot; underneath a SQLite implementation compiled to WASM. Resulting project is &lt;a href=&quot;https://github.com/jlongster/absurd-sql&quot;&gt;absurd-sql&lt;/a&gt;. Makes use of &lt;a href=&quot;/storage/sqljs&quot;&gt;sql.js&lt;/a&gt; and a few source changes to it.&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://christine.website/blog/sqlite-json-munge-2022-01-04&quot;&gt;&quot;Bashing JSON into Shape with SQLite&quot;&lt;/a&gt;: &quot;SQLIte added JSON functions to allow you to munge and modify JSON data in whatever creative ways you want.&quot;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://tirkarthi.github.io/programming/2022/02/26/sqlite-json-improvements.html&quot;&gt;&quot;JSON improvements in SQLite 3.38.0&quot;&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://medium.com/capital-one-tech/experimenting-with-sqlite-in-ios-ae9dec92dbaf&quot;&gt;&quot;Experimenting With SQLite in iOS&quot;&lt;/a&gt;&lt;/p&gt; 
&lt;h2&gt;Plugins/additions/enhancements&lt;/h2&gt; 
&lt;p&gt;&lt;a href=&quot;https://github.com/vlcn-io/cr-sqlite&quot;&gt;cr-sqlite&lt;/a&gt;: a loadable SQLite extension by Matt Wonlaw that &quot;allows merging different SQLite databases together that have taken independent writes&quot;.&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://til.simonwillison.net/sqlite/cr-sqlite-macos&quot;&gt;Trying cr-sqlite out on macOS&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;&lt;a href=&quot;https://github.com/maxpert/marmot&quot;&gt;Marmot&lt;/a&gt;: A distributed SQLite replicator built on top of NATS.&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://www.zetetic.net/sqlcipher/&quot;&gt;SQLCypher&lt;/a&gt; is an extension to SQLite adding encryption. Open-source and commercial.&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://dirtylittlesql.com/&quot;&gt;A fast SQLite PWA notebook for CSV files&lt;/a&gt; (&lt;a href=&quot;https://github.com/mwenge/dirtylittlesql.com&quot;&gt;Source&lt;/a&gt;, uses &lt;a href=&quot;https://github.com/sql-js/sql.js&quot;&gt;sql.js&lt;/a&gt; (The database is a web-assembly version of SQLite called sql.js that runs in your browser.), &lt;a href=&quot;http://www.dessus.com/files/vsv.c&quot;&gt;VSV&lt;/a&gt; (It also uses a SQLite extension called vsv to load delimited text files quickly.), &lt;a href=&quot;https://codemirror.net/&quot;&gt;Codemirror&lt;/a&gt; (Syntax highlighting), &lt;a href=&quot;https://sheetjs.com/&quot;&gt;sheet.js&lt;/a&gt; (Excel and Openoffice support.), &lt;a href=&quot;https://chartjs.org/&quot;&gt;chart.js&lt;/a&gt; (Charts), and &lt;a href=&quot;https://github.com/localForage/localForage&quot;&gt;LocalForage&lt;/a&gt; (IndexedDB for efficient local storage.) under the hood.)&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://sqlitestudio.pl/&quot;&gt;SQLStudio&lt;/a&gt; (&lt;a href=&quot;https://github.com/pawelsalawa/sqlitestudio&quot;&gt;Source&lt;/a&gt;): A free, open source, multi-platform SQLite database manager.&lt;/p&gt; 
&lt;h2&gt;Access&lt;/h2&gt; 
&lt;h3&gt;Typescript&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://kysely.dev/&quot;&gt;Kysely&lt;/a&gt; (&lt;a href=&quot;https://github.com/kysely-org/kysely&quot;&gt;Source&lt;/a&gt;): The type-safe SQL query builder for TypeScript&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Swift/iOS&lt;/h3&gt; 
&lt;p&gt;By default, SQLite from Swift/iOS is an exercise in C integration. Numerous wrappers are available.&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/stephencelis/SQLite.swift&quot;&gt;SQLite.swift&lt;/a&gt;: Type-safe Swift wrapper over sqlite3 C API&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/wildthink/SQift&quot;&gt;Sqift&lt;/a&gt;: Powerful Swift wrapper for SQLite&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Java&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/xerial/sqlite-jdbc&quot;&gt;SQLite-jdbc&lt;/a&gt;: Straight JDBC driver for SQLite&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;C#/.NET&lt;/h3&gt; 
&lt;p&gt;&lt;a href=&quot;https://docs.microsoft.com/en-us/dotnet/standard/data/sqlite/&quot;&gt;Microsoft.Data.Sqlite&lt;/a&gt;: &lt;code&gt;dotnet add package Microsoft.Data.Sqlite&lt;/code&gt;&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-cs&quot;&gt;using (var connection = new SqliteConnection(&quot;Data Source=hello.db&quot;))
{
    connection.Open();

    var command = connection.CreateCommand();
    command.CommandText =
    @&quot;
        SELECT name
        FROM user
        WHERE id = $id
    &quot;;
    command.Parameters.AddWithValue(&quot;$id&quot;, id);

    using (var reader = command.ExecuteReader())
    {
        while (reader.Read())
        {
            var name = reader.GetString(0);

            Console.WriteLine($&quot;Hello, {name}!&quot;);
        }
    }
}
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;Native&lt;/h3&gt; 
&lt;p&gt;&lt;a href=&quot;https://cgsql.dev/&quot;&gt;CG/SQL&lt;/a&gt; is a code generation system for the popular SQLite library that allows developers to write stored procedures in a variant of Transact-SQL (T-SQL) and compile them into C code that uses SQLite’s C API to do the coded operations. CG/SQL enables engineers to create highly complex stored procedures with very large queries, without the manual code checking that existing methods require. (Produces C source that can be compiled, and the language is flexible enough to do a fair amount of typical C dev without leaving CQL.)&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://cgsql.dev/docs/introduction&quot;&gt;Docs&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://cgsql.dev/cql-guide/ch01&quot;&gt;Language Guide&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;Internals &lt;a href=&quot;https://cgsql.dev/cql-guide/int01&quot;&gt;Part 1&lt;/a&gt;, &lt;a href=&quot;https://cgsql.dev/cql-guide/int02&quot;&gt;Part 2&lt;/a&gt;: An interesting look into how it works&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/facebookincubator/CG-SQL&quot;&gt;Source&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>SuperDB</title>
      <link>https://tedneward.github.io/Research/storage/superdb/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/superdb/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://superdb.org/docs/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/brimdata/super&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;hr&gt; 
&lt;p&gt;Used to be the &lt;a href=&quot;https://zed.brimdata.io/&quot;&gt;Zed Project and language&lt;/a&gt; &lt;a href=&quot;https://github.com/brimdata&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&quot;Zed&quot; is an umbrella term that describes a number of different elements of the system:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;The Zed data model is the abstract definition of the data types and semantics that underlie the Zed formats.&lt;/li&gt; 
 &lt;li&gt;The Zed formats are a family of sequential (ZNG), columnar (VNG), and human-readable (ZSON) formats that all adhere to the same abstract Zed data model.&lt;/li&gt; 
 &lt;li&gt;A Zed lake is a collection of Zed data stored across one or more data pools with ACID commit semantics and accessed via a Git-like API.&lt;/li&gt; 
 &lt;li&gt;The Zed language is the system&apos;s pipeline language for performing queries, searches, analytics, transformations, or any of the above combined together.&lt;/li&gt; 
 &lt;li&gt;A Zed query is a Zed script that performs search and/or analytics.&lt;/li&gt; 
 &lt;li&gt;A Zed shaper is a Zed script that performs data transformation to shape the input data into the desired set of organizing Zed data types called &quot;shapes&quot;, which are traditionally called schemas in relational systems but are much more flexible in the Zed system.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;--&lt;/p&gt; 
&lt;p&gt;Also related: The &lt;a href=&quot;https://zui.brimdata.io/docs&quot;&gt;Zui Desktop Application&lt;/a&gt;, a graphical user interface for exploring data in Zed lakes.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>TerminusDB</title>
      <link>https://tedneward.github.io/Research/storage/terminusdb/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/terminusdb/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://terminusdb.com/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/terminusdb/terminusdb&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Apache TinkerPop</title>
      <link>https://tedneward.github.io/Research/storage/tinkerpop/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/tinkerpop/index.html</guid>
      	<description>
	&lt;p&gt;&quot;Apache TinkerPop™ is an open source, vendor-agnostic, graph computing framework distributed under the commercial friendly Apache2 license. When a data system is TinkerPop-enabled, its users are able to model their domain as a graph and analyze that graph using the Gremlin graph traversal language. Furthermore, all TinkerPop-enabled systems integrate with one another allowing them to easily expand their offerings as well as allowing users to choose the appropriate graph technology for their application. Sometimes an application is best served by an in-memory, transactional graph database. Sometimes a multi-machine distributed graph database will do the job. Or perhaps the application requires both a distributed graph database for real-time queries and, in parallel, a Big(Graph)Data processor for batch analytics. Whatever the application&apos;s requirements, there exists a TinkerPop-enabled graph system out there to meet its needs.&quot;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;http://tinkerpop.apache.org/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://www.apache.org/dyn/closer.lua/tinkerpop/&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>UnQLite</title>
      <link>https://tedneward.github.io/Research/storage/unqlite/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/unqlite/index.html</guid>
      	<description>
	&lt;p&gt;&quot;UnQLite is a in-process software library which implements a self-contained, serverless, zero-configuration, transactional NoSQL database engine. UnQLite is a document store database similar to MongoDB, Redis, CouchDB etc. as well a standard Key/Value store similar to BerkeleyDB, LevelDB, etc.&quot;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://unqlite.org/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/symisc/unqlite&quot;&gt;Github&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&quot;Jx9 is the embedded scripting language which power the document-store interface to UnQLite. Jx9 is a Turing complete programming language based on JSON and implemented as a library in the UnQLite core.&quot; (&lt;a href=&quot;https://unqlite.org/jx9.html&quot;&gt;Website&lt;/a&gt;)&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>VeloxDB</title>
      <link>https://tedneward.github.io/Research/storage/veloxdb/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/veloxdb/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.vlxdb.com/index.html&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://www.vlxdb.com/guide/introduction.html&quot;&gt;Docs&lt;/a&gt; | &lt;a href=&quot;https://github.com/VeloxDB/VeloxDB&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://dev.to/defufna/introducing-veloxdb-26j1&quot;&gt;&quot;Introducing VeloxDB&quot;&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Web Storage</title>
      <link>https://tedneward.github.io/Research/storage/webstorage/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/webstorage/index.html</guid>
      	<description>
	&lt;p&gt;&quot;The two mechanisms within Web Storage are as follows:&lt;br&gt; * sessionStorage maintains a separate storage area for each given origin that&apos;s available for the duration of the page session (as long as the browser is open, including page reloads and restores)&lt;br&gt; * Stores data only for a session, meaning that the data is stored until the browser (or tab) is closed.&lt;br&gt; * Data is never transferred to the server.&lt;br&gt; * Storage limit is larger than a cookie (at most 5MB).&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;localStorage does the same thing, but persists even when the browser is closed and reopened.&lt;/li&gt; 
 &lt;li&gt;Stores data with no expiration date, and gets cleared only through JavaScript, or clearing the Browser cache / Locally Stored Data.&lt;/li&gt; 
 &lt;li&gt;Storage limit is the maximum amongst the three.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;These mechanisms are available via the &lt;code&gt;Window.sessionStorage&lt;/code&gt; and &lt;code&gt;Window.localStorage&lt;/code&gt; properties (to be more precise, in supporting browsers the Window object implements the &lt;code&gt;WindowLocalStorage&lt;/code&gt; and &lt;code&gt;WindowSessionStorage&lt;/code&gt; objects, which the &lt;code&gt;localStorage&lt;/code&gt; and &lt;code&gt;sessionStorage&lt;/code&gt; properties hang off) — invoking one of these will create an instance of the &lt;code&gt;Storage&lt;/code&gt; object, through which data items can be set, retrieved and removed. A different &lt;code&gt;Storage&lt;/code&gt; object is used for the &lt;code&gt;sessionStorage&lt;/code&gt; and &lt;code&gt;localStorage&lt;/code&gt; for each origin — they function and are controlled separately.&quot;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/Web_Storage_API&quot;&gt;Website&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Zvec</title>
      <link>https://tedneward.github.io/Research/storage/zvec/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/zvec/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://zvec.org/en/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/alibaba/zvec&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p align=&quot;center&quot;&gt; &lt;a href=&quot;https://zvec.org/en/docs/quickstart/&quot;&gt;🚀 &lt;strong&gt;Quickstart&lt;/strong&gt; &lt;/a&gt; | &lt;a href=&quot;https://zvec.org/en/&quot;&gt;🏠 &lt;strong&gt;Home&lt;/strong&gt; &lt;/a&gt; | &lt;a href=&quot;https://zvec.org/en/docs/&quot;&gt;📚 &lt;strong&gt;Docs&lt;/strong&gt; &lt;/a&gt; | &lt;a href=&quot;https://zvec.org/en/docs/benchmarks/&quot;&gt;📊 &lt;strong&gt;Benchmarks&lt;/strong&gt; &lt;/a&gt; | &lt;a href=&quot;https://discord.gg/rKddFBBu9z&quot;&gt;🎮 &lt;strong&gt;Discord&lt;/strong&gt; &lt;/a&gt; &lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Zvec&lt;/strong&gt; is an open-source, in-process vector database — lightweight, lightning-fast, and designed to embed directly into applications. Built on &lt;strong&gt;Proxima&lt;/strong&gt; (Alibaba&apos;s battle-tested vector search engine), it delivers production-grade, low-latency, scalable similarity search with minimal setup.&lt;/p&gt; 
&lt;h2&gt;💫 Features&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;strong&gt;Blazing Fast&lt;/strong&gt;: Searches billions of vectors in milliseconds.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Simple, Just Works&lt;/strong&gt;: &lt;a href=&quot;#-installation&quot;&gt;Install&lt;/a&gt; and start searching in seconds. No servers, no config, no fuss.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Dense + Sparse Vectors&lt;/strong&gt;: Work with both dense and sparse embeddings, with native support for multi-vector queries in a single call.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Hybrid Search&lt;/strong&gt;: Combine semantic similarity with structured filters for precise results.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Runs Anywhere&lt;/strong&gt;: As an in-process library, Zvec runs wherever your code runs — notebooks, servers, CLI tools, or even edge devices.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;📦 Installation&lt;/h2&gt; 
&lt;h3&gt;&lt;a href=&quot;https://pypi.org/project/zvec/&quot;&gt;Python&lt;/a&gt;&lt;/h3&gt; 
&lt;p&gt;&lt;strong&gt;Requirements&lt;/strong&gt;: Python 3.10 - 3.12&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;pip install zvec
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;&lt;a href=&quot;https://www.npmjs.com/package/@zvec/zvec&quot;&gt;Node.js&lt;/a&gt;&lt;/h3&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;npm install @zvec/zvec
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;✅ Supported Platforms&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;Linux (x86_64, ARM64)&lt;/li&gt; 
 &lt;li&gt;macOS (ARM64)&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;🛠️ Building from Source&lt;/h3&gt; 
&lt;p&gt;If you prefer to build Zvec from source, please check the &lt;a href=&quot;https://zvec.org/en/docs/build/&quot;&gt;Building from Source&lt;/a&gt; guide.&lt;/p&gt; 
&lt;h2&gt;⚡ One-Minute Example&lt;/h2&gt; 
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;import zvec

# Define collection schema
schema = zvec.CollectionSchema(
    name=&quot;example&quot;,
    vectors=zvec.VectorSchema(&quot;embedding&quot;, zvec.DataType.VECTOR_FP32, 4),
)

# Create collection
collection = zvec.create_and_open(path=&quot;./zvec_example&quot;, schema=schema)

# Insert documents
collection.insert([
    zvec.Doc(id=&quot;doc_1&quot;, vectors={&quot;embedding&quot;: [0.1, 0.2, 0.3, 0.4]}),
    zvec.Doc(id=&quot;doc_2&quot;, vectors={&quot;embedding&quot;: [0.2, 0.3, 0.4, 0.1]}),
])

# Search by vector similarity
results = collection.query(
    zvec.VectorQuery(&quot;embedding&quot;, vector=[0.4, 0.3, 0.3, 0.1]),
    topk=10
)

# Results: list of {&apos;id&apos;: str, &apos;score&apos;: float, ...}, sorted by relevance
print(results)
&lt;/code&gt;&lt;/pre&gt; 
&lt;h2&gt;📈 Performance at Scale&lt;/h2&gt; 
&lt;p&gt;Zvec delivers exceptional speed and efficiency, making it ideal for demanding production workloads.&lt;/p&gt; 
&lt;p&gt;&lt;img src=&quot;https://zvec.oss-cn-hongkong.aliyuncs.com/qps_10M.svg&quot; width=&quot;800&quot; alt=&quot;Zvec Performance Benchmarks&quot;&gt;&lt;/p&gt; 
&lt;p&gt;For detailed benchmark methodology, configurations, and complete results, please see our &lt;a href=&quot;https://zvec.org/en/docs/benchmarks/&quot;&gt;Benchmarks documentation&lt;/a&gt;.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>SimpleDB</title>
      <link>https://tedneward.github.io/Research/storage/simpledb/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/simpledb/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;http://www.cs.bc.edu/~sciore/simpledb/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;http://www.cs.bc.edu/%7Esciore/simpledb/SimpleDB_3.4.zip&quot;&gt;Code&lt;/a&gt; (v3.4)&lt;/p&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;SimpleDB is a multi-user transactional database server written in Java, which interacts with Java client programs via JDBC. The system is intended for pedagogical use only. The code is clean and compact. The APIs are straightforward. The learning curve is relatively small. Everything about it is geared towards improving the experience of a database system internals course. Consequently, the system is intentionally bare-bones. It implements only a small fraction of SQL and JDBC, and does little or no error checking. Although it is a great teaching tool, I can&apos;t imagine that anyone would want to use it for anything else.&lt;/p&gt; 
 &lt;p&gt;The SimpleDB code is an integral part of my textbook &lt;a href=&quot;https://www.amazon.com/dp/3030338355/&quot;&gt;Database Design and Implementation&lt;/a&gt;, published by Springer. If you are interested in understanding how (and why) the software works, your best bet is to take a look at the text.&lt;/p&gt; 
 &lt;p&gt;I teach a course at Boston College (CSCI3357: Database Systems and Implementation), which does not require previous database knowledge. ... Here are the &lt;a href=&quot;http://www.cs.bc.edu/~sciore/simpledb/hwassignments.zip&quot;&gt;homework assignments&lt;/a&gt; that I used in my most recent offering of the course.&lt;/p&gt; 
&lt;/blockquote&gt;
	</description>
    </item>
    <item>
      <title>SQL.js (SQLite in JavaScript)</title>
      <link>https://tedneward.github.io/Research/storage/sqljs/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/sqljs/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;http://sql.js.org/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/sql-js/sql.js&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&quot;sql.js is a port of &lt;a href=&quot;sqlite.html&quot;&gt;SQLite&lt;/a&gt; to Webassembly, by compiling the SQLite C code with Emscripten, with contributed math and string extension functions included. It uses a virtual database file stored in memory, and thus doesn&apos;t persist the changes made to the database. However, it allows you to import any existing sqlite file, and to export the created database as a JavaScript typed array.&lt;/p&gt; 
&lt;p&gt;&quot;There are no C bindings or node-gyp compilation here, sql.js is a simple JavaScript file, that can be used like any traditional JavaScript library. If you are building a native application in JavaScript (using Electron for instance), or are working in node.js, you will likely prefer to use a native binding of SQLite to JavaScript.&quot;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>SurrealDB</title>
      <link>https://tedneward.github.io/Research/storage/surrealdb/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/surrealdb/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://surrealdb.com&quot;&gt;Website&lt;/a&gt; |&lt;/p&gt; 
&lt;p&gt;When it comes to data modeling it’s extremely flexible, making it an ideal choice for recommendation engines, social networks, etc. In this regard, it’s similar to the popular graph database Neo4J.&lt;/p&gt; 
&lt;p&gt;It’s also very simple to use with any SQL type query language and also provides the ability to perform real-time queries efficiently.&lt;/p&gt; 
&lt;p&gt;For instance, here’s an insertion query in SurrealQL that looks almost identical to an SQL insert query:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;INSERT INTO company {
	name: &apos;Siddhant&apos;,
	age: 24,
	hobbies: [&apos;technical writing&apos;, &apos;basketball&apos;]
};
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Moreover, you can use SurrealQL to directly connect your Surreal DB to your client applications.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>TileDB</title>
      <link>https://tedneward.github.io/Research/storage/tiledb/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/tiledb/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.tiledb.com/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/TileDB-Inc/TileDB&quot;&gt;Source&lt;/a&gt; |&lt;/p&gt; 
&lt;p&gt;APIs:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;C (examples, API docs)&lt;/li&gt; 
 &lt;li&gt;C++ (examples, API docs)&lt;/li&gt; 
 &lt;li&gt;Python&lt;/li&gt; 
 &lt;li&gt;R&lt;/li&gt; 
 &lt;li&gt;Java&lt;/li&gt; 
 &lt;li&gt;Go&lt;/li&gt; 
 &lt;li&gt;C#&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Titan</title>
      <link>https://tedneward.github.io/Research/storage/titan/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/titan/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;http://titan.thinkaurelius.com/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/thinkaurelius/titan/&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Titan is a transactional database that can support thousands of concurrent users executing complex graph traversals in real time.&lt;/p&gt; 
&lt;p&gt;In addition, Titan provides the following features:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Elastic and linear scalability for a growing data and user base.&lt;/li&gt; 
 &lt;li&gt;Data distribution and replication for performance and fault tolerance.&lt;/li&gt; 
 &lt;li&gt;Multi-datacenter high availability and hot backups.&lt;/li&gt; 
 &lt;li&gt;Support for ACID and eventual consistency.&lt;/li&gt; 
 &lt;li&gt;Support for various storage backends: 
  &lt;ul&gt; 
   &lt;li&gt;Apache &lt;a href=&quot;../cassandra&quot;&gt;Cassandra&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Apache &lt;a href=&quot;../hbase&quot;&gt;HBase&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Oracle &lt;a href=&quot;../berkeleydb&quot;&gt;BerkeleyDB&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Support for global graph data analytics, reporting, and ETL through integration with big data platforms: 
  &lt;ul&gt; 
   &lt;li&gt;Apache Spark&lt;/li&gt; 
   &lt;li&gt;Apache Giraph&lt;/li&gt; 
   &lt;li&gt;Apache Hadoop&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Support for geo, numeric range, and full-text search via: 
  &lt;ul&gt; 
   &lt;li&gt;ElasticSearch&lt;/li&gt; 
   &lt;li&gt;Solr&lt;/li&gt; 
   &lt;li&gt;Lucene&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Native integration with the TinkerPop graph stack: 
  &lt;ul&gt; 
   &lt;li&gt;Gremlin graph query language&lt;/li&gt; 
   &lt;li&gt;Gremlin graph server&lt;/li&gt; 
   &lt;li&gt;Gremlin applications&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Quick start&lt;/h3&gt; 
&lt;pre&gt;&lt;code&gt;&amp;lt;dependency&amp;gt;
   &amp;lt;groupId&amp;gt;com.thinkaurelius.titan&amp;lt;/groupId&amp;gt;
   &amp;lt;artifactId&amp;gt;titan-core&amp;lt;/artifactId&amp;gt;
   &amp;lt;version&amp;gt;1.0.0&amp;lt;/version&amp;gt;
&amp;lt;/dependency&amp;gt;
&amp;lt;!-- core, all, cassandra, hbase, berkeleyje, es, lucene --&amp;gt;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;then&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;// who is hercules&apos; grandfather?
g.V.has(&apos;name&apos;,&apos;hercules&apos;).out(&apos;father&apos;).out(&apos;father&apos;).name
&lt;/code&gt;&lt;/pre&gt;
	</description>
    </item>
    <item>
      <title>UOR (Foundation)</title>
      <link>https://tedneward.github.io/Research/storage/uor/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/uor/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.uor.foundation/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/UOR-Foundation&quot;&gt;Source&lt;/a&gt; | &lt;a href=&quot;https://uor-foundation.discourse.group/&quot;&gt;Discourse Group&lt;/a&gt;&lt;/p&gt; 
&lt;h2&gt;Universal Object Reference (UOR)&lt;/h2&gt; 
&lt;p&gt;What if every piece of data on the internet, including every website, API, AI model, or configuration file, could be referenced, trusted, and composed like code?&lt;/p&gt; 
&lt;p&gt;Universal Object Reference (UOR) makes this possible.&lt;/p&gt; 
&lt;p&gt;UOR is an open source data system that reimagines the internet as a single, structured and composable dataset. It treats everything as an object. Each is uniquely identified by a cryptographic hash and described by its intrinsic attributes, such as size, media type and content digest, rather than by location.&lt;/p&gt; 
&lt;p&gt;This Rosetta Stone for data changes the paradigm.&lt;/p&gt; 
&lt;p&gt;Instead of chasing data by where it lives, you access it by what it is. The result is secure, deterministic, and interoperable across systems.&lt;/p&gt; 
&lt;p&gt;The outcome is a universal layer for decentralized, serverless and composable infrastructure. It invites developers, researchers and architects to help build the next foundation of the internet.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Vitess</title>
      <link>https://tedneward.github.io/Research/storage/vitess/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/vitess/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://vitess.io/&quot;&gt;Website&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>WhiteDB</title>
      <link>https://tedneward.github.io/Research/storage/whitedb/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/whitedb/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;http://whitedb.org/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/priitj/whitedb&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;h3&gt;Project goals&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;speed&lt;/li&gt; 
 &lt;li&gt;portability&lt;/li&gt; 
 &lt;li&gt;simplicity and small footprint&lt;/li&gt; 
 &lt;li&gt;low memory usage&lt;/li&gt; 
 &lt;li&gt;easy to use in embedded systems&lt;/li&gt; 
 &lt;li&gt;graph database applications&lt;/li&gt; 
 &lt;li&gt;extended rdf database applications&lt;/li&gt; 
 &lt;li&gt;fast interprocess communication&lt;br&gt; For the next version we&apos;re working on JSON support and a REST tool.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Data storage&lt;/h3&gt; 
&lt;p&gt;Data is kept in shared memory by default, making all the data accessible to separate processes.&lt;/p&gt; 
&lt;p&gt;Each database record is a tuple of N elements, encoded in WhiteDB-s simple compact format. You can store both conventional datatypes and direct pointers to records: the latter enables highly efficient traversal of complex data.&lt;/p&gt; 
&lt;h3&gt;Supported features&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;indexes (T-tree)&lt;/li&gt; 
 &lt;li&gt;persistence through logging and memory dumps&lt;/li&gt; 
 &lt;li&gt;concurrency through locking&lt;/li&gt; 
 &lt;li&gt;limited queries (conjunctive only)&lt;/li&gt; 
 &lt;li&gt;CSV and RDF support&lt;/li&gt; 
 &lt;li&gt;Linux and Windows&lt;/li&gt; 
 &lt;li&gt;Python bindings&lt;/li&gt; 
 &lt;li&gt;command line utility tools&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>sones</title>
      <link>https://tedneward.github.io/Research/storage/sones/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/sones/index.html</guid>
      	<description>
	&lt;p&gt;No updates for 8 years (2013?).&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://github.com/sones/sones&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Microsoft SQL Server</title>
      <link>https://tedneward.github.io/Research/storage/sqlserver/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/sqlserver/index.html</guid>
      	<description>
	&lt;h3&gt;Tools&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/tsqllint/tsqllint&quot;&gt;tsqllint&lt;/a&gt;: Configurable linting for TSQL. Install with &lt;code&gt;$ dotnet tool install --global TSQLLint&lt;/code&gt; or &lt;code&gt;brew tap tsqllint/homebrew-tsqllint; brew install tsqllint&lt;/code&gt; for macOS/Linux or &lt;code&gt;npm install tsqllint -t&lt;/code&gt; for npm. Supports the creation of custom plugins (implemenent an interface in CLR code).&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/davebally/TSQL-Smells&quot;&gt;TSQL-Smells&lt;/a&gt;: &quot;TSQL Smells Finder&quot;. Last meaningful activity in 2016/2018.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Reading&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.red-gate.com/community/books/ssc-7&quot;&gt;Best of SQLServerCentral.com Vol 7&lt;/a&gt; *(RedGate, By SQLServerCentral Authors)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.red-gate.com/community/books/sql-server-maintenance-plans&quot;&gt;Brad&apos;s Sure Guide to SQL Server Maintenance Plans&lt;/a&gt; - Brad McGehee (PDF) (email address &lt;em&gt;requested&lt;/em&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.red-gate.com/library/defensive-database-programming&quot;&gt;Defensive Database Programming&lt;/a&gt; - Alex Kuznetsov (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.red-gate.com/library/fundamentals-of-sql-server-2012-replication&quot;&gt;Fundamentals Of SQL Server 2012 Replication&lt;/a&gt; - Sebastian Meine (PDF) (email address &lt;em&gt;requested&lt;/em&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.red-gate.com/community/books/exceptional-dba-book&quot;&gt;How to Become an Exceptional DBA, Second edition&lt;/a&gt; - Brad McGehee (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.red-gate.com/products/sql-development/sql-prompt/entrypage/sql-query-optimizer-ebook3&quot;&gt;Inside the SQL Server Query Optimizer&lt;/a&gt; - Benjamin Nevarez (PDF) (email address &lt;em&gt;requested&lt;/em&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://social.technet.microsoft.com/wiki/contents/articles/11608.e-book-gallery-for-microsoft-technologies-en.aspx#IntroducingMicrosoftSQLServer2008R2&quot;&gt;Introducing Microsoft SQL Server 2008 R2&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://social.technet.microsoft.com/wiki/contents/articles/11608.e-book-gallery-for-microsoft-technologies-en.aspx#IntroducingMicrosoftSQLServer2012&quot;&gt;Introducing Microsoft SQL Server 2012&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://blogs.msdn.com/b/microsoft_press/archive/2014/04/02/free-ebook-introducing-microsoft-sql-server-2014.aspx&quot;&gt;Introducing Microsoft SQL Server 2014&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.red-gate.com/community/books/mastering-sql-server-profiler&quot;&gt;Mastering SQL Server Profiler&lt;/a&gt; - Brad McGehee (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://goalkicker.com/MicrosoftSQLServerBook/&quot;&gt;Microsoft SQL Server Notes for Professionals&lt;/a&gt; - Compiled from StackOverflow Documentation (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.red-gate.com/community/books/dynamic-management-views&quot;&gt;Performance Tuning with SQL Server Dynamic Management Views&lt;/a&gt; - Tim Ford, Louis Davidson (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.red-gate.com/community/books/protecting-data&quot;&gt;Protecting SQL Server Data&lt;/a&gt; - John Magnabosco (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://social.technet.microsoft.com/wiki/contents/articles/11608.e-book-gallery-for-microsoft-technologies-en.aspx#SQLServer2012Tutorials%3AReportingServices&quot;&gt;SQL Server 2012 Tutorials: Reporting Services&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.packtpub.com/free-ebooks/sql-server-2017-administrators-guide&quot;&gt;SQL Server 2017 Administrator&apos;s Guide&lt;/a&gt; - Marek Chmel, Vladimír Mužný (Packt account &lt;em&gt;required&lt;/em&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.red-gate.com/community/books/sql-server-backup-and-restore&quot;&gt;SQL Server Backup and Restore&lt;/a&gt; - Shawn McGehee (PDF) (email address &lt;em&gt;requested&lt;/em&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://assets.red-gate.com/community/books/sql-server-execution-plans-3rd-edition.pdf&quot;&gt;SQL Server Execution Plans, Third Edition&lt;/a&gt; - Grant Fritchey (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.syncfusion.com/ebooks/sql_server_for_c_sharp_developers_succinctly&quot;&gt;SQL Server for C# Developers Succinctly&lt;/a&gt; - Sander Rossel&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.red-gate.com/community/books/sql-server-hardware&quot;&gt;SQL Server Hardware&lt;/a&gt; - Glenn Berry (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.red-gate.com/library/sql-server-internals-in-memory-oltp&quot;&gt;SQL Server Internals: In-Memory OLTP&lt;/a&gt; - Kalen Delaney (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.syncfusion.com/ebooks/sql-server-metadata-succinctly&quot;&gt;SQL Server Metadata Succinctly&lt;/a&gt; - Joseph D. Booth&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.red-gate.com/products/sql-development/sql-source-control/entrypage/sql-server-source-control-basics&quot;&gt;SQL Server Source Control Basics&lt;/a&gt; - Rob Sheldon, Rob Richardson, Tony Davis (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.red-gate.com/community/books/sql-server-statistics&quot;&gt;SQL Server Statistics&lt;/a&gt; - Holger Schmeling (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.red-gate.com/community/books/sql-server-stumpers-v5&quot;&gt;SQL Server Stumpers Vol.5&lt;/a&gt; (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.red-gate.com/community/books/sql-server-tacklebox&quot;&gt;SQL Server Tacklebox&lt;/a&gt; - Rodney Landrum (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.red-gate.com/community/books/sql-server-transaction-log-management&quot;&gt;SQL Server Transaction Log Management&lt;/a&gt; - Tony Davis, Gail Shaw (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.red-gate.com/community/books/art-of-filestream&quot;&gt;The Art of SQL Server FILESTREAM&lt;/a&gt; - Jacob Sebastian, Sven Aelterman (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.red-gate.com/library/the-art-of-xsd&quot;&gt;The Art of XSD&lt;/a&gt; - Jacob Sebastian (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.red-gate.com/library/the-best-of-sqlservercentral-com-vol-7&quot;&gt;The Best of SQLServerCentral.com Vol 7&lt;/a&gt; (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.red-gate.com/library/the-redgate-guide-to-sql-server-team-based-development&quot;&gt;The Redgate Guide to SQL Server Team-based Development&lt;/a&gt; - Phil Factor, Grant Fritchey, Alex Kuznetsov, Mladen Prajdić (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.red-gate.com/community/books/accidental-dba&quot;&gt;Troubleshooting SQL Server: A Guide for the Accidental DBA&lt;/a&gt; - Jonathan Kehayias, Ted Krueger (PDF)&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>TaffyDB</title>
      <link>https://tedneward.github.io/Research/storage/taffydb/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/taffydb/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;http://taffydb.com/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/typicaljoe/taffydb&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>TimescaleDB</title>
      <link>https://tedneward.github.io/Research/storage/timescaledb/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/timescaledb/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.timescale.com/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/timescale/timescaledb&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Trino</title>
      <link>https://tedneward.github.io/Research/storage/trino/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/trino/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://trino.io/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/trinodb/trino&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Vedis</title>
      <link>https://tedneward.github.io/Research/storage/vedis/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/vedis/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://vedis.symisc.net/&quot;&gt;Website&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;C/C++ API&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>VoltDB</title>
      <link>https://tedneward.github.io/Research/storage/voltdb/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/voltdb/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://voltactivedata.com/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/voltdb/voltdb/&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;From the GitHub repo:&lt;/p&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;This version is provided for students, hobbyists, and researchers interested in testing an ultra-fast, scalable ACID database. But all new and production-ready features are available through the commercial product from &lt;a href=&quot;https://www.voltactivedata.com&quot;&gt;https://www.voltactivedata.com&lt;/a&gt;.&lt;/p&gt; 
 &lt;p&gt;Volt Active Data offers the fully open source, AGPL3-licensed Community Edition of Volt Active Data through GitHub here: &lt;a href=&quot;https://github.com/voltdb/voltdb/&quot;&gt;https://github.com/voltdb/voltdb/&lt;/a&gt; . The Community Edition has full application compatibility and provides everything needed to run a real-time, in-memory SQL database with datacenter-local redundancy and snapshot-based disk persistence.&lt;/p&gt; 
 &lt;p&gt;Trials of the enterprise edition of Volt Active Data are available from the Volt Active Data website at the following URL: &lt;a href=&quot;https://www.voltactivedata.com&quot;&gt;https://www.voltactivedata.com&lt;/a&gt; . The commercial editions add operational features to support industrial-strength durability, manageability, and availability, including per-transaction disk-based persistence, multi-datacenter replication, elastic online expansion, live online upgrade, etc.&lt;/p&gt; 
&lt;/blockquote&gt;
	</description>
    </item>
    <item>
      <title>Xata</title>
      <link>https://tedneward.github.io/Research/storage/xata/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/xata/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://xata.io/&quot;&gt;Website&lt;/a&gt; | Commercial&lt;/p&gt; 
&lt;p&gt;Treats your data as a spreadsheet making it very easy for developers to build applications that require a flexible schema. You can also imagine it as a developer-friendly alternative to AirTable or Notion.&lt;/p&gt; 
&lt;p&gt;It comes with a full-text search out of the box and can also help you visualize the relationships in real time between your tables using the schema editor it provides. It also supports branching like Dolt and is primarily used for processing large volumes of data in real-time. It also supports some advanced querying capabilities like aggregations, filters, joins, etc.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>OrioleDB</title>
      <link>https://tedneward.github.io/Research/storage/orioledb/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/orioledb/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/orioledb/orioledb&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;OrioleDB consists of an extension, building on the innovative table access method framework and other standard Postgres extension interfaces. By extending and enhancing the current table access methods, OrioleDB opens the door to a future of more powerful storage models that are optimized for cloud and modern hardware architectures.&lt;/p&gt; 
&lt;p&gt;OrioleDB is currently distributed under the standard PostgreSQL license.&lt;/p&gt; 
&lt;ol&gt; 
 &lt;li&gt; &lt;p&gt;Designed for modern hardware. OrioleDB design avoids legacy CPU bottlenecks on modern servers containing dozens and hundreds CPU cores, providing optimized usage of modern storage technologies such as SSD and NVRAM.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Reduced maintenance needs. OrioleDB implements the concepts of undo log and page-mergins, eliminating the need for dedicated garbage collection processes. Additionally, OrioleDB implements default 64-bit transaction identifiers, thus eliminating the well-known and painful wraparound problem.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Designed to be distributed. OrioleDB implements a row-level write-ahead log with support for parallel apply. This log architecture is optimized for raft consensus-based replication allowing the implementation of active-active multimaster.&lt;/p&gt; &lt;/li&gt; 
&lt;/ol&gt; 
&lt;p&gt;The key technical differentiations of OrioleDB are as follows:&lt;/p&gt; 
&lt;ol&gt; 
 &lt;li&gt; &lt;p&gt;No buffer mapping and lock-less page reading. In-memory pages in OrioleDB are connected with direct links to the storage pages. This eliminates the need for in-buffer mapping along with its related bottlenecks. Additionally, in OrioleDB in-memory page reading doesn&apos;t involve atomic operations. Together, these design decisions bring vertical scalability for Postgres to the whole new level.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;MVCC is based on the UNDO log concept. In OrioleDB, old versions of tuples do not cause bloat in the main storage system, but eviction into the undo log comprising undo chains. Page-level undo records allow the system to easily reclaim space occupied by deleted tuples as soon as possible. Together with page-mergins, these mechanisms eliminate bloat in the majority of cases. Dedicated VACUUMing of tables is not needed as well, removing a significant and common cause of system performance deterioration and database outages.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Copy-on-write checkpoints and row-level WAL. OrioleDB utilizes copy-on-write checkpoints, which provides a structurally consistent snapshot of data every moment of time. This is friendly for modern SSDs and allows row-level WAL logging. In turn, row-level WAL logging is easy to parallelize (done), compact and suitable for active-active multimaster (planned).&lt;/p&gt; &lt;/li&gt; 
&lt;/ol&gt;
	</description>
    </item>
    <item>
      <title>Perst</title>
      <link>https://tedneward.github.io/Research/storage/perst/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/perst/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.mcobject.com/perst/&quot;&gt;Website&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>PostgresQL</title>
      <link>https://tedneward.github.io/Research/storage/postgresql/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/postgresql/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.postgresql.org/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://git.postgresql.org/gitweb/?p=postgresql.git&quot;&gt;Source&lt;/a&gt; | &lt;a href=&quot;https://wiki.postgresql.org/wiki/Main_Page&quot;&gt;Wiki&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://www.postgresql.org/download/&quot;&gt;Download&lt;/a&gt; | Also installable via Homebrew (macOS): &lt;code&gt;brew install postgresql&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/PostgreSQL&quot;&gt;Wikipedia&lt;/a&gt;&lt;/p&gt; 
&lt;h2&gt;Implementations&lt;/h2&gt; 
&lt;h3&gt;Distributions&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://postgresapp.com/&quot;&gt;Postgres.app&lt;/a&gt; - The Easiest Way to Get Started with PostgreSQL on macOS.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/mihasic/PostgreSql.Binaries.Lite&quot;&gt;PostgreSql.Binaries.Lite&lt;/a&gt; - Minimum set of Windows binaries of the PostgreSQL database. Also made available through NuGet.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/snaplet/postgres-wasm&quot;&gt;Postgres-wasm&lt;/a&gt;: A PostgreSQL server instance running in a virtual machine running in the browser&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Optimizations&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://philbooth.me/blog/nine-ways-to-shoot-yourself-in-the-foot-with-postgresql&quot;&gt;9 ways to shoot yourself in the foot&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;PaaS &lt;em&gt;(PostgreSQL as a Service)&lt;/em&gt;&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://aiven.io/postgresql&quot;&gt;Aiven PostgreSQL&lt;/a&gt; - PostgreSQL as a service in AWS, Azure, DigitalOcean, Google Cloud and UpCloud; plans range from $19/month single node instances to large highly-available setups, free trial for two weeks.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://aws.amazon.com/rds/postgresql/&quot;&gt;Amazon RDS for PostgreSQL&lt;/a&gt; - Amazon Relational Database Service (RDS) for PostgreSQL&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://azure.microsoft.com/en-us/services/postgresql/&quot;&gt;Azure Database for PostgreSQL&lt;/a&gt; - Azure Database for PostgreSQL provides fully managed, enterprise-ready community PostgreSQL database as a service. It provides builtin HA, elastic scaling and native integration with Azure ecosystem.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.crunchydata.com/products/crunchy-bridge/&quot;&gt;Crunchy Bridge&lt;/a&gt; - Fully managed Postgres from the Postgres experts. Available across all major cloud providers: Amazon AWS, Google GCP, Microsoft Azure. No lock-in with full super-user support.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.databaselabs.io&quot;&gt;Database Labs&lt;/a&gt; - Get a production-ready cloud PostgreSQL server in minutes, from $20 a month Backups, monitoring, patches, and 24/7 tech support all included.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.digitalocean.com/products/managed-databases/&quot;&gt;DigitalOcean Managed Databases&lt;/a&gt; - Fully managed PostgreSQL databases. No free plan. Starting at $15/mo. Daily backups with point-in-time recovery. Standby nodes with auto-failover.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.elephantsql.com/&quot;&gt;ElephantSQL&lt;/a&gt; - Offers databases ranging from shared servers for smaller projects and proof of concepts, up to enterprise grade multi server setups. Has free plan for up to 5 DBs, 20 MB each.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://cloud.google.com/sql/docs/postgres/&quot;&gt;Google Cloud SQL for PostgreSQL&lt;/a&gt; - Fully-managed database service that makes it easy to set up, maintain, manage, and administer your PostgreSQL relational databases on Google Cloud Platform.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://elements.heroku.com/addons/heroku-postgresql&quot;&gt;Heroku Postgres&lt;/a&gt; - Plans from free to huge, operated by PostgreSQL experts. Does not require running your app on Heroku. Free plan includes 10,000 rows, 20 connections, up to two backups, and has PostGIS support.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://render.com/docs/databases&quot;&gt;Render Managed PostgreSQL&lt;/a&gt; - Secure, reliable, and completely hands-off managed PostgreSQL. Encryption at rest, automated backups, and expandable SSD storage included in all plans. Plans start at $7 per month for 256MB RAM and 1GB storage (free for first 90 days).&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.scaleway.com/en/database/&quot;&gt;Scaleway Managed Database&lt;/a&gt; - Fully managed PostgreSQL databases with HA, scaling, and automated backups, hosted in the EU. Starting at €10 per month.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Server&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.postgres-xl.org/&quot;&gt;Postgres-XL&lt;/a&gt; - Scalable Open Source PostgreSQL-based Database Cluster.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://bitnine.net/&quot;&gt;AgensGraph&lt;/a&gt; - Powerful graph database based on the PostgreSQL.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/greenplum-db/gpdb&quot;&gt;Greenplum Database&lt;/a&gt; - Open source fork of PostgreSQL for large data volumes.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Docker images&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://hub.docker.com/_/postgres/&quot;&gt;postgres&lt;/a&gt; - Official postgres container (from Docker)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://hub.docker.com/r/citusdata/citus/&quot;&gt;citusdata/citus&lt;/a&gt; - Citus official images with citus extensions. Based on the official Postgres container.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://hub.docker.com/r/mdillon/postgis/&quot;&gt;mdillon/postgis&lt;/a&gt; - PostGIS 2.3 on Postgres 9. Based on the official Postgres container.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Reading&lt;/h2&gt; 
&lt;h3&gt;Books&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://edu.postgrespro.com/postgresql_internals-14_en.pdf&quot;&gt;PostgreSQL 14 Internals&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Articles&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://dev.to/shayy/postgres-is-too-good-and-why-thats-actually-a-problem-4imc&quot;&gt;&quot;Postgres is Too Good (And Why That&apos;s Actually a Problem)&quot;&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://pierce.dev/notes/go-ahead-self-host-postgres&quot;&gt;Go ahead, self-host Postgres&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.interdb.jp/pg/&quot;&gt;The Internals of PostgreSQL&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Access Tools&lt;/h2&gt; 
&lt;h3&gt;Language bindings&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;API: &lt;a href=&quot;https://github.com/PostgREST/postgrest&quot;&gt;PostgREST&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;Common Lisp: &lt;a href=&quot;https://github.com/marijnh/Postmodern&quot;&gt;Postmodern&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;Clojure: &lt;a href=&quot;https://github.com/remodoy/clj-postgresql&quot;&gt;clj-postgresql&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;Elixir: &lt;a href=&quot;https://github.com/elixir-ecto/postgrex&quot;&gt;postgrex&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;Go: &lt;a href=&quot;https://github.com/lib/pq&quot;&gt;pq&lt;/a&gt;, &lt;a href=&quot;https://github.com/jackc/pgx&quot;&gt;pgx&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;Haskell: &lt;a href=&quot;http://hackage.haskell.org/package/postgresql-simple&quot;&gt;postgresql-simple&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;Java: &lt;a href=&quot;https://jdbc.postgresql.org/&quot;&gt;PostgreSQL JDBC Driver&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;.NET/.NET Core: &lt;a href=&quot;https://github.com/npgsql/npgsql&quot;&gt;Npgsql&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;Node: &lt;a href=&quot;https://github.com/brianc/node-postgres&quot;&gt;node-postgres&lt;/a&gt;, &lt;a href=&quot;https://github.com/vitaly-t/pg-promise&quot;&gt;pg-promise&lt;/a&gt;, &lt;a href=&quot;https://github.com/holdfenytolvaj/pogi&quot;&gt;pogi&lt;/a&gt;, &lt;a href=&quot;https://github.com/gajus/slonik&quot;&gt;slonik&lt;/a&gt;, &lt;a href=&quot;https://github.com/porsager/postgres&quot;&gt;postgres&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;Perl: &lt;a href=&quot;https://metacpan.org/pod/distribution/DBD-Pg/Pg.pm&quot;&gt;DBD-Pg&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;PHP: &lt;a href=&quot;http://www.pomm-project.org&quot;&gt;Pomm&lt;/a&gt;, &lt;a href=&quot;https://github.com/m6w6/ext-pq&quot;&gt;pecl/pq&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;Python: &lt;a href=&quot;https://pypi.org/project/psycopg2/&quot;&gt;psycopg2&lt;/a&gt;, &lt;a href=&quot;https://pypi.org/project/asyncpg/&quot;&gt;asyncpg&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;R: &lt;a href=&quot;https://github.com/tomoakin/RPostgreSQL&quot;&gt;RPostgreSQL&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;Ruby: &lt;a href=&quot;https://github.com/ged/ruby-pg&quot;&gt;pg&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;Rust: &lt;a href=&quot;https://github.com/sfackler/rust-postgres&quot;&gt;rust-postgresql&lt;/a&gt;, &lt;a href=&quot;https://github.com/tcdi/pgx&quot;&gt;pgx&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;Lua: &lt;a href=&quot;https://github.com/arcapos/luapgsql&quot;&gt;luapgsql&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;CLI&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/dbcli/pgcli&quot;&gt;pgcli&lt;/a&gt; - Postgres CLI with autocompletion and syntax highlighting&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/sastraxi/pgsh&quot;&gt;pgsh&lt;/a&gt; - Branch your PostgreSQL Database like Git&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.postgresql.org/docs/current/static/app-psql.html&quot;&gt;psql&lt;/a&gt; - The built-in PostgreSQL CLI client&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/fphilipe/psql2csv&quot;&gt;psql2csv&lt;/a&gt; - Run a query in psql and output the result as CSV&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://gitlab.com/postgres-ai/nancy&quot;&gt;nancy&lt;/a&gt; - The Nancy CLI is a unified way to manage automated database experiments either in clouds or on-premise&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/schemaspy/schemaspy&quot;&gt;schemaspy&lt;/a&gt; - SchemaSpy is a JAVA JDBC-compliant tool for generating your database to HTML documentation, including Entity Relationship diagrams&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;GUI&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.adminer.org/&quot;&gt;Adminer&lt;/a&gt; - Full-featured database management tool written in PHP.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.beekeeperstudio.io&quot;&gt;Beekeeper Studio&lt;/a&gt; - Free and open source SQL client with a modern UI and great Postgres support. Cross platform.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://chartbrew.com&quot;&gt;Chartbrew&lt;/a&gt; - Create live dashboards, charts, and client reports from PostgreSQL data. Features a query tool that works with SQL.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://count.co/&quot;&gt;Count&lt;/a&gt; - Web-based analytics platform with a notebook interface which connects to PostgreSQL (Commercial Software).&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.jetbrains.com/datagrip/&quot;&gt;DataGrip&lt;/a&gt; - IDE with advanced tool sets and good cross-platform experience (Commercial Software).&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://datazenit.com/&quot;&gt;Datazenit&lt;/a&gt; - Web-based PostgreSQL GUI (Commercial Software).&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.datarow.com/&quot;&gt;DataRow&lt;/a&gt; - Cross-platform SQL Client for Amazon Redshift: Simple, Effortless, Extensible.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://dbeaver.io/&quot;&gt;DBeaver&lt;/a&gt; - Universal Database Manager with excellent support for PostgreSQL.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://dbglass.web-pal.com&quot;&gt;dbglass&lt;/a&gt; - Cross-platform desktop client for PostgreSQL, built with Electron.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.holistics.io/&quot;&gt;Holistics&lt;/a&gt; - Online cross platform database management tool and SQL query reporting GUI with strong PostgreSQL support (Commercial Software).&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.jackdb.com/&quot;&gt;JackDB&lt;/a&gt; - Web-based SQL query interface (Commercial Software).&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.metabase.com/&quot;&gt;Metabase&lt;/a&gt; - Simple dashboards, charts and query tool for PostgreSQL.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://numeracy.co/&quot;&gt;Numeracy&lt;/a&gt; - Fast SQL editor with charts and dashboards for PostgreSQL (Commercial Software).&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://omnidb.org/en/&quot;&gt;OmniDB&lt;/a&gt; - Open Source Collaborative Environment&lt;br&gt; For Database Management&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.pgadmin.org/&quot;&gt;pgAdmin&lt;/a&gt; - PostgreSQL Administration and Management GUI.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://pgmodeler.io/&quot;&gt;pgModeler&lt;/a&gt; - pgModeler is an open-source PostgreSQL Database Modeler.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/sosedoff/pgweb&quot;&gt;pgweb&lt;/a&gt; - Web-based PostgreSQL database browser written in Go.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/phppgadmin/phppgadmin&quot;&gt;phpPgAdmin&lt;/a&gt; - The Premier Web Based Administration Tool for PostgreSQL.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/Paxa/postbird&quot;&gt;Postbird&lt;/a&gt; - PostgreSQL Client for macOS.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.postgrescompare.com&quot;&gt;PostgresCompare&lt;/a&gt; - Cross-platform database comparison and deployment tool (Commercial Software).&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://eggerapps.at/postico/&quot;&gt;Postico&lt;/a&gt; - Modern PostgreSQL Client for macOS (Commercial Software).&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.psequel.com/&quot;&gt;PSequel&lt;/a&gt; - Clean and simple interface to perform common PostgreSQL tasks quickly (Commercial Software).&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.sqltabs.com/&quot;&gt;SQL Tabs&lt;/a&gt; - Cross Platform Desktop Client for PostgreSQL written in JS.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://macpostgresclient.com/&quot;&gt;SQLPro for Postgres&lt;/a&gt; - Simple, powerful PostgreSQL manager for macOS (Commercial Software).&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/dalibo/temboard&quot;&gt;temBoard&lt;/a&gt; - Web-based PostgreSQL GUI and monitoring.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://tableplus.com/&quot;&gt;TablePlus&lt;/a&gt; - Native App which let you edit database and structure. High-end security ensured (Commercial Software).&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.valentina-db.com/en/valentina-studio-overview&quot;&gt;Valentina Studio&lt;/a&gt; - Cross-platform database administration tool (Free/Commercial)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://dbgate.org&quot;&gt;DbGate&lt;/a&gt; - The Smartest (no)SQL Database Client&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Extensions&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/citusdata/citus&quot;&gt;Citus&lt;/a&gt; - Scalable PostgreSQL cluster for real-time workloads.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/citusdata/cstore_fdw&quot;&gt;cstore_fdw&lt;/a&gt; - Columnar store for analytics with PostgreSQL.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://pgxn.org/dist/cyanaudit/&quot;&gt;cyanaudit&lt;/a&gt; - Cyan Audit provides in-database logging of all DML activity on a column-by-column basis.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/citusdata/pg_cron&quot;&gt;pg_cron&lt;/a&gt; - Run periodic jobs in PostgreSQL.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/2ndQuadrant/pglogical&quot;&gt;pglogical&lt;/a&gt; - Extension that provides logical streaming replication.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/pgpartman/pg_partman&quot;&gt;pg_partman&lt;/a&gt; - Partition management extension for PostgreSQL.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/citusdata/pg_paxos/&quot;&gt;pg_paxos&lt;/a&gt; - Basic implementation of Paxos and Paxos-based table replication for a cluster of PostgreSQL nodes.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/citusdata/pg_shard&quot;&gt;pg_shard&lt;/a&gt; - Extension to scale out real-time reads and writes.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://wiki.postgresql.org/wiki/PGStrom&quot;&gt;PGStrom&lt;/a&gt; - Extension to offload CPU intensive workloads to GPU.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://pgxn.org/&quot;&gt;pgxn&lt;/a&gt; PostgreSQL Extension Network - central distribution point for many open-source PostgreSQL extensions&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.confluent.io/blog/pipelinedb-team-joins-confluent/&quot;&gt;PipelineDB&lt;/a&gt; - A PostgreSQL extension that runs SQL queries continuously on streams, incrementally storing results in tables.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/okbob/plpgsql_check&quot;&gt;plpgsql_check&lt;/a&gt; - Extension that allows to check plpgsql source code.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://postgis.net/&quot;&gt;PostGIS&lt;/a&gt; - Spatial and Geographic objects for PostgreSQL.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/cossacklabs/pg_themis&quot;&gt;PG_Themis&lt;/a&gt; - Postgres binding as extension for crypto library Themis, providing various security services on PgSQL&apos;s side.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/zombodb/zombodb&quot;&gt;zomboDB&lt;/a&gt; - Extension that enables efficient full-text searching via the use of indexes backed by Elasticsearch.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/pgMemento/pgMemento&quot;&gt;pgMemento&lt;/a&gt; - Provides an audit trail for your data inside a PostgreSQL database using triggers and server-side functions written in PL/pgSQL.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.timescale.com/&quot;&gt;TimescaleDB&lt;/a&gt; - Open-source time-series database fully compatible with Postgres, distributed as extension&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://pgtap.org/&quot;&gt;pgTAP&lt;/a&gt; - Database testing framework for Postgres&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/HypoPG/hypopg&quot;&gt;HypoPG&lt;/a&gt; - HypoPG provides hypothetical/virtual indexes feature.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/pgRouting/pgrouting&quot;&gt;pgRouting&lt;/a&gt; - pgRouting extends the PostGIS/PostgreSQL geospatial database to provide geospatial routing and other network analysis functionality.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://pgroonga.github.io/&quot;&gt;PGroonga&lt;/a&gt; - PGroonga provides a new index access method that uses Groonga allowing super fast full text search feature against all languages.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.pgaudit.org/&quot;&gt;PGAudit&lt;/a&gt; - The PostgreSQL Audit Extension (or pgaudit) provides detailed session and/or object audit logging via the standard logging facility provided by PostgreSQL.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Backups&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.pgbarman.org/index.html&quot;&gt;Barman&lt;/a&gt; - Backup and Recovery Manager for PostgreSQL by 2ndQuadrant.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/omniti-labs/omnipitr&quot;&gt;OmniPITR&lt;/a&gt; - Advanced WAL File Management Tools for PostgreSQL.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/postgrespro/pg_probackup&quot;&gt;pg_probackup&lt;/a&gt; – A fork of pg_arman, improved by @PostgresPro, supports incremental backups, backups from replica, multithreaded backup and restore, and anonymous backup without archive command.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://pgbackrest.org/&quot;&gt;pgBackRest&lt;/a&gt; - Reliable PostgreSQL Backup &amp;amp; Restore.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/orgrim/pg_back/&quot;&gt;pg_back&lt;/a&gt; - pg_back is a simple backup script&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/aiven/pghoard&quot;&gt;pghoard&lt;/a&gt; - Backup and restore tool for cloud object stores (AWS S3, Azure, Google Cloud, OpenStack Swift).&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/wal-e/wal-e&quot;&gt;wal-e&lt;/a&gt; (obsolete) - Simple Continuous Archiving for PostgreSQL to S3, Azure, or Swift by Heroku.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/wal-g/wal-g&quot;&gt;wal-g&lt;/a&gt; - The successor of WAL-E rewritten in Go. Currently supports cloud object storage services by AWS (S3), Google Cloud (GCS), Azure, as well as OpenStack Swift, MinIO, and file system storages. Supports block-level incremental backups, offloading backup tasks to a standby server, provides parallelization and throttling options. In addition to Postgres, WAL-G can be used for MySQL and MongoDB databases.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://dalibo.github.io/pitrery/&quot;&gt;pitrery&lt;/a&gt; - pitrery is a set of Bash scripts to manage Point In Time Recovery (PITR) backups for PostgreSQL.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;High-Availability&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/2ndQuadrant/bdr&quot;&gt;BDR&lt;/a&gt; - BiDirectional Replication - a multimaster replication system for PostgreSQL&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/zalando/patroni&quot;&gt;Patroni&lt;/a&gt; - Template for PostgreSQL HA with ZooKeeper or etcd.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/sorintlab/stolon&quot;&gt;Stolon&lt;/a&gt; - PostgreSQL HA based on Consul or etcd, with Kubernetes integration.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/aiven/pglookout&quot;&gt;pglookout&lt;/a&gt; - Replication monitoring and failover daemon.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/2ndQuadrant/repmgr&quot;&gt;repmgr&lt;/a&gt; - Open-source tool suite to manage replication and failover in a cluster of PostgreSQL servers.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://slony.info/&quot;&gt;Slony-I&lt;/a&gt; - &quot;Master to multiple slaves&quot; replication system with cascading and failover.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/ClusterLabs/PAF&quot;&gt;PAF&lt;/a&gt; - PostgreSQL Automatic Failover: High-Availibility for Postgres, based on Pacemaker and Corosync.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/pgq/skytools-legacy&quot;&gt;SkyTools&lt;/a&gt; - Replication tools, including PgQ, a queuing system, and Londiste, a replication system a bit simpler to manage than Slony.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Monitoring&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/OPMDG/check_pgactivity&quot;&gt;check_pgactivity&lt;/a&gt; - check_pgactivity is designed to monitor PostgreSQL clusters from Nagios. It offers many options to measure and monitor useful performance metrics.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/bucardo/check_postgres&quot;&gt;Check_postgres&lt;/a&gt; - Nagios check_postgres plugin for checking status of PostgreSQL databases.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/Instrumental/instrumentald&quot;&gt;Instrumental&lt;/a&gt; - Real-time performance monitoring, including &lt;a href=&quot;https://instrumentalapp.com/docs/instrumentald/postgresql#suggested-graphs&quot;&gt;pre-made graphs&lt;/a&gt; for ease of setup (Commercial Software)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/cavaliercoder/libzbxpgsql&quot;&gt;libzbxpgsql&lt;/a&gt; - Comprehensive PostgreSQL monitoring module for Zabbix.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/percona/pmm&quot;&gt;PMM&lt;/a&gt; - Percona Monitoring and Management (PMM) is a Free and Open Source platform for monitoring and managing PostgreSQL, MySQL, and MongoDB.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/rach/pome&quot;&gt;Pome&lt;/a&gt; - Pome stands for PostgreSQL Metrics. Pome is a PostgreSQL Metrics Dashboard to keep track of the health of your database.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://pgmetrics.io/&quot;&gt;pgmetrics&lt;/a&gt; - pgmetrics is an open-source, zero-dependency, single-binary tool that can collect a lot of information and statistics from a running PostgreSQL server and display it in easy-to-read text format or export it as JSON and CSV for scripting.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/zalando/pg_view&quot;&gt;pg_view&lt;/a&gt; - Open-source command-line tool that shows global system stats, per-partition information, memory stats and other information.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/cybertec-postgresql/pgwatch2&quot;&gt;pgwatch2&lt;/a&gt; - Flexible and easy to get started PostgreSQL metrics monitor focusing on Grafana dashboards.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.postgresql.org/docs/devel/static/pgbench.html&quot;&gt;pgbench&lt;/a&gt; - Run a benchmark test on PostgreSQL.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://opm.io&quot;&gt;opm.io&lt;/a&gt; - Open PostgreSQL Monitoring is a free software suite designed to help you manage your PostgreSQL servers. It can gather stats, display dashboards and send warnings when something goes wrong.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://okmeter.io/pg&quot;&gt;okmeter.io&lt;/a&gt; - Commercial SaaS agent-based monitoring with a very detailed PostgreSQL plugin. It automatically gathers 100s of stats, displays dashboards on every aspect and sends alerts when something goes wrong (Commercial Software).&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/ankane/dexter&quot;&gt;dexter&lt;/a&gt; - The automatic indexer for Postgres. Detects slow queries and creates indexes if configured to do so.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Optimization&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/mgartner/pg_flame&quot;&gt;pg_flame&lt;/a&gt; - A flamegraph generator for query plans.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/ankane/pghero&quot;&gt;PgHero&lt;/a&gt; - PostgreSQL insights made easy.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.pgmustard.com/&quot;&gt;pgMustard&lt;/a&gt; - A modern user interface&lt;br&gt; for &lt;code&gt;EXPLAIN&lt;/code&gt;, that also provides performance tips (Commercial Software).&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/gregs1104/pgtune/&quot;&gt;pgtune&lt;/a&gt; - PostgreSQL configuration wizard.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/le0pard/pgtune&quot;&gt;pgtune&lt;/a&gt; - Online version of PostgreSQL configuration wizard.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/sebastianwebber/pgconfig&quot;&gt;pgconfig.org&lt;/a&gt; - PostgreSQL Online Configuration Tool (also based on pgtune).&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://powa.readthedocs.io/en/latest/&quot;&gt;PoWA&lt;/a&gt; - PostgreSQL Workload Analyzer gathers performance stats and provides real-time charts and graphs to help monitor and tune your PostgreSQL servers.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/kirs/pg_web_stats&quot;&gt;pg_web_stats&lt;/a&gt; - Web UI to view pg_stat_statements.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/timescale/timescaledb-tune&quot;&gt;TimescaleDB Tune&lt;/a&gt; - a program for tuning a TimescaleDB database to perform its best based on the host&apos;s resources such as memory and number of CPUs.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Utilities&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.apgdiff.com/&quot;&gt;apgdiff&lt;/a&gt; - Compares two database dump files and creates output with DDL statements that can be used to update old database schema to new one.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/Alexis-benoist/eralchemy&quot;&gt;ERAlchemy&lt;/a&gt; - ERAlchemy generates Entity Relation (ER) diagram from databases.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/dalibo/ldap2pg&quot;&gt;ldap2pg&lt;/a&gt; - Synchronize roles and privileges from YML and LDAP.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/lanyrd/mysql-postgresql-converter&quot;&gt;mysql-postgresql-converter&lt;/a&gt; - Lanyrd&apos;s MySQL to PostgreSQL conversion script.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://ora2pg.darold.net&quot;&gt;ora2pg&lt;/a&gt; - Perl module to export an Oracle database schema to a PostgreSQL compatible schema.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/dalibo/pg_activity&quot;&gt;pg_activity&lt;/a&gt; - top like application for PostgreSQL server activity monitoring.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/gajus/pg-formatter&quot;&gt;pg-formatter&lt;/a&gt; - A PostgreSQL SQL syntax beautifier (Node.js).&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://pganalyze.com&quot;&gt;pganalyze&lt;/a&gt; - PostgreSQL Performance Monitoring (Commercial Software).&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/darold/pgbadger&quot;&gt;pgbadger&lt;/a&gt; - Fast PostgreSQL Log Analyzer.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.pgbouncer.org/&quot;&gt;PgBouncer&lt;/a&gt; - Lightweight connection pooler for PostgreSQL.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/lesovsky/pgcenter&quot;&gt;pgCenter&lt;/a&gt; - Provides convenient interface to various statistics, management task, reloading services, viewing log files and canceling or terminating database backends.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/the4thdoctor/pg_chameleon&quot;&gt;pg_chameleon&lt;/a&gt; - Real time replica from MySQL to PostgreSQL with optional type override migration and migration capabilities.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/lukasmartinelli/pgclimb&quot;&gt;pgclimb&lt;/a&gt; - Export data from PostgreSQL into different data formats.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/mchristofides/pg_docs_bot/&quot;&gt;pg_docs_bot&lt;/a&gt; - Browser extension to redirect PostgreSQL docs links to the current version.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/lukasmartinelli/pgfutter&quot;&gt;pgfutter&lt;/a&gt; - Import CSV and JSON into PostgreSQL the easy way.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://pginsight.io/&quot;&gt;PGInsight&lt;/a&gt; - CLI tool to easily dig deep inside your PostgreSQL database.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/lob/pg_insights&quot;&gt;pg_insights&lt;/a&gt; - Convenient SQL for monitoring Postgres database health.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/dimitri/pgloader&quot;&gt;pgloader&lt;/a&gt; - Loads data into PostgreSQL using the COPY streaming protocol, and does so with separate threads for reading and writing data.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/CrunchyData/pgmonitor&quot;&gt;pgMonitor&lt;/a&gt; - Postgres metrics collection and visualization that can be deployed to bare metal, virtual machines, or Kubernetes.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.pgpool.net/mediawiki/index.php/Main_Page&quot;&gt;pgpool-II&lt;/a&gt; - Middleware that provides connection pooling, replication, load balancing and limiting exceeding connections.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/ankane/pgsync&quot;&gt;pgsync&lt;/a&gt; - Tool to sync PostgreSQL data to your local machine.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/pgxn/pgxnclient&quot;&gt;PGXN client&lt;/a&gt; - Command line tool to interact with the PostgreSQL Extension Network&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/spotify/postgresql-metrics&quot;&gt;postgresql-metrics&lt;/a&gt; - Tool that extracts and provides metrics for your PostgreSQL database.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/PostgREST/postgrest&quot;&gt;PostgREST&lt;/a&gt; - Serves a fully RESTful API from any existing PostgreSQL database. &lt;a href=&quot;https://docs.postgrest.org/en/v13/index.html&quot;&gt;Docs&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/prest/prest&quot;&gt;pREST&lt;/a&gt; - Serve a RESTful API from any PostgreSQL database (Golang)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/graphile/postgraphile&quot;&gt;PostGraphile&lt;/a&gt; - Instant GraphQL API or GraphQL schema for your PostgreSQL database&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/nanopack/yoke&quot;&gt;yoke&lt;/a&gt; - PostgreSQL high-availability cluster with auto-failover and automated cluster recovery.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/kabirbaidhya/pglistend&quot;&gt;pglistend&lt;/a&gt; - A lightweight PostgresSQL &lt;code&gt;LISTEN&lt;/code&gt;/&lt;code&gt;NOTIFY&lt;/code&gt; daemon built on top of &lt;code&gt;node-postgres&lt;/code&gt;.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/postgrespro/zson&quot;&gt;ZSON&lt;/a&gt; - PostgreSQL extension for transparent JSONB compression&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://ossc-db.github.io/pg_bulkload/index.html&quot;&gt;pg_bulkload&lt;/a&gt; - It&apos;s a high speed data loading utility for PostgreSQL.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/jwdeitch/pg_migrate&quot;&gt;pg_migrate&lt;/a&gt; - Manage PostgreSQL codebases and make VCS simple.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/sqitchers/sqitch&quot;&gt;sqitch&lt;/a&gt; - Tool for managing versioned schema deployment&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/yandex/pgmigrate&quot;&gt;pgmigrate&lt;/a&gt; - CLI tool to evolve schema migrations, developed by Yandex.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/cbbrowne/pgcmp&quot;&gt;pgcmp&lt;/a&gt; - Tool to compare database schemas, with capability to accept some persistent differences&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/multum/pg-differ&quot;&gt;pg-differ&lt;/a&gt; - Tool for easy initialization / updating of the structure of PostgreSQL tables, migration alternative (Node.js).&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/jarulraj/sqlcheck&quot;&gt;sqlcheck&lt;/a&gt; - Automatically detects common SQL anti-patterns. Such anti-patterns often slow down queries. Addressing them will, therefore, help accelerate queries.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://gitlab.com/postgres-ai/postgres-checkup&quot;&gt;postgres-checkup&lt;/a&gt; - a new-generation diagnostics tool that allows users to collect deep analysis of the health of a Postgres database.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://scaffoldhub.io&quot;&gt;ScaffoldHub.io&lt;/a&gt; - Generate fullstack PostgreSQL apps with Angular, Vue or React (Commercial Software).&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Resources&lt;/h2&gt; 
&lt;h3&gt;Tutorials&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://coderwall.com/p/cwe2_a/backup-and-recover-a-postgres-db-using-wal-e&quot;&gt;Backup and recover a PostgreSQL DB using wal-e&lt;/a&gt; - Tutorial about setting up continuous archiving in PostgreSQL using wal-e.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.pgcasts.com&quot;&gt;PG Casts&lt;/a&gt; - Free weekly PostgreSQL screencasts by Hashrocket.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://postgresguide.com/&quot;&gt;Postgres Guide&lt;/a&gt; - Guide designed as an aid for beginners and experienced users to find specific tips and explore tools available within PostgreSQL.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://pgexercises.com/&quot;&gt;PostgreSQL Exercises&lt;/a&gt; - Site to make it easy to learn PostgreSQL by doing exercises.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.tutorialspoint.com/postgresql/&quot;&gt;tutorialspoint PostgreSQL tutorial&lt;/a&gt; - Very extensive collection of tutorials on PostgreSQL&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/morenoh149/postgresDBSamples&quot;&gt;postgresDBSamples&lt;/a&gt; - A collection of sample postgres schemas&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://zaiste.net/posts/postgresql-primer-for-busy-people/&quot;&gt;PostgreSQL Primer for Busy People&lt;/a&gt; - A collection of the most common commands used in PostgreSQL&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/dataegret/pg-utils&quot;&gt;pg-utils&lt;/a&gt; - Useful DBA tools by Data Egret&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Blogs&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://planet.postgresql.org/&quot;&gt;Planet PostgreSQL&lt;/a&gt; - Blog aggregation service for PostgreSQL.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://adpgtech.blogspot.com/search/label/PostgreSQL/&quot;&gt;Andrew Dunstan&apos;s PostgreSQL and Technical blog&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://momjian.us/main/blogs/pgblog.html&quot;&gt;Bruce Momjian&apos;s PostgreSQL blog&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.craigkerstiens.com/categories/postgres/&quot;&gt;Craig Kerstiens PostgreSQL posts&lt;/a&gt; - Set of posts on PostgreSQL cool features, tips and tricks.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.databasesoup.com/search/label/postgresql/&quot;&gt;Database Soup&lt;/a&gt; - Josh Berkus&apos; blog.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://paquier.xyz/&quot;&gt;Michael Paquier&apos;s blog&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://rhaas.blogspot.com/search/label/postgresql/&quot;&gt;Robert Haas&apos; blog&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.depesz.com/tag/postgresql/&quot;&gt;select * from depesz;&lt;/a&gt; - Hubert Lubaczewski&apos;s blog.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Books&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.postgresql.org/docs/&quot;&gt;Postgres Official Documentation&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.syncfusion.com/resources/techportal/ebooks/postgres&quot;&gt;Postgres Succinctly&lt;/a&gt; (PDF, Kindle) (email address &lt;em&gt;requested&lt;/em&gt;, not required)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://goalkicker.com/PostgreSQLBook/&quot;&gt;PostgreSQL Notes for Professionals&lt;/a&gt; - Compiled from StackOverflow documentation (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.tutorialspoint.com/postgresql&quot;&gt;PostgreSQL Tutorial&lt;/a&gt; - Tutorials Point&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.faqs.org/docs/ppbook/book1.htm&quot;&gt;Practical PostgreSQL&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.interdb.jp/pg&quot;&gt;The Internals of PostgreSQL for database administrators and system developers&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Articles&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;What PostgreSQL has over other open source SQL databases: &lt;a href=&quot;https://www.compose.com/articles/what-postgresql-has-over-other-open-source-sql-databases/&quot;&gt;Part I&lt;/a&gt; | &lt;a href=&quot;https://www.compose.com/articles/what-postgresql-has-over-other-open-source-sql-databases-part-ii/&quot;&gt;Part II&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://di.nmfay.com/postgres-vs-mysql&quot;&gt;the ultimate postgres vs mysql blog post&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.justwatch.com/blog/post/debugging-postgresql-performance-the-hard-way/&quot;&gt;Debugging PostgreSQL performance, the hard way&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.craigkerstiens.com/2017/04/30/why-postgres-five-years-later/&quot;&gt;Why use Postgres?&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://infinum.com/the-capsized-eight/superfast-csv-imports-using-postgresqls-copy&quot;&gt;Superfast CSV imports using PostgreSQL&apos;s COPY command&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://spacelift.io/blog/tricking-postgres-into-using-query-plan&quot;&gt;Tricking Postgres into using an insane – but 200x faster – query plan&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://heap.io/blog/optimizing-postgres-queries-at-scale&quot;&gt;&quot;Optimizing Postgres Queries at Scale&quot;&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://blog.crunchydata.com/blog/five-tips-for-a-healthier-postgres-database-in-the-new-year&quot;&gt;5 Tips for a Healthier Postgres Database&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://webapp.io/blog/postgres-is-the-answer/&quot;&gt;Postgres is a great pub/sub &amp;amp; job server&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://stepzen.com/blog/join-data-postgresql-declarative-graphql-without-sql&quot;&gt;&quot;Join Data from PostgreSQL Declaratively in GraphQL w/o writing SQL&quot;&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Newsletters&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://postgresweekly.com/&quot;&gt;Postgres Weekly&lt;/a&gt; - Weekly newsletter that contains articles, news, and repos relevant to PostgreSQL.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;WTF&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/eggyknap/pllolcode&quot;&gt;PostgresQL implementation of LOLCode&lt;/a&gt;; &lt;a href=&quot;https://www.pgcon.org/2009/schedule/track/Tutorial/159.en.html&quot;&gt;PGCon slides (PDF)&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>QuestDB</title>
      <link>https://tedneward.github.io/Research/storage/questdb/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/questdb/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://questdb.io/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/questdb/questdb&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://bjug.jerrinot.info/#1&quot;&gt;Slides explaining its engineering&lt;/a&gt;&lt;/p&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;We achieve high performance via a column-oriented storage model, parallelized vector execution, SIMD instructions, and low-latency techniques. In addition, QuestDB is hardware efficient, with quick setup and operational efficiency.&lt;br&gt; QuestDB implements ANSI SQL with native time-series SQL extensions. These SQL extensions make it simple to analyze, filter and downsample data, or to correlate data from multiple sources using relational and time-series joins.&lt;/p&gt; 
&lt;/blockquote&gt;
	</description>
    </item>
    <item>
      <title>RedisGraph</title>
      <link>https://tedneward.github.io/Research/storage/redisgraph/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/redisgraph/index.html</guid>
      	<description>
	&lt;p&gt;RedisGraph is the first queryable Property Graph database to use sparse matrices to represent the adjacency matrix in graphs and linear algebra to query the graph.&lt;/p&gt; 
&lt;p&gt;Primary features:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Based on the Property Graph Model&lt;/li&gt; 
 &lt;li&gt;Nodes (vertices) and Relationships (edges) that may have attributes&lt;/li&gt; 
 &lt;li&gt;Nodes that can be labeled&lt;/li&gt; 
 &lt;li&gt;Relationships have a relationship type&lt;/li&gt; 
 &lt;li&gt;Graphs represented as sparse adjacency matrices&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;/languages/cypher&quot;&gt;Cypher&lt;/a&gt; as query language&lt;/li&gt; 
 &lt;li&gt;Cypher queries translated into linear algebra expressions&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;&lt;a href=&quot;https://oss.redislabs.com/redisgraph/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/RedisGraph/RedisGraph/&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;To quickly try out RedisGraph, launch an instance using docker: &lt;code&gt;docker run -p 6379:6379 -it --rm redislabs/redisgraph&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;After you load RedisGraph, you can interact with it using &lt;code&gt;redis-cli&lt;/code&gt;.&lt;/p&gt; 
&lt;p&gt;Here we&apos;ll quickly create a small graph representing a subset of motorcycle riders and teams taking part in the MotoGP league. Once created, we&apos;ll start querying our data.&lt;/p&gt; 
&lt;p&gt;With redis-cli&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;$ redis-cli
127.0.0.1:6379&amp;gt; GRAPH.QUERY MotoGP &quot;CREATE (:Rider {name:&apos;Valentino Rossi&apos;})-[:rides]-&amp;gt;(:Team {name:&apos;Yamaha&apos;}), (:Rider {name:&apos;Dani Pedrosa&apos;})-[:rides]-&amp;gt;(:Team {name:&apos;Honda&apos;}), (:Rider {name:&apos;Andrea Dovizioso&apos;})-[:rides]-&amp;gt;(:Team {name:&apos;Ducati&apos;})&quot;
1) 1) Labels added: 2
   2) Nodes created: 6
   3) Properties set: 6
   4) Relationships created: 3
   5) &quot;Query internal execution time: 0.399000 milliseconds&quot;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Now that our MotoGP graph is created, we can start asking questions. For example: Who&apos;s riding for team Yamaha?&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;127.0.0.1:6379&amp;gt; GRAPH.QUERY MotoGP &quot;MATCH (r:Rider)-[:rides]-&amp;gt;(t:Team) WHERE t.name = &apos;Yamaha&apos; RETURN r.name, t.name&quot;
1) 1) &quot;r.name&quot;
   2) &quot;t.name&quot;
2) 1) 1) &quot;Valentino Rossi&quot;
      2) &quot;Yamaha&quot;
3) 1) &quot;Query internal execution time: 0.625399 milliseconds&quot;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;How many riders represent team Ducati?&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;127.0.0.1:6379&amp;gt; GRAPH.QUERY MotoGP &quot;MATCH (r:Rider)-[:rides]-&amp;gt;(t:Team {name:&apos;Ducati&apos;}) RETURN count(r)&quot;
1) 1) &quot;count(r)&quot;
2) 1) 1) (integer) 1
3) 1) &quot;Query internal execution time: 0.624435 milliseconds&quot;
&lt;/code&gt;&lt;/pre&gt;
	</description>
    </item>
    <item>
      <title>Riak</title>
      <link>https://tedneward.github.io/Research/storage/riak/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/riak/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://riak.com/index.html&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/basho/riak&quot;&gt;Source&lt;/a&gt; | &lt;a href=&quot;https://docs.riak.com/&quot;&gt;Docs&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>OctoBase</title>
      <link>https://tedneward.github.io/Research/storage/octobase/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/octobase/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://octobase.dev/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/toeverything/OctoBase&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;h2&gt;Features&lt;/h2&gt; 
&lt;p&gt;As an offline collaborative data database, OctoBase has the following characteristics:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;📚 &lt;strong&gt;Multi-platform available&lt;/strong&gt; offline collaboration, Schemaless, structured/unstructured/rich text data storage.&lt;/li&gt; 
 &lt;li&gt;🗃️ &lt;strong&gt;Binary storage&lt;/strong&gt; that supports data deduplication and rich media editing.&lt;/li&gt; 
 &lt;li&gt;🔍 &lt;strong&gt;High-performance real-time full-text indexing&lt;/strong&gt; with high-quality multilingual word segmentation support.&lt;/li&gt; 
 &lt;li&gt;🌐 &lt;strong&gt;CRDT-driven P2P synchronization&lt;/strong&gt; with rich multi-platform native support.&lt;/li&gt; 
 &lt;li&gt;🔒 &lt;strong&gt;Fine-grained permission control&lt;/strong&gt; with advanced permission management.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;OctoBase provides native support for offline collaboration, full-text indexing, and binary storage, making it easy for developers to build secure and high-performance local-first collaborative applications that work seamlessly across multiple platforms.&lt;/p&gt; 
&lt;p&gt;With OctoBase, you will have access to same data abstractions across platform that enable you to maintain consistency and coherence across all your applications, regardless of the devices or platforms used.&lt;/p&gt; 
&lt;p&gt;Additionally, OctoBase can function as a standalone server database, or it can be integrated directly into your application as an embedded database while remaining fully functional.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Orly</title>
      <link>https://tedneward.github.io/Research/storage/orly/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/orly/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/orlyatomics/orly/wiki&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/orlyatomics/orly&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;h2&gt;Orly (&quot;oh-really&quot;) features:&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;strong&gt;Points of View&lt;/strong&gt;: This is our version of optimistic locking or isolation. In traditional databases, clients have to lock the entire database (or at least large swaths of it) before updating it to ensure data remains consistent. In Orly, clients make changes in their own private points of view, which are like small sandboxes. Changes in private points of view eventually propagate into shared points of view and eventually reach the global point of view, which is the whole database. Updates to private points of view don&apos;t lock anything: Orly determines later whether, when, and how to reconcile changes from different points of view. We also encourage field calls rather than field changes (e.g., &lt;code&gt;x += 1&lt;/code&gt; is better than &lt;code&gt;x = x + 1&lt;/code&gt;).&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Time Travel&lt;/strong&gt;: We use something called the &lt;em&gt;Flux Capacitor&lt;/em&gt; to keep a history of changes made to the database and to resolve conflicts as they come into shared points of view and the global point of view. This permits us to perform consistent read for any point in time. Orly defines its &quot;time line&quot; by causality rather than clock time. Instead of manipulating timestamps, Orly records an ordering of events (e.g., update A affects update B, so A &quot;happens before&quot; B).)&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Query Language&lt;/strong&gt;: Orly has its own high-level, compiled, type-safe, functional language called &lt;em&gt;Orlyscript&lt;/em&gt;. Orlyscript is not just a query language: You can write general-purpose programs in it complete with compile-time unit tests. Orly comes with a compiler that transforms Orlyscript into shared libraries (.so files on Linux), which Orly servers load as packages.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Scalability and Availability&lt;/strong&gt;: While we eventually plan to develop a sharded Orly machine (and actively design so that we can build such a machine), our current single-node server with fail-over/replication can handle hundreds of thousands of transactions per second. We like to say that Orly will function on a &quot;planetary scale&quot;: Your data and computations will not only distribute across a data center, but also across many data centers across the globe. This means that no disaster short of nuking the planet fifty times over or colliding with a gigantic asteroid will destroy your data. (Even those might not be catastrophic: Maybe we&apos;ll have data centers running Orly with your replicated data on the moon or Mars.)&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>PingCAP</title>
      <link>https://tedneward.github.io/Research/storage/pingcap/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/pingcap/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://en.pingcap.com/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/pingcap/tidb&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>PouchDB</title>
      <link>https://tedneward.github.io/Research/storage/pouchdb/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/pouchdb/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;http://pouchdb.com&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/pouchdb/pouchdb&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;PouchDB databases come in two flavors: local and remote.&lt;/p&gt; 
&lt;p&gt;To create a local database, you simply call new PouchDB and give it a name:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;var db = new PouchDB(&apos;kittens&apos;);
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;To create a remote database, you call new PouchDB and give it a path to a database in CouchDB.&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;var db = new PouchDB(&apos;http://localhost:5984/kittens&apos;);
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;You can see basic information about the database by using the info() method.&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;db.info().then(function (info) {
  console.log(info);
})
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;The local database should show something like:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;{&quot;doc_count&quot;:0,&quot;update_seq&quot;:0,&quot;db_name&quot;:&quot;kittens&quot;}
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;The remote database may have a bit more information:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;{&quot;db_name&quot;:&quot;kittens&quot;,&quot;doc_count&quot;:0,&quot;doc_del_count&quot;:0,&quot;update_seq&quot;:0,&quot;purge_seq&quot;:0,&quot;compact_running&quot;:false,&quot;disk_size&quot;:79,&quot;data_size&quot;:0,&quot;instance_start_time&quot;:&quot;1410722558431975&quot;,&quot;disk_format_version&quot;:6,&quot;committed_update_seq&quot;:0}
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;You can also enable debug logging by doing:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;PouchDB.debug.enable(&apos;*&apos;);
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;And then disable it by doing:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;PouchDB.debug.disable();
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;During development, it&apos;s often useful to destroy the local database, so you can see what your users will experience when they visit your site for the first time. A page refresh is not enough, because the data will still be there!&lt;/p&gt; 
&lt;p&gt;In Chrome, you can use the Clear Cache extension, which will add a trashcan icon to your toolbar, which you can click to delete all local data (IndexedDB, WebSQL, LocalStorage, cookies, etc.).&lt;/p&gt; 
&lt;p&gt;In Firefox, you can use the Clear Recent History+ add-on, so when you right-click a page you can quickly clear all data.&lt;/p&gt; 
&lt;p&gt;In Safari, you can simply click Safari → Clear History and Website Data.&lt;/p&gt; 
&lt;p&gt;When you create a local PouchDB database, it uses whatever underlying datastore is available - IndexedDB in most browsers, WebSQL in older browsers, and LevelDB in Node.js.&lt;/p&gt; 
&lt;p&gt;When you create a remote PouchDB database, it communicates directly with the remote database – CouchDB, Cloudant, Couchbase, etc.&lt;/p&gt; 
&lt;p&gt;The goal of PouchDB is to allow you to seamlessly communicate with one or the other. You should not notice many differences between the two, except that of course the local one is much faster!&lt;/p&gt; 
&lt;p&gt;To store a document, you simply put it:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;var doc = {
  &quot;_id&quot;: &quot;mittens&quot;,
  &quot;name&quot;: &quot;Mittens&quot;,
  &quot;occupation&quot;: &quot;kitten&quot;,
  &quot;age&quot;: 3,
  &quot;hobbies&quot;: [
    &quot;playing with balls of yarn&quot;,
    &quot;chasing laser pointers&quot;,
    &quot;lookin&apos; hella cute&quot;
  ]
};
db.put(doc);
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Whenever you put() a document, it must have an _id field so that you can retrieve it later.&lt;/p&gt; 
&lt;p&gt;So now let&apos;s get() the document by using its _id:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;db.get(&apos;mittens&apos;).then(function (doc) {
  console.log(doc);
});
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;You should see:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;{
  &quot;name&quot;: &quot;Mittens&quot;,
  &quot;occupation&quot;: &quot;kitten&quot;,
  &quot;age&quot;: 3,
  &quot;hobbies&quot;: [
    &quot;playing with balls of yarn&quot;,
    &quot;chasing laser pointers&quot;,
    &quot;lookin&apos; hella cute&quot;
  ],
  &quot;_id&quot;: &quot;mittens&quot;,
  &quot;_rev&quot;: &quot;1-bea5fa18e06522d12026f4aee6b15ee4&quot;
}
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;The document looks exactly the same as when we put it, except... aha! What is this? There is a new field, _rev, the revision marker. It is a randomly-generated ID that changes whenever a document is created or updated.&lt;/p&gt; 
&lt;p&gt;For instance, to increment Mittens&apos; age to 4, we would do:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;doc.age = 4;
doc._rev = &quot;1-bea5fa18e06522d12026f4aee6b15ee4&quot;;
db.put(doc);
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;If you fail to include the correct _rev, you will get the following sad error:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;{
  &quot;status&quot;: 409,
  &quot;name&quot;: &quot;conflict&quot;,
  &quot;message&quot;: &quot;Document update conflict&quot;
}
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;HTTP 409 is a standard HTTP error message that indicates a conflict.&lt;/p&gt; 
&lt;p&gt;So to update Mittens&apos; age, we will first need to fetch Mittens from the database, to ensure that we have the correct _rev before we put them back. We don&apos;t need to manually assign the _rev value here (like we did above), as it is already in the doc we&apos;re fetching.&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;// fetch mittens
db.get(&apos;mittens&apos;).then(function (doc) {
  // update their age
  doc.age = 4;
  // put them back
  return db.put(doc);
}).then(function () {
  // fetch mittens again
  return db.get(&apos;mittens&apos;);
}).then(function (doc) {
  console.log(doc);
});
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Now you should see the following:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;{
  &quot;name&quot;: &quot;Mittens&quot;,
  &quot;occupation&quot;: &quot;kitten&quot;,
  &quot;age&quot;: 4,
  &quot;hobbies&quot;: [
    &quot;playing with balls of yarn&quot;,
    &quot;chasing laser pointers&quot;,
    &quot;lookin&apos; hella cute&quot;
  ],
  &quot;_id&quot;: &quot;mittens&quot;,
  &quot;_rev&quot;: &quot;2-3e3fd988b331193beeeea2d4221b57e7&quot;
}
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;As you can see, we have successfully updated Mittens&apos; age to 4 (they grow up so fast!), and their revision marker has also changed to &quot;2-3e3fd988b331193beeeea2d4221b57e7&quot;. If we wanted to increment their age to 5, we would need to supply this new revision marker.&lt;/p&gt; 
&lt;p&gt;PouchDB provides a fully asynchronous API. This ensures that when you talk to PouchDB, the UI doesn&apos;t stutter, because the DOM is not being blocked by database operations. To make things as flexible as possible for PouchDB users, the API is provided in both callback format and promise format.&lt;/p&gt; 
&lt;p&gt;The callback format looks like this:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;db.get(&apos;mittens&apos;, function (error, doc) {
  if (error) {
    // oh noes! we got an error
  } else {
    // okay, doc contains our document
  }
});
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;The promise format looks like this:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;db.get(&apos;mittens&apos;).then(function (doc) {
  // okay, doc contains our document
}).catch(function (err) {
  // oh noes! we got an error
});
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Basically, if you include a callback as the last argument in a function, then PouchDB assumes you want the callback style. Otherwise it assumes you want the promise style.&lt;/p&gt; 
&lt;p&gt;The big advantage of working with Promises in asynchronous code is that you can always attach a catch function to the end of a big promise chain, and any errors that occur along the way will show up at the end.&lt;/p&gt; 
&lt;p&gt;This avoids endless if (err) {} checking in the callback world:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;doSomething(function (err, result) {
  if (err) {
    // handle error
  }
  doSomethingElse(function (err, result) {
    if (err) {
      // handle error again...
    }
    doSomethingYetAgain(function (err, result) {
      if (err) {
        // seriously? okay, handle error again...
      }
    });
  });
});
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Instead, in the promise world, you can have a long chain of asynchronous operations with a single catch at the end. To use PouchDB as an example:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;db.put({_id: &apos;charlie&apos;, age: 21}).then(function () {
  return db.get(&apos;charlie&apos;);
}).then(function (charlie) {
  // increment Charlie&apos;s age
  charlie.age++;
  return db.put(charlie);
}).then(function () {
  return db.get(&apos;charlie&apos;);
}).then(function (charlie) {
  // increment Charlie&apos;s age again
  charlie.age++;
  return db.put(charlie);
}).then(function () {
  return db.get(&apos;charlie&apos;);
}).then(function (charlie) {
  console.log(charlie);
}).catch(function (err) {
  console.log(err);
});
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;You should see:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;{&quot;age&quot;:23,&quot;_id&quot;:&quot;charlie&quot;,&quot;_rev&quot;:&quot;3-e794618b4e39ed566cc68b56f5426e8e&quot;}
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;You can see a live example of this code.&lt;/p&gt; 
&lt;p&gt;In this example, we put/get a document 3 times in a row. At the very end, there is a catch() statement to catch any errors along the way.&lt;/p&gt; 
&lt;p&gt;What kind of errors might we run into? Well, let&apos;s imagine that we accidentally misspell the id &apos;charlie&apos; at some point. In this case, we will gracefully catch the error. Here&apos;s another live example.&lt;/p&gt; 
&lt;p&gt;You should see:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;{&quot;status&quot;:404,&quot;name&quot;:&quot;not_found&quot;,&quot;message&quot;:&quot;missing&quot;}
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;This is really nice! No matter where the misspelling is, the error can be handled within a single function. That&apos;s much nicer than having to do if (err){} an endless number of times!&lt;/p&gt; 
&lt;p&gt;If you&apos;ve been doing promises for awhile, you might have seen this instead:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;db.get(&apos;charlie&apos;).then(function (charlie) {
  // we got the charlie doc
}, function (err) {
  // we got an error
})
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;This is equivalent to:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;db.get(&apos;charlie&apos;).then(function (charlie) {
  // we got the charlie doc
}).catch(function (err) {
  // we got an error
})
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;The catch() method is just syntactic sugar. You can use either format.&lt;/p&gt; 
&lt;p&gt;Often in our code, we&apos;ll want to get() a document, and if it doesn&apos;t exist, we want to create some default. For instance, let&apos;s say we have a configuration object. We want to provide some reasonable defaults for our config:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;{
  _id: &apos;config&apos;,
  background: &apos;blue&apos;,
  foreground: &apos;white&apos;,
  sparkly: &apos;false&apos;
}
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;This is a pretty good default setting! So let&apos;s write the code to set it as our default.&lt;/p&gt; 
&lt;p&gt;Thankfully, promises make this rather easy:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;db.get(&apos;config&apos;).catch(function (err) {
  if (err.name === &apos;not_found&apos;) {
    return {
      _id: &apos;config&apos;,
      background: &apos;blue&apos;,
      foreground: &apos;white&apos;,
      sparkly: &apos;false&apos;
    };
  } else { // hm, some other error
    throw err;
  }
}).then(function (configDoc) {
  // sweet, here is our configDoc
}).catch(function (err) {
  // handle any errors
});
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;This code is doing the following:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Try to get() a doc with _id equal to &apos;config&apos;&lt;/li&gt; 
 &lt;li&gt;If it doesn&apos;t find it, return the default doc&lt;/li&gt; 
 &lt;li&gt;Otherwise, you&apos;ll just get back the existing document&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;A common question from new PouchDB/CouchDB users is: why do we have to deal with _rev at all? Why can&apos;t I just put() the document without providing a _rev?&lt;/p&gt; 
&lt;p&gt;The answer is: because _revs are what makes sync work so well. PouchDB asks for a little upfront effort with managing document revisions, so that later on, sync is a breeze.&lt;/p&gt; 
&lt;p&gt;In fact, you are probably already familiar with a system that forces you to go through a similar dance. This system is called Git.&lt;/p&gt; 
&lt;p&gt;PouchDB and CouchDB&apos;s document revision structure is very similar to Git&apos;s. In fact, each document&apos;s revision history is stored as a tree (exactly like Git), which allows you to handle conflicts when any two databases get out of sync.&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;rev 3-a  rev 3-b
      \___/
        |
      rev 2
        |
      rev 1
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Conflicts will be discussed later in this guide. For now, you can think of revisions as being a single lineage:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;  rev 4
    |
  rev 3
    |
  rev 2
    |
  rev 1
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;When you remove() a document, it&apos;s not really deleted; it just gets a _deleted attribute added to it.&lt;/p&gt; 
&lt;p&gt;That is, the database saves a tombstone at the end of the revision tree.&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;{_id: &apos;foo&apos;, _rev: &apos;4-z&apos;, _deleted: true}
            |
{_id: &apos;foo&apos;, _rev: &apos;3-y&apos;}
            |
{_id: &apos;foo&apos;, _rev: &apos;2-x&apos;}
            |
{_id: &apos;foo&apos;, _rev: &apos;1-w&apos;}
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;There are three ways of deleting a document, which are all equivalent:&lt;/p&gt; 
&lt;p&gt;1) You can call db.remove(doc):&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;db.get(&apos;mydoc&apos;).then(function (doc) {
  return db.remove(doc);
});
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;2) You can call db.remove(doc._id, doc._rev):&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;db.get(&apos;mydoc&apos;).then(function (doc) {
  return db.remove(doc._id, doc._rev);
});
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;3) You can call db.put(doc) with _deleted set to true:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;db.get(&apos;mydoc&apos;).then(function (doc) {
  doc._deleted = true;
  return db.put(doc);
});
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Of course, you will want to add catch() to the end of all these, unless you like to live dangerously.&lt;/p&gt; 
&lt;p&gt;You can get(), put(), and remove() single documents to your heart&apos;s content, but a database isn&apos;t a database unless it can handle many operations at once!&lt;/p&gt; 
&lt;p&gt;PouchDB provides two methods for bulk operations - bulkDocs() for bulk writes, and allDocs() for bulk reads.&lt;/p&gt; 
&lt;p&gt;Attachments are where PouchDB can get really fun. The big difference between storage engines like WebSQL/IndexedDB and the older localStorage API is that you can stuff a lot more data in it. PouchDB attachments allow you to use that to full advantage to store images, MP3s, zip files, or whatever you want. As their name implies, attachments are attached to documents. You can work with attachments either in base64-encoded format, or as a Blob.&lt;/p&gt; 
&lt;p&gt;For example, here is a very simple document with a plain text attachment, stored as base64.&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;db.put({
  _id: &apos;mydoc&apos;,
  _attachments: {
    &apos;myattachment.txt&apos;: {
      content_type: &apos;text/plain&apos;,
      data: &apos;aGVsbG8gd29ybGQ=&apos;
    }
  }
});
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Our document has the usual _id field, but it also has a special _attachments field that holds the attachments. Documents can have as many attachments as you want.&lt;/p&gt; 
&lt;p&gt;As it turns out, &apos;aGVsbG8gd29ybGQ=&apos; is just the string &apos;hello world&apos; encoded in base64. You can use the atob() and btoa() methods in your browser to verify.&lt;/p&gt; 
&lt;p&gt;btoa(&apos;hello world&apos;) // &quot;aGVsbG8gd29ybGQ=&quot;&lt;br&gt; atob(&apos;aGVsbG8gd29ybGQ=&apos;) // &quot;hello world&quot;&lt;br&gt; Let&apos;s see what happens after we store this document. If you try to get() it normally, you may be surprised to see that the attachment data itself isn&apos;t returned:&lt;/p&gt; 
&lt;p&gt;db.get(&apos;mydoc&apos;).then(function (doc) {&lt;br&gt; console.log(doc);&lt;br&gt; });&lt;br&gt; The returned document will look like this:&lt;/p&gt; 
&lt;p&gt;{&lt;br&gt; &quot;_attachments&quot;: {&lt;br&gt; &quot;myattachment.txt&quot;: {&lt;br&gt; &quot;content_type&quot;: &quot;text/plain&quot;,&lt;br&gt; &quot;digest&quot;: &quot;md5-XrY7u+Ae7tCTyyK7j1rNww==&quot;,&lt;br&gt; &quot;stub&quot;: true&lt;br&gt; }&lt;br&gt; },&lt;br&gt; &quot;_id&quot;: &quot;mydoc&quot;,&lt;br&gt; &quot;_rev&quot;: &quot;1-e8a84187bb4e671f27ec11bdf7320aaa&quot;&lt;br&gt; }&lt;br&gt; You can see a live example of this code.&lt;/p&gt; 
&lt;p&gt;By default, PouchDB will only give you an attachment stub, which contains a digest, i.e. the md5sum of the binary attachment.&lt;/p&gt; 
&lt;p&gt;To get the full attachments when using get() or allDocs(), you need to specify {attachments: true}:&lt;/p&gt; 
&lt;p&gt;db.get(&apos;mydoc&apos;, {attachments: true}).then(function (doc) {&lt;br&gt; console.log(doc);&lt;br&gt; });&lt;br&gt; Then you&apos;ll get back the full attachment, base64-encoded:&lt;/p&gt; 
&lt;p&gt;{&lt;br&gt; &quot;_attachments&quot;: {&lt;br&gt; &quot;myattachment.txt&quot;: {&lt;br&gt; &quot;content_type&quot;: &quot;text/plain&quot;,&lt;br&gt; &quot;digest&quot;: &quot;md5-XrY7u+Ae7tCTyyK7j1rNww==&quot;,&lt;br&gt; &quot;data&quot;: &quot;aGVsbG8gd29ybGQ=&quot;&lt;br&gt; }&lt;br&gt; },&lt;br&gt; &quot;_id&quot;: &quot;mydoc&quot;,&lt;br&gt; &quot;_rev&quot;: &quot;1-e8a84187bb4e671f27ec11bdf7320aaa&quot;&lt;br&gt; }&lt;br&gt; You can see a live example of this code.&lt;/p&gt; 
&lt;p&gt;Plaintext is cool and all, but you know what would be really awesome? Storing images.&lt;/p&gt; 
&lt;p&gt;So let&apos;s do it! In this example, we&apos;ll put a document with a small icon attachment, represented as a base64-encoded string. Then we&apos;ll fetch it and display the icon as a normal &lt;img src=&quot;https://tedneward.github.io/Research/storage/&quot;&gt; tag:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;db.put({
  _id: &apos;meowth&apos;,
  _attachments: {
    &apos;meowth.png&apos;: {
      content_type: &apos;image/png&apos;,
      data: &apos;iVBORw0KGgoAAAANSUhEUgAAACgAAAAkCAIAAAB0Xu9BAAAABGdBTUEAALGPC/xhBQAAAuNJREFUWEetmD1WHDEQhDdxRMYlnBFyBIccgdQhKVcgJeQMpE5JSTd2uqnvIGpVUqmm9TPrffD0eLMzUn+qVnXPwiFd/PP6eLh47v7EaazbmxsOxjhTT88z9hV7GoNF1cUCvN7TTPv/gf/+uQPm862MWTL6fff4HfDx4S79/oVAlAUwqOmYR0rnazuFnhfOy/ErMKkcBFOr1vOjUi2MFn4nuMil6OPh5eGANLhW3y6u3aH7ijEDCxgCvzFmimvc95TekZLyMSeJC68Bkw0kqUy1K87FlpGZqsGFCyqEtQNDdFUtFctTiuhnPKNysid/WFEFLE2O102XJdEE+8IgeuGsjeJyGHm/xHvQ3JtKVsGGp85g9rK6xMHtvHO9+WACYjk5vkVM6XQ6OZubCJvTfPicYPeHO2AKFl5NuF5UK1VDUbeLxh2BcRGKTQE3irHm3+vPj6cfCod50Eqv5QxtwBQUGhZhbrGVuRia1B4MNp6edwBxld2sl1splfHCwfsvCZfrCQyWmX10djjOlWJSSy3VQlS6LmfrgNvaieRWx1LZ6s9co+P0DLsy3OdLU3lWRclQsVcHJBcUQ0k9/WVVrmpRzYQzpgAdQcAXxZzUnFX3proannrYH+Vq6KkLi+UkarH09mC8YPr2RMWOlEqFkQClsykGEv7CqCUbXcG8+SaGvJ4a8d4y6epND+pEhxoN0vWUu5ntXlFb5/JT7JfJJqoTdy9u9qc7ax3xJRHqJLADWEl23cFWl4K9fvoaCJ2BHpmJ3s3z+O0U/DmzdMjB9alWZtg4e3yxzPa7lUR7nkvxLHO9+tvJX3mtSDpwX8GajB283I8R8a7D2MhUZr1iNWdny256yYLd52DwRYBtRMvE7rsmtxIUE+zLKQCDO4jlxB6CZ8M17GhuY+XTE8vNhQiIiSE82ZsGwk1pht4ZSpT0YVpon6EvevOXXH8JxVR78QzNuamupW/7UB7wO/+7sG5V4ekXb4cL5Lyv+4IAAAAASUVORK5CYII=&apos;
    }
  }
}).then(function () {
  return db.getAttachment(&apos;meowth&apos;, &apos;meowth.png&apos;);
}).then(function (blob) {
  var url = URL.createObjectURL(blob);
  var img = document.createElement(&apos;img&apos;);
  img.src = url;
  document.body.appendChild(img);
}).catch(function (err) {
  console.log(err);
});
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;You should be unsurprised to see a cat smiling back at you. If the kitten theme bothers you, then you haven&apos;t been on the Internet very long.&lt;/p&gt; 
&lt;p&gt;How does this code work? First off, we are making use of the URL.createObjectURL() method, which is a standard HTML5 method that converts a Blob to a URL that we can easily use as the src of an img.&lt;/p&gt; 
&lt;p&gt;Second off, we are using the getAttachment() API, which returns a Blob rather than a base64-encoded string. To be clear: we can always convert between base64 and Blobs, but in this case, getAttachment() is just more convenient.&lt;/p&gt; 
&lt;p&gt;Up to now, we&apos;ve been supplying our attachments as base64-encoded strings. But we can also create the Blobs ourselves and store those directly in PouchDB.&lt;/p&gt; 
&lt;p&gt;Another shortcut we can use is the putAttachment() API, which simply modifies the existing document to hold a new attachment. Or, if the document does not exist, it will create an empty one.&lt;/p&gt; 
&lt;p&gt;In Node.js, PouchDB uses Buffers instead of Blobs. Otherwise, the same rules apply.&lt;br&gt; For instance, we can read the image data from an &lt;img src=&quot;https://tedneward.github.io/Research/storage/&quot;&gt; tag using a canvas element, and then directly write that Blob to PouchDB:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;function convertImgToBlob(img, callback) {
  var canvas = document.createElement(&apos;canvas&apos;);
  var context = canvas.getContext(&apos;2d&apos;);
  context.drawImage(img, 0, 0);

    // Warning: toBlob() isn&apos;t supported by every browser.
    // You may want to use blob-util.
  canvas.toBlob(callback, &apos;image/png&apos;);
}

var catImage = document.getElementById(&apos;cat&apos;);
convertImgToBlob(catImage, function (blob) {
  db.putAttachment(&apos;meowth&apos;, &apos;meowth.png&apos;, blob, &apos;image/png&apos;).then(function () {
    return db.get(&apos;meowth&apos;, {attachments: true});
  }).then(function (doc) {
    console.log(doc);
  });
});
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;This stores exactly the same image content as in the other example, which you can confirm by checking the base64-encoded output.&lt;/p&gt; 
&lt;p&gt;Blobs can be tricky to work with, especially when it comes to cross-browser support. You may find blob-util to be a useful addition to the attachment API. For instance, it has an imgSrcToBlob() method that will work cross-browser.&lt;/p&gt; 
&lt;p&gt;You can also upload a file with the HTML5 File API and store it directly in the database, because the data you get from the &lt;input type=&quot;file&quot;&gt; element is already a Blob. (See: Blob API and File API, which inherits properties from the Blob Interface.)&lt;/p&gt; 
&lt;p&gt;Here is an example of allowing a user to choose a file from their filesystem:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;&amp;lt;input type=&quot;file&quot;&amp;gt;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;And then &quot;uploading&quot; that file directly into PouchDB:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;var input = document.querySelector(&apos;input&apos;);
input.addEventListener(&apos;change&apos;, function () {
  var file = input.files[0]; // file is a Blob

  db.put({
    _id: &apos;mydoc&apos;,
    _attachments: {
      filename: {
        type: file.type,
        data: file
      }
    }
  }).catch(function (err) {
    console.log(err);
  });
});
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Select a file and you will see the stored file, size, and type, which are valid Blob properties. If you choose an image, it will also show the image!&lt;/p&gt; 
&lt;p&gt;Whether you supply attachments as base64-encoded strings or as Blobs/Buffers, PouchDB will try to store them in the most efficient way.&lt;/p&gt; 
&lt;p&gt;So when you insert your attachments, either format is acceptable. For instance, you can put Blobs/Buffers using put():&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;db.put({
  _id: &apos;mydoc&apos;,
  _attachments: {
    &apos;myattachment.txt&apos;: {
      content_type: &apos;text/plain&apos;,
      data: myBlob
    }
  }
});
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;And you can also pass base64-encoded strings to putAttachment():&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;db.putAttachment(&apos;mydoc&apos;, &apos;myattachment.png&apos;, myBase64String, &apos;image/png&apos;);
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;You can also insert multiple attachments at once using put():&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;db.put({
  _id: &apos;mydoc&apos;,
  _attachments: {
    &apos;myattachment1.txt&apos;: {
      content_type: &apos;text/plain&apos;,
      data: myBlob1
    },
    &apos;myattachment2.txt&apos;: {
      content_type: &apos;text/plain&apos;,
      data: myBlob2
    },
    &apos;myattachment3.txt&apos;: {
      content_type: &apos;text/plain&apos;,
      data: myBlob3
    },
    // etc.
  }
});
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;The bulkDocs() and post() APIs also accept attachments in either format.&lt;/p&gt; 
&lt;p&gt;When you fetch attachments, however, getAttachment() will always return Blobs/Buffers.&lt;/p&gt; 
&lt;p&gt;The other &quot;read&quot; APIs, such as get(), allDocs(), changes(), and query() have an {attachments: true} option that returns the attachments base64-encoded strings. If you add {binary: true}, though, they will return Blobs/Buffers.&lt;/p&gt; 
&lt;p&gt;Performance tip: If you can insert and retrieve your attachments using only Blobs/Buffers, then you will typically get better performance, especially when it comes to memory usage. The base64 string format is mostly provided for developer convenience and debugging.&lt;/p&gt; 
&lt;p&gt;Blobs have their own type, but there is also a content_type that you specify when you store it in PouchDB:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;var myBlob = new Blob([&apos;I am plain text!&apos;], {type: &apos;text/plain&apos;});
console.log(myBlob.type); // &apos;text/plain&apos;

db.put({
  _id: &apos;mydoc&apos;,
  _attachments: {
    &apos;myattachment.txt&apos;: {
      content_type: &apos;text/plain&apos;,
      data: myBlob
    }
  }
});
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;The reason for this redundancy is 1) Buffers in Node do not have a type, and 2) the CouchDB attachment format requires it.&lt;/p&gt; 
&lt;p&gt;So for best results, you should ensure that your Blobs have the same type as the one reported to PouchDB. Otherwise you may see inconsistent behavior (e.g. in IndexedDB, where the Blob is stored as-is on compatible browsers).&lt;/p&gt; 
&lt;p&gt;PouchDB and CouchDB were designed for one main purpose: sync. Jason Smith has a great quote about this:&lt;/p&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;The way I like to think about CouchDB is this: CouchDB is bad at everything, except syncing. And it turns out that&apos;s the most important feature you could ever ask for, for many types of software.&quot;&lt;/p&gt; 
&lt;/blockquote&gt; 
&lt;p&gt;When you first start using CouchDB, you may become frustrated because it doesn&apos;t work quite like other databases. Unlike most databases, CouchDB requires you to manage revisions (_rev), which can be tedious.&lt;/p&gt; 
&lt;p&gt;However, CouchDB was designed with sync in mind, and this is exactly what it excels at. Many of the rough edges of the API serve this larger purpose. For instance, managing your document revisions pays off in the future, when you eventually need to start dealing with conflicts.&lt;/p&gt; 
&lt;p&gt;CouchDB sync has a unique design. Rather than relying on a master/follower architecture, CouchDB supports a multi-master architecture. You can think of this as a system where any node can be written to or read from, and where you don&apos;t have to care which one is the &quot;master&quot; and which one is the &quot;follower.&quot; In CouchDB&apos;s egalitarian world, every citizen is as worthy as another.&lt;/p&gt; 
&lt;p&gt;When you use PouchDB, CouchDB, and other members of the Couch family, you don&apos;t have to worry which database is the &quot;single source of truth.&quot; They all are. According to the CAP theorem, a database can only have at most 2 of 3 properties: Consistency, Availability, or Partition-Tolerance. Typical relational databases such as MySQL are CP, which means they are consistent and tolerant to node partitions, at the expense of availability. CouchDB is an AP database, meaning that it&apos;s Partition-Tolerant, every node is Available at all times, but it&apos;s only eventually Consistent.&lt;/p&gt; 
&lt;p&gt;To illustrate, imagine a multi-node architecture with CouchDB servers spread across several continents. As long as you&apos;re willing to wait, the data will eventually flow from Australia to Europe to North America to wherever. Users around the world running PouchDB in their browsers or Couchbase Lite/Cloudant Sync in their smartphones experience the same privileges. The data won&apos;t show up instantaneously, but depending on the Internet connection speed, it&apos;s usually close enough to real-time.&lt;/p&gt; 
&lt;p&gt;In cases of conflict, CouchDB will choose an arbitrary winner that every node can agree upon deterministically. However, conflicts are still stored in the revision tree (similar to a Git history tree), which means that app developers can either surface the conflicts to the user, or just ignore them.&lt;/p&gt; 
&lt;p&gt;In this way, CouchDB replication &quot;just works.&quot;&lt;/p&gt; 
&lt;p&gt;As you already know, you can create either local PouchDBs:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;var localDB = new PouchDB(&apos;mylocaldb&apos;)
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;or remote PouchDBs:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;var remoteDB = new PouchDB(&apos;http://localhost:5984/myremotedb&apos;)
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;This pattern comes in handy when you want to share data between the two.&lt;/p&gt; 
&lt;p&gt;The simplest case is unidirectional replication, meaning you just want one database to mirror its changes to a second one. Writes to the second database, however, will not propagate back to the master database.&lt;/p&gt; 
&lt;p&gt;To perform unidirectional replication, you simply do:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;localDB.replicate.to(remoteDB).on(&apos;complete&apos;, function () {
  // yay, we&apos;re done!
}).on(&apos;error&apos;, function (err) {
  // boo, something went wrong!
});
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Congratulations, all changes from the localDB have been replicated to the remoteDB.&lt;/p&gt; 
&lt;p&gt;However, what if you want bidirectional replication? You could do:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;localDB.replicate.to(remoteDB);
localDB.replicate.from(remoteDB);
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;However, to make things easier for your poor tired fingers, PouchDB has a shortcut API:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;localDB.sync(remoteDB);
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;These two code blocks above are equivalent. And the sync API supports all the same events as the replicate API:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;localDB.sync(remoteDB).on(&apos;complete&apos;, function () {
  // yay, we&apos;re in sync!
}).on(&apos;error&apos;, function (err) {
  // boo, we hit an error!
});
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Live replication (or &quot;continuous&quot; replication) is a separate mode where changes are propagated between the two databases as the changes occur. In other words, normal replication happens once, whereas live replication happens in real time.&lt;/p&gt; 
&lt;p&gt;To enable live replication, you simply specify {live: true}:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;localDB.sync(remoteDB, {
  live: true
}).on(&apos;change&apos;, function (change) {
  // yo, something changed!
}).on(&apos;error&apos;, function (err) {
  // yo, we got an error! (maybe the user went offline?)
});
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;However, there is one gotcha with live replication: what if the user goes offline? In those cases, an error will be thrown and replication will stop.&lt;/p&gt; 
&lt;p&gt;You can allow PouchDB to automatically handle this error, and retry until the connection is re-established, by using the retry option:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;localDB.sync(remoteDB, {
  live: true,
  retry: true
}).on(&apos;change&apos;, function (change) {
  // yo, something changed!
}).on(&apos;paused&apos;, function (info) {
  // replication was paused, usually because of a lost connection
}).on(&apos;active&apos;, function (info) {
  // replication was resumed
}).on(&apos;error&apos;, function (err) {
  // totally unhandled error (shouldn&apos;t happen)
});
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;This is ideal for scenarios where the user may be flitting in and out of connectivity, such as on mobile devices.&lt;/p&gt; 
&lt;p&gt;Sometimes, you may want to manually cancel replication – for instance, because the user logged out. You can do so by calling cancel() and then waiting for the &apos;complete&apos; event:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;var syncHandler = localDB.sync(remoteDB, {
  live: true,
  retry: true
});

syncHandler.on(&apos;complete&apos;, function (info) {
  // replication was canceled!
});

syncHandler.cancel(); // &amp;lt;-- this cancels it
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;The replicate API also supports canceling:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;var replicationHandler = localDB.replicate.to(remoteDB, {
  live: true,
  retry: true
});

replicationHandler.on(&apos;complete&apos;, function (info) {
  // replication was canceled!
});

replicationHandler.cancel(); // &amp;lt;-- this cancels it
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;One thing to note about replication is that it tracks the data within a database, not the database itself. If you destroy() a database that is being replicated to, the next time the replication starts it will transfer all of the data again, recreating the database to the state it was before it was destroyed. If you want the data within the database to be deleted you will need to delete via remove() or bulkDocs(). The pouchdb-erase plugin can help you remove the entire contents of a database.&lt;/p&gt; 
&lt;p&gt;Any PouchDB object can replicate to any other PouchDB object. So for instance, you can replicate two remote databases, or two local databases. You can also replicate from multiple databases into a single one, or from a single database into many others.&lt;/p&gt; 
&lt;p&gt;This can be very powerful, because it enables lots of fancy scenarios. For example:&lt;/p&gt; 
&lt;p&gt;You have an in-memory PouchDB that replicates with a local PouchDB, acting as a cache.&lt;/p&gt; 
&lt;p&gt;You have many remote CouchDB databases that the user may access, and they are all replicated to the same local PouchDB.&lt;/p&gt; 
&lt;p&gt;You have many local PouchDB databases, which are mirrored to a single remote CouchDB as a backup store.&lt;/p&gt; 
&lt;p&gt;The only limits are your imagination and your disk space.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>RavenDB</title>
      <link>https://tedneward.github.io/Research/storage/ravendb/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/ravendb/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://ravendb.net/&quot;&gt;Website&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Rel</title>
      <link>https://tedneward.github.io/Research/storage/rel/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/rel/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://reldb.org/c/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/DaveVoorhis/Rel&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>RocksDB</title>
      <link>https://tedneward.github.io/Research/storage/rocksdb/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/rocksdb/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://rocksdb.org/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/facebook/rocksdb/&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>OpenTSDB (Time-Series Database)</title>
      <link>https://tedneward.github.io/Research/storage/opemtsdb/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/opemtsdb/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://opentsdb.net/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/OpenTSDB/opentsdb&quot;&gt;Source&lt;/a&gt; | &lt;a href=&quot;https://opentsdb.net/docs/build/html/index.html#opentsdb-3-0&quot;&gt;Docs&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;OpenTSDB was written to address a common need: store, index and serve metrics collected from computer systems (network gear, operating systems, applications) at a large scale, and make this data easily accessible and graphable.&lt;/p&gt; 
&lt;p&gt;Thanks to HBase&apos;s scalability, OpenTSDB allows you to collect thousands of metrics from tens of thousands of hosts and applications, at a high rate (every few seconds). OpenTSDB will never delete or downsample data and can easily store hundreds of billions of data points.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Outerbase</title>
      <link>https://tedneward.github.io/Research/storage/outerbase/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/outerbase/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.outerbase.com/&quot;&gt;Website&lt;/a&gt;&lt;/p&gt; 
&lt;h3&gt;Articles&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.outerbase.com/blog/outerbase-studio-open-source-database-management/&quot;&gt;&quot;Outerbase Studio&quot;&lt;/a&gt; (&lt;a href=&quot;https://github.com/outerbase/studio&quot;&gt;Source&lt;/a&gt;)&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Planet Scale</title>
      <link>https://tedneward.github.io/Research/storage/planet-scale/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/planet-scale/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://planetscale.com/&quot;&gt;Website&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Built on &lt;a href=&quot;./vitess.md&quot;&gt;Vitess&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&quot;A branching database allows you to create different branches from your main database that you can use for different purposes. You can imagine this workflow as something very similar to a version control system like Git where you make changes to a project without breaking the entire codebase.&lt;/p&gt; 
&lt;p&gt;&quot;You can create a copy of your main or production database into a separate database branch. Then, you can experiment in that database branch, make changes and when you’re completely satisfied with them, merge them back to your main database. Thus it’s highly efficient and intuitive to play around and experiment with your database while keeping your production database intact.&quot;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Presto (PrestoDB, PrestoSQL)</title>
      <link>https://tedneward.github.io/Research/storage/prestodb/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/prestodb/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://prestodb.io&quot;&gt;Website&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;See also: &lt;a href=&quot;couchbase-lite.html&quot;&gt;couchbase-lite&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Realm (Realm Database, Realm Object Server)</title>
      <link>https://tedneward.github.io/Research/storage/realm/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/realm/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://realm.io/products/realm-database&quot;&gt;Realm Database&lt;/a&gt; | &lt;a href=&quot;https://realm.io/products/realm-platform&quot;&gt;Realm Platform&lt;/a&gt; | &lt;a href=&quot;https://realm.io/products/realm-studio&quot;&gt;Realm Studio&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Realm Object Server and Realm Database combine to make the Realm Platform.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>RestDB.io</title>
      <link>https://tedneward.github.io/Research/storage/restdb/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/restdb/index.html</guid>
      	<description>
	&lt;p&gt;&quot;restdb.io is probably the easiest online NoSQL database backend for web and serverless &quot;low code&quot; applications. Model your information quickly. The data management application, schema and REST API are instantly available using our powerful API Automation technology.&lt;/p&gt; 
&lt;p&gt;&quot;In the backend, users collaborate and work with data in multiple ways. A centralized search let&apos;s users quickly search through the entire database quickly (if given access). It&apos;s also a breeze to navigate the database relationships.&lt;/p&gt; 
&lt;p&gt;&quot;restdb.io NoSQL databases can also serve web pages. Use HTML, Javascript, jQuery, Angular, ReactJS (or your favorite framework) on restdb.io Pages with server-side data-binding. Add your own secure domains for the web pages and the REST API.&quot;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://restdb.io/&quot;&gt;Website&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>RxDB</title>
      <link>https://tedneward.github.io/Research/storage/rxdb/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/rxdb/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://rxdb.info/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/pubkey/rxdb&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;RxDB is based on a storage interface that enables you to swap out the underlying storage engine. This increases code reuse because the same database code can be used in different JavaScript environments by just switching out the storage settings. You can use RxDB on top of IndexedDB, OPFS, LokiJS, Dexie.js, in-memory, SQLite, in a WebWorker thread and even on top of FoundationDB.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>OrientDB</title>
      <link>https://tedneward.github.io/Research/storage/orientdb/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/orientdb/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://orientdb.org/&quot;&gt;Community website&lt;/a&gt; | &lt;a href=&quot;https://github.com/orientechnologies/orientdb&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Owncloud</title>
      <link>https://tedneward.github.io/Research/storage/owncloud/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/owncloud/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://owncloud.com/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/owncloud/core&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>PlanetScale</title>
      <link>https://tedneward.github.io/Research/storage/planetscale/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/planetscale/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://planetscale.com/&quot;&gt;Website&lt;/a&gt; | Commercial&lt;/p&gt; 
&lt;p&gt;What’s interesting about PlanetScale is that it’s a branching database, a novel workflow that has emerged only recently but appears to be quite promising. But what is a branching database? A branching database allows you to create different branches from your main database that you can use for different purposes. You can imagine this workflow as something very similar to a version control system like Git where you make changes to a project without breaking the entire codebase.&lt;/p&gt; 
&lt;p&gt;You can create a copy of your main or production database into a separate database branch. Then, you can experiment in that database branch, make changes and when you’re completely satisfied with them, merge them back to your main database. Thus it’s highly efficient and intuitive to play around and experiment with your database while keeping your production database intact.&lt;/p&gt; 
&lt;p&gt;PlanetScale also adds branches to your database so you can test schema changes on an isolated development branch. This branch is separate from the production branch or your main database. This provides an isolated working environment without explicitly creating a staging or testing environment for experimenting with schema changes. You can read more on what branching means and how PlanetScale uses this concept in their documentation page.&lt;/p&gt; 
&lt;p&gt;PlanetScale automatically creates daily backups and protects direct schema changes on your production branch right out of the box, reducing the possibility of accidentally corrupting the production database.&lt;/p&gt; 
&lt;p&gt;Non-blocking schema changes are yet another interesting feature it provides. You can create and deploy a request to update your tables without disrupting your users when you want to change your database schema. It is also simple to integrate with third-party tools like Prisma.&lt;/p&gt; 
&lt;p&gt;Prisma is an open-source database toolkit that provides a type-safe ORM (Object-Relational Mapping) layer for modern web applications. When you want to change your database schema, you can use Prisma’s migration feature to generate the necessary SQL scripts that can be applied to your database in a non-blocking way, without disrupting your users. This way you can integrate your PlanetScale with Prisma to efficiently update your schema whilst your application remains online.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Probase</title>
      <link>https://tedneward.github.io/Research/storage/probase/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/probase/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.microsoft.com/en-us/research/project/probase/&quot;&gt;Website&lt;/a&gt;&lt;/p&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;The goal of Probase to enable machines to better understand human communication. For example, in natural language processing and speech analysis, knowledgebases can help reduce the ambiguities in language. As Probase has a knowledgebase as large as the concept space (of wordly facts) in a human mind, it has unique advantages in these applications.Besides, with the probabilistic knowledge provided by Probase, we build several interesting applications, such as topic search, web table search and document understanding.&lt;/p&gt; 
&lt;/blockquote&gt;
	</description>
    </item>
    <item>
      <title>Redis</title>
      <link>https://tedneward.github.io/Research/storage/redis/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/redis/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;http://redis.io/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/redis/redis&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Docker: &lt;code&gt;docker run -p 6379:6379 -it --rm redis&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://redis.io/commands/&quot;&gt;Commands&lt;/a&gt;&lt;/p&gt; 
&lt;h2&gt;&lt;a href=&quot;https://redis.io/docs/&quot;&gt;Docs&lt;/a&gt; (notes)&lt;/h2&gt; 
&lt;p&gt;Redis is a data structure server. At its core, Redis provides a collection of native data types that help you solve a wide variety of problems, from caching to queuing to event processing.&lt;/p&gt; 
&lt;h3&gt;Keys&lt;/h3&gt; 
&lt;p&gt;Redis keys are binary safe, this means that you can use any binary sequence as a key, from a string like &quot;foo&quot; to the content of a JPEG file. The empty string is also a valid key.&lt;/p&gt; 
&lt;p&gt;Very long keys are not a good idea. For instance a key of 1024 bytes is a bad idea not only memory-wise, but also because the lookup of the key in the dataset may require several costly key-comparisons. Even when the task at hand is to match the existence of a large value, hashing it (for example with SHA1) is a better idea, especially from the perspective of memory and bandwidth.&lt;/p&gt; 
&lt;p&gt;Very short keys are often not a good idea. There is little point in writing &quot;u1000flw&quot; as a key if you can instead write &quot;user:1000:followers&quot;. The latter is more readable and the added space is minor compared to the space used by the key object itself and the value object. While short keys will obviously consume a bit less memory, your job is to find the right balance.&lt;/p&gt; 
&lt;p&gt;Try to stick with a schema. For instance &quot;object-type:id&quot; is a good idea, as in &quot;user:1000&quot;. Dots or dashes are often used for multi-word fields, as in &quot;comment:4321:reply.to&quot; or &quot;comment:4321:reply-to&quot;.&lt;/p&gt; 
&lt;p&gt;The maximum allowed key size is 512 MB.&lt;/p&gt; 
&lt;h3&gt;Strings&lt;/h3&gt; 
&lt;p&gt;Redis strings are the most basic Redis data type, representing a sequence of bytes.&lt;/p&gt; 
&lt;p&gt;The Redis String type is the simplest type of value you can associate with a Redis key. It is the only data type in Memcached, so it is also very natural for newcomers to use it in Redis.&lt;/p&gt; 
&lt;p&gt;Since Redis keys are strings, when we use the string type as a value too, we are mapping a string to another string. The string data type is useful for a number of use cases, like caching HTML fragments or pages.&lt;/p&gt; 
&lt;h3&gt;Lists&lt;/h3&gt; 
&lt;p&gt;Redis lists are lists of strings sorted by insertion order.&lt;/p&gt; 
&lt;h3&gt;Sets&lt;/h3&gt; 
&lt;p&gt;Redis sets are unordered collections of unique strings that act like the sets from your favorite programming language (for example, Java HashSets, Python sets, and so on). With a Redis set, you can add, remove, and test for existence O(1) time (in other words, regardless of the number of set elements).&lt;/p&gt; 
&lt;h3&gt;Hashes&lt;/h3&gt; 
&lt;p&gt;Redis hashes are record types modeled as collections of field-value pairs. As such, Redis hashes resemble Python dictionaries, Java HashMaps, and Ruby hashes.&lt;/p&gt; 
&lt;h3&gt;Sorted sets&lt;/h3&gt; 
&lt;p&gt;Redis sorted sets are collections of unique strings that maintain order by each string&apos;s associated score.&lt;/p&gt; 
&lt;h3&gt;Streams&lt;/h3&gt; 
&lt;p&gt;A Redis stream is a data structure that acts like an append-only log. Streams help record events in the order they occur and then syndicate them for processing.&lt;/p&gt; 
&lt;h3&gt;Geospatial indexes&lt;/h3&gt; 
&lt;p&gt;Redis geospatial indexes are useful for finding locations within a given geographic radius or bounding box.&lt;/p&gt; 
&lt;h3&gt;Bitmaps&lt;/h3&gt; 
&lt;p&gt;Redis bitmaps let you perform bitwise operations on strings.&lt;/p&gt; 
&lt;h3&gt;Bitfields&lt;/h3&gt; 
&lt;p&gt;Redis bitfields efficiently encode multiple counters in a string value. Bitfields provide atomic get, set, and increment operations and support different overflow policies.&lt;/p&gt; 
&lt;h3&gt;HyperLogLog&lt;/h3&gt; 
&lt;p&gt;The Redis HyperLogLog data structures provide probabilistic estimates of the cardinality (i.e., number of elements) of large sets.&lt;/p&gt; 
&lt;h3&gt;Extensions&lt;/h3&gt; 
&lt;p&gt;To extend the features provided by the included data types, use one of these options:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Custom server-side functions in Lua.&lt;/li&gt; 
 &lt;li&gt;Custom Redis modules using the modules API or check out the community-supported modules.&lt;/li&gt; 
 &lt;li&gt;Use JSON, querying, time series, and other capabilities provided by Redis Stack.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Reading&lt;/h2&gt; 
&lt;h3&gt;Books&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://redis.com/ebook/redis-in-action/&quot;&gt;Redis in Action&lt;/a&gt; - Josiah L. Carlson&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://openmymind.net/2012/1/23/The-Little-Redis-Book/&quot;&gt;The Little Redis Book&lt;/a&gt; - K. Seguin (PDF, Epub)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.digitalocean.com/community/books/how-to-manage-a-redis-database-ebook&quot;&gt;How To Manage a Redis Database&lt;/a&gt; - Mark Drake (PDF, EPUB)&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>RethinkDB</title>
      <link>https://tedneward.github.io/Research/storage/rethinkdb/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/rethinkdb/index.html</guid>
      	<description>
	&lt;p&gt;&quot;RethinkDB is the first open-source scalable database built for realtime applications. It exposes a new database access model, in which the developer can tell the database to continuously push updated query results to applications without polling for changes. RethinkDB allows developers to build scalable realtime apps in a fraction of the time with less effort.&quot;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://rethinkdb.com/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/rethinkdb/rethinkdb&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;h2&gt;Reading&lt;/h2&gt; 
&lt;h3&gt;Articles&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;Publish-Subscribe with RethinkDB: &lt;a href=&quot;https://rethinkdb.com/docs/publish-subscribe/javascript/&quot;&gt;JavaScript&lt;/a&gt; &lt;a href=&quot;https://rethinkdb.com/docs/publish-subscribe/python/&quot;&gt;Python&lt;/a&gt; &lt;a href=&quot;https://rethinkdb.com/docs/publish-subscribe/ruby/&quot;&gt;Ruby&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Amazon S3 (and Glacier)</title>
      <link>https://tedneward.github.io/Research/storage/s3/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/s3/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://docs.aws.amazon.com/s3/index.html&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://docs.aws.amazon.com/AmazonS3/latest/userguide/index.html&quot;&gt;User Guide&lt;/a&gt; (&lt;a href=&quot;https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-userguide.pdf&quot;&gt;PDF&lt;/a&gt;) | &lt;a href=&quot;https://docs.aws.amazon.com/AmazonS3/latest/API/Welcome.html&quot;&gt;API Reference&lt;/a&gt; (&lt;a href=&quot;https://docs.aws.amazon.com/AmazonS3/latest/API/s3-api.pdf&quot;&gt;PDF&lt;/a&gt;) | &lt;a href=&quot;https://docs.aws.amazon.com/amazonglacier/latest/dev/index.html&quot;&gt;Glacier Developer Guide&lt;/a&gt; (&lt;a href=&quot;https://docs.aws.amazon.com/amazonglacier/latest/dev/glacier-dg.pdf&quot;&gt;PDF&lt;/a&gt;)&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Event-sourcing storage model</title>
      <link>https://tedneward.github.io/Research/storage/models/event-sourcing/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/models/event-sourcing/index.html</guid>
      	<description>
	&lt;p&gt;A storage approach that stores a system’s state as an append-only sequence of events. Instead of updating the current state directly, each change to the system is recorded as an event. These events are then used to reconstruct the system’s state at any point in time.&lt;/p&gt; 
&lt;p&gt;Important Considerations for Event Sourcing&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Event Immutability: Events should be immutable. Once created, they cannot be changed.&lt;/li&gt; 
 &lt;li&gt;Event Sourcing vs. Event-Driven Architecture: While closely related, Event Sourcing is a pattern for storing and reconstructing state, while Event-Driven Architecture is a pattern for loosely coupling components.&lt;/li&gt; 
 &lt;li&gt;Eventual Consistency: Event Sourcing often leads to eventual consistency, meaning the system’s state may not be immediately updated after an event is recorded.&lt;/li&gt; 
 &lt;li&gt;Performance: Event Sourcing can be performance-intensive, especially for systems with high write loads or complex state transitions.&lt;/li&gt; 
 &lt;li&gt;Complexity: Implementing Event Sourcing can be more complex than traditional approaches due to the need for event handling, storage, and reconstruction.&lt;/li&gt; 
 &lt;li&gt;When to Use Event Sourcing&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;Event Sourcing is well-suited for:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Systems that require a complete audit trail of changes.&lt;/li&gt; 
 &lt;li&gt;Systems with complex state transitions or business rules.&lt;/li&gt; 
 &lt;li&gt;Systems that need to be able to replay past events to recover from failures or explore different scenarios.&lt;/li&gt; 
 &lt;li&gt;Systems that benefit from eventual consistency.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;Event Sourcing vs. Event-Driven Architecture: While Event-Driven Architecture and Event Sourcing are often used together, they are distinct concepts:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Event-Driven Architecture: Focuses on decoupling components using events as a communication mechanism.&lt;/li&gt; 
 &lt;li&gt;Event Sourcing: Focuses on storing and reconstructing state using events.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;&lt;a href=&quot;https://github.com/oskardudycz/EventSourcing.NetCore/tree/main/Workshops/IntroductionToEventSourcing&quot;&gt;Introduction to Event Sourcing Workshop&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://github.com/oskardudycz/EventSourcing.NetCore&quot;&gt;Examples and Tutorials of Event Sourcing in .NET&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://leanpub.com/eventmodeling-and-eventsourcing&quot;&gt;Understanding Eventsourcing&lt;/a&gt;: The book by Martin Dilger&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Object storage model</title>
      <link>https://tedneward.github.io/Research/storage/models/object/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/models/object/index.html</guid>
      	<description>
	&lt;p&gt;(Placeholder)&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Text storage model</title>
      <link>https://tedneward.github.io/Research/storage/models/text/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/models/text/index.html</guid>
      	<description>
	&lt;p&gt;(Placeholder)&lt;/p&gt; 
&lt;p&gt;Thinking primarily ElasticSearch and the like.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>MongoDB</title>
      <link>https://tedneward.github.io/Research/storage/mongodb/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/mongodb/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.mongodb.com/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/mongodb/mongo&quot;&gt;Source&lt;/a&gt; | &lt;a href=&quot;https://docs.mongodb.com/manual/&quot;&gt;Docs&lt;/a&gt; | &lt;a href=&quot;https://www.mongodb.com/cloud/atlas&quot;&gt;Cloud-hosted&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://github.com/fakemongo/fongo&quot;&gt;&quot;Fake Mongo&quot;, aka fongo&lt;/a&gt;: faked out in-memory mongo for java&lt;/p&gt; 
&lt;h2&gt;Books&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.tutorialspoint.com/mongodb&quot;&gt;Introduction to MongoDB&lt;/a&gt; - Tutorials Point&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://riptutorial.com/Download/mongodb.pdf&quot;&gt;Learning MongoDB&lt;/a&gt; - Based on Unaffiliated Stack Overflow Documentation (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/chicagoruby/MongoDB_Koans&quot;&gt;MongoDB Koans&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://goalkicker.com/MongoDBBook/&quot;&gt;MongoDB Notes for Professionals&lt;/a&gt; - Compiled from StackOverflow Documentation (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.syncfusion.com/resources/techportal/ebooks/mongodb&quot;&gt;MongoDB Succinctly, Syncfusion&lt;/a&gt; (PDF, Kindle) (email address &lt;em&gt;requested&lt;/em&gt;, not required)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://openmymind.net/2011/3/28/The-Little-MongoDB-Book/&quot;&gt;The Little MongoDB Book&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;hr&gt; 
&lt;p&gt;&lt;a href=&quot;https://docs.mongodb.com/manual/tutorial/store-javascript-function-on-server/&quot;&gt;Store a JS function on the server&lt;/a&gt;: &quot;(NOTE: There are performance limitations to running JavaScript inside of MongoDB.) There is a special system collection named &lt;code&gt;system.js&lt;/code&gt; that can store JavaScript functions for reuse. To store a function, you can use the &lt;code&gt;db.collection.save()&lt;/code&gt;, as in the following examples:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;db.system.js.save(
   {
     _id: &quot;echoFunction&quot;,
     value : function(x) { return x; }
   }
)

db.system.js.save(
   {
     _id : &quot;myAddFunction&quot; ,
     value : function (x, y){ return x + y; }
   }
);
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Once you save a function in the &lt;code&gt;system.js&lt;/code&gt; collection, you can use the function from any JavaScript context; e.g. &lt;code&gt;$where&lt;/code&gt; operator, &lt;code&gt;mapReduce&lt;/code&gt; command or &lt;code&gt;db.collection.mapReduce()&lt;/code&gt;.&quot;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>NeDB</title>
      <link>https://tedneward.github.io/Research/storage/nedb/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/nedb/index.html</guid>
      	<description>
	&lt;p&gt;&quot;Embedded persistent or in memory database for Node.js, nw.js, Electron and browsers, 100% JavaScript, no binary dependency. API is a subset of MongoDB&apos;s. You can use NeDB as an in-memory only datastore or as a persistent datastore. One datastore is the equivalent of a MongoDB collection. Under the hood, NeDB&apos;s persistence uses an append-only format, meaning that all updates and deletes actually result in lines added at the end of the datafile, for performance reasons. The database is automatically compacted (i.e. put back in the one-line-per-document format) every time you load each database within your application.&quot;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://github.com/louischatriot/nedb&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Author considers it to be feature-complete.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>NMemory</title>
      <link>https://tedneward.github.io/Research/storage/nmemory/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/nmemory/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://nmemory.net/&quot;&gt;Website&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>NosDB</title>
      <link>https://tedneward.github.io/Research/storage/nosdb/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/nosdb/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.alachisoft.com/nosdb/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/Alachisoft/NCache&quot;&gt;Github&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Objectivity/DB</title>
      <link>https://tedneward.github.io/Research/storage/objectivitydb/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/objectivitydb/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://objectivity.com/objectivity-db/&quot;&gt;Website&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Commercial&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Graph storage model</title>
      <link>https://tedneward.github.io/Research/storage/models/graph/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/models/graph/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Graph_database&quot;&gt;Wikipedia&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&quot;A graph is a structure composed of vertices and edges. Both vertices and edges can have an arbitrary number of key/value-pairs called properties. Vertices denote discrete objects such as a person, a place, or an event. Edges denote relationships between vertices. For instance, a person may know another person, have been involved in an event, and/or have recently been at a particular place. Properties express non-relational information about the vertices and edges. Example properties include a vertex having a name and an age, and an edge having a timestamp and/or a weight.&lt;/p&gt; 
&lt;p&gt;&quot;If a user&apos;s domain is composed of a heterogeneous set of objects (vertices) that can be related to one another in a multitude of ways (edges), then a graph may be the right representation to use. In a graph, each vertex is seen as an atomic entity (not simply a &quot;row in a table&quot;) that can be linked to any other vertex or have properties added or removed at will. This empowers the data modeler to think in terms of actors within a world of complex relations as opposed to, in relational databases, statically-typed tables joined in aggregate. Once a domain is modeled, that model must then be exploited in order to yield novel, differentiating information. Graph computing has a rich history that includes not only query languages devoid of table-join semantics, but also algorithms that support complex reasoning: path analysis, vertex clustering and ranking, subgraph identification, and more. The world of applied graph computing offers a flexible, intuitive data structure along with a host of algorithms able to effectively leverage that structure.&quot; -- from &lt;a href=&quot;http://tinkerpop.apache.org/&quot;&gt;Apache TinkerPop&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;List of graph dbs to add (from TinkerPop page):&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://cn.aliyun.com/product/gdb&quot;&gt;Alibaba Graph Database&lt;/a&gt; - A real-time, reliable, cloud-native graph database service that supports property graph model.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://aws.amazon.com/neptune/&quot;&gt;Amazon Neptune&lt;/a&gt; - Fully-managed graph database service.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://s2graph.apache.org/&quot;&gt;Apache S2Graph&lt;/a&gt; - OLTP graph database running on Apache HBase.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/lambdazen/bitsy/wiki&quot;&gt;Bitsy&lt;/a&gt; - A small, fast, embeddable, durable in-memory graph database.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/blazegraph&quot;&gt;Blazegraph&lt;/a&gt; - RDF graph database with OLTP support.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/MartinHaeusler/chronos/tree/master/org.chronos.chronograph&quot;&gt;ChronoGraph&lt;/a&gt; - A versioned graph database.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.datastax.com/products/datastax-enterprise-graph&quot;&gt;DSEGraph&lt;/a&gt; - DataStax graph database with OLTP and OLAP support.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://grakn.ai/&quot;&gt;GRAKN.AI&lt;/a&gt; - Distributed OLTP/OLAP knowledge graph system.&lt;/li&gt; 
 &lt;li&gt;Hadoop (Spark) - OLAP graph processor using Spark.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/rayokota/hgraphdb&quot;&gt;HGraphDB&lt;/a&gt; - OLTP graph database running on Apache HBase.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.huaweicloud.com/en-us/product/ges.html&quot;&gt;Huawei Graph Engine Service&lt;/a&gt; - Fully-managed, distributed, at-scale graph query and analysis service that provides a visualized interactive analytics platform.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://console.ng.bluemix.net/catalog/services/ibm-graph/&quot;&gt;IBM Graph&lt;/a&gt; - OLTP graph database as a service.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/SteelBridgeLabs/neo4j-gremlin-bolt&quot;&gt;neo4j-gremlin-bolt&lt;/a&gt; - OLTP graph database (using Bolt Protocol).&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/pietermartin/sqlg&quot;&gt;Sqlg&lt;/a&gt; - OLTP implementation on SQL databases.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://stardog.com/&quot;&gt;Stardog&lt;/a&gt; - RDF graph database with OLTP and OLAP support.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://tinkerpop.apache.org/docs/current/reference/#tinkergraph-gremlin&quot;&gt;TinkerGraph&lt;/a&gt; - In-memory OLTP and OLAP reference implementation.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/rmagen/unipop&quot;&gt;Unipop&lt;/a&gt; - OLTP Elasticsearch and JDBC backed graph.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Reading&lt;/h2&gt; 
&lt;h3&gt;Books&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;http://graphdatabases.com&quot;&gt;Graph Databases&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Raw storage model</title>
      <link>https://tedneward.github.io/Research/storage/models/raw/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/models/raw/index.html</guid>
      	<description>
	&lt;p&gt;(Placeholder)&lt;/p&gt; 
&lt;p&gt;&quot;Blob&quot; storage. Amazon S3, for example--no structure at all.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Time-series storage model</title>
      <link>https://tedneward.github.io/Research/storage/models/time-series/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/models/time-series/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Time_series_database&quot;&gt;Wikipedia&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&quot;A time series database is a specialized database that efficiently stores and retrieves time-stamped data. Each time series is stored individually as an optimized list of values, enabling fast data retrieval and cost-effective storage.&quot; --&lt;a href=&quot;https://www.honeycomb.io/blog/time-series-database&quot;&gt;Honeycomb&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&quot;Time series databases are specialized databases designed to manage data that is organized and indexed by time. Unlike traditional databases, which are optimized for general-purpose data storage, TSDBs focus on efficiently storing, querying, and analyzing sequences of time-stamped data points.&quot; -- &lt;a href=&quot;https://www.datacamp.com/blog/time-series-database&quot;&gt;Datacamp&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Characteristics of Time Series Databases&lt;/em&gt;&lt;/strong&gt;: There are a few things that TSDBs do differently than traditional databases.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Optimized for time-stamped data.&lt;/strong&gt; At their core, TSDBs are built to handle data with timestamps as a fundamental attribute. Every data point in a TSDB includes a timestamp, which serves as its primary index. This allows these databases to efficiently store and retrieve time-ordered sequences and provide quick access to historical trends or recent events. Most TSDBs use time-based partitioning, meaning the data is stored in partitions based on time intervals (e.g., hourly, daily). This enables efficient pruning, where queries ignore irrelevant partitions altogether. They can also implement time buckets, grouping data into predefined time windows (e.g., 1 minute, 1 hour) for faster aggregations.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;High ingestion rates.&lt;/strong&gt; Time series data is often generated at a rapid pace—think of IoT devices sending thousands of data points per second or a server monitoring tool capturing system metrics in real time. TSDBs are optimized for these high write rates and can ingest vast amounts of data without slowing down or losing information. This is usually achieved using append-only data storage models and in-memory buffers to prevent locks or transactional bottlenecks.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Efficient queries for time ranges.&lt;/strong&gt; Analyzing time series data often involves querying specific time intervals or windows, such as “last 24 hours” or “this year compared to last year.” TSDBs are built with this in mind, offering specialized query capabilities that allow users to quickly retrieve data over defined time ranges. They also support aggregations like averages, sums, or trends to offer valuable analytics without complex query logic.&lt;/p&gt; 
&lt;p&gt;The query optimization techniques include:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Pre-aggregated data: TSDBs often pre-calculate summaries for common time intervals (e.g., hourly or daily averages). 
  &lt;ul&gt; 
   &lt;li&gt;Sliding window algorithms: These help efficiently compute metrics over moving time windows, such as rolling averages.&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;&lt;strong&gt;Data compression and retention policies.&lt;/strong&gt; To manage the vast amount of time series data generated over time, TSDBs use advanced data compression techniques. These methods reduce storage requirements while preserving query performance. TSDBs usually include retention policies so the users can define how long data should be kept. For example, a system might retain detailed data for the past month while downsampling for older data. Downsampling is the process of reducing the granularity of data over time. For example: Raw temperature readings might be recorded every 10 seconds for the most recent 7 days; or for older data, the system might downsample to hourly averages to save space while still retaining historical trends.&lt;/p&gt; 
&lt;p&gt;Examples of advanced compression techniques include:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Delta encoding: Storing the difference between consecutive values instead of the full value. 
  &lt;ul&gt; 
   &lt;li&gt;Gorilla compression: A method used to efficiently compress floating-point time series data by storing changes in binary format.&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;&lt;strong&gt;Writes dominate.&lt;/strong&gt; Our primary requirement for a TSDB is that it should always be available to take writes. As we have hundreds of systems exposing multiple data items, the write rate might easily exceed tens of millions of data points each second. In constrast, the read rate is usually a couple orders of magnitude lower as it is primarily from automated systems watching ’important’ time series, data visualization systems presenting dashboards for human consumption, or from human operators wishing to diagnose an observed problem.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;State transitions.&lt;/strong&gt; We wish to identify issues that emerge from a new software release, an unexpected side effect of a configuration change, a network cut and other issues that result in a significant state transition. Thus, we wish for our TSDB to support fine-grained aggregations over short-time windows. The ability to display state transitions within tens of seconds is particularly prized as it allows automation to quickly remediate problems before they become wide spread.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;High availability.&lt;/strong&gt; Even if a network partition or other failure leads to disconnection between different datacenters, systems operating within any given datacenter ought to be able to write data to local TSDB machines and be able to retrieve this data on demand.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Fault tolerance.&lt;/strong&gt; We wish to replicate all writes to multiple regions so we can survive the loss of any given datacenter or geographic region due to a disaster.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Lack of ACID.&lt;/strong&gt; These systems do not store any user data so traditional ACID guarantees are not a core requirement for TSDBs. However, a high percentage of writes must succeed at all times, even in the face of disasters that might render entire datacenters unreachable. Additionally, recent data points are of higher value than older points given the intuition that knowing if a particular system or service is broken right now is more valuable to an operations engineer than knowing if it was broken an hour ago.&lt;/p&gt; 
&lt;h2&gt;Databases&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/Netflix/atlas&quot;&gt;atlas&lt;/a&gt; In-memory dimensional time series database from Netflix.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;/storage/cassandra&quot;&gt;Cassandra&lt;/a&gt; Apache Cassandra is an open source NoSQL distributed database trusted by thousands of companies for scalability and high availability without compromising performance.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://clickhouse.com/&quot;&gt;ClickHouse&lt;/a&gt; An open-source, high performance columnar OLAP database management system for real-time analytics using SQL.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://crate.io/use-cases/time-series/&quot;&gt;cratedb&lt;/a&gt; The SQL database for complex, large scale time series workloads in industrial IoT.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://druid.apache.org/&quot;&gt;druid&lt;/a&gt; A high performance real-time analytics database.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://fauna.com&quot;&gt;fauna&lt;/a&gt; Fauna is a flexible, developer-friendly, transactional database delivered as a secure and scalable cloud API with native GraphQL.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;/storage/influxdb/&quot;&gt;InfluxDB&lt;/a&gt; Is the essential time series toolkit - dashboards, queries, tasks and agents all in one place.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://kairosdb.github.io/&quot;&gt;KairosDB&lt;/a&gt; Fast Time Series Database on Cassandra.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;/storage/opentsdb&quot;&gt;OpenTSDB&lt;/a&gt; The Scalable Time Series Database.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://prometheus.io/&quot;&gt;prometheus&lt;/a&gt; An open-source systems monitoring and alerting toolkit originally built at &lt;a href=&quot;https://soundcloud.com&quot;&gt;SoundCloud&lt;/a&gt;.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/questdb/questdb&quot;&gt;QuestDB&lt;/a&gt; An open source SQL database designed to process time series data, faster.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://siridb.com/&quot;&gt;SiriDB&lt;/a&gt; An highly-scalable, robust and super fast time series database.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;/storage/timescaledb&quot;&gt;TimescaleDB&lt;/a&gt; TimescaleDB is the leading open-source relational database with support for time-series data.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://tdengine.com&quot;&gt;TDengine&lt;/a&gt; An open-source time-series database with high-performance, scalability and SQL support.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/graphite-project/whisper&quot;&gt;Whisper (Graphite)&lt;/a&gt;: a file-based time-series database format for Graphite. (&lt;a href=&quot;http://graphite.readthedocs.org/&quot;&gt;Docs&lt;/a&gt;) | &lt;a href=&quot;https://graphiteapp.org/&quot;&gt;Graphite website&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Managed database services&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://aws.amazon.com/timestream/&quot;&gt;Amazon Timestream&lt;/a&gt; A fast, scalable, and serverless time series database service for IoT and operational applications.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://azure.microsoft.com/en-us/services/postgresql/#overview&quot;&gt;Azure Database for PostgreSQL&lt;/a&gt; Fully managed, intelligent, and scalable PostgreSQL with support for TimeScaleDB.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://azure.microsoft.com/en-us/services/time-series-insights/&quot;&gt;Azure time series insights&lt;/a&gt; Visualize IoT data in real time.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.influxdata.com/products/influxdb-cloud/&quot;&gt;InfluxDB Cloud&lt;/a&gt; It’s a fast, elastic, serverless real-time monitoring platform, dashboarding engine, analytics service and event and metrics processor.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.timescale.com/products/#Timescale-Cloud&quot;&gt;TimeScaleDB Cloud&lt;/a&gt; Managed TimeScaleDB service.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://cloud.tdengine.com/&quot;&gt;TDengine Cloud&lt;/a&gt; Serverless, fully managed cloud service for time series data&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Packages&lt;/h2&gt; 
&lt;h3&gt;Python&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/arundo/adtk&quot;&gt;adtk&lt;/a&gt; A Python toolkit for rule-based/unsupervised anomaly detection in time series.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/aeon-toolkit/aeon&quot;&gt;aeon&lt;/a&gt; A unified framework for machine learning with time series.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/SeldonIO/alibi-detect&quot;&gt;alibi-detect&lt;/a&gt; Algorithms for outlier, adversarial and drift detection.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/winedarksea/AutoTS&quot;&gt;AutoTS&lt;/a&gt; A time series package for Python designed for rapidly deploying high-accuracy forecasts at scale.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/AutoViML/Auto_TS&quot;&gt;Auto_TS&lt;/a&gt; Automatically build ARIMA, SARIMAX, VAR, FB Prophet and XGBoost Models on Time Series data sets with a Single Line of Code. Now updated with Dask to handle millions of rows.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/cesium-ml/cesium&quot;&gt;cesium&lt;/a&gt; Open-Source Platform for Time Series Inference.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/unit8co/darts&quot;&gt;darts&lt;/a&gt; Time Series Made Easy in Python. A python library for easy manipulation and forecasting of time series.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/deeptime-ml/deeptime&quot;&gt;deeptime&lt;/a&gt; Python library for analysis of time series data including dimensionality reduction, clustering, and Markov model estimation.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/DynamicTimeWarping/dtw-python&quot;&gt;dtw-python&lt;/a&gt; Python port of R&apos;s Comprehensive Dynamic Time Warp algorithm package.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/tinkoff-ai/etna&quot;&gt;etna&lt;/a&gt; ETNA is an easy-to-use time series forecasting framework.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/microsoft/FOST&quot;&gt;fost&lt;/a&gt; Forecasting open source tool aims to provide an easy-use tool for spatial-temporal forecasting.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/descendant-ai/functime&quot;&gt;functime&lt;/a&gt; Time-series machine learning and embeddings at scale.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/awslabs/gluon-ts&quot;&gt;gluon-ts&lt;/a&gt; Probabilistic time series modeling in Python from AWS.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/equinor/gordo&quot;&gt;gordo&lt;/a&gt; Building thousands of models with time series data to monitor systems.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/linkedin/greykite&quot;&gt;greykite&lt;/a&gt; A flexible, intuitive and fast forecasting library from LinkedIn.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/hmmlearn/hmmlearn&quot;&gt;hmmlearn&lt;/a&gt; Hidden Markov Models in Python, with &lt;code&gt;scikit-learn&lt;/code&gt; like API.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/DataCanvasIO/HyperTS&quot;&gt;HyperTS&lt;/a&gt; A Full-Pipeline Automated Time Series (AutoTS) Analysis Toolkit.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/facebookresearch/kats&quot;&gt;kats&lt;/a&gt; A kit to analyze time series data, a lightweight, easy-to-use, generalizable, and extendable framework to perform time series analysis, from understanding the key statistics and characteristics, detecting change points and anomalies, to forecasting future trends.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/cvjena/libmaxdiv&quot;&gt;libmaxdiv&lt;/a&gt; Implementation of the Maximally Divergent Intervals algorithm for Anomaly Detection in multivariate spatio-temporal time-series.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/CamDavidsonPilon/lifelines&quot;&gt;lifelines&lt;/a&gt; Survival analysis in Python.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/zillow/luminaire&quot;&gt;luminaire&lt;/a&gt; A python package that provides ML driven solutions for monitoring time series data. Luminaire provides several anomaly detection and forecasting capabilities that incorporate correlational and seasonal patterns in the data over time as well as uncontrollable variations.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/matrix-profile-foundation/mass-ts&quot;&gt;mass-ts&lt;/a&gt; Mueen&apos;s Algorithm for Similarity Search, a library used for searching time series sub- sequences under z-normalized Euclidean distance for similarity.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/matrix-profile-foundation/matrixprofile&quot;&gt;matrixprofile&lt;/a&gt; A Python library making time series data mining tasks, utilizing matrix profile algorithms, accessible to everyone.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/salesforce/Merlion&quot;&gt;Merlion&lt;/a&gt; A Python library for time series intelligence. It provides an end-to-end machine learning framework that includes loading and transforming data, building and training models, post-processing model outputs, and evaluating model performance.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/Nixtla/neuralforecast&quot;&gt;neuralforecast&lt;/a&gt; Scalable and user friendly neural brain forecasting algorithms.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/Nixtla/nixtla&quot;&gt;nixtla&lt;/a&gt; Automated time series processing and forecasting.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/uber/orbit&quot;&gt;orbit&lt;/a&gt; A package for Bayesian forecasting with object-oriented design and probabilistic models under the hood from Uber.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/pastas/pastas&quot;&gt;pastas&lt;/a&gt; An open-source Python framework for the analysis of hydrological time series.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/alkaline-ml/pmdarima&quot;&gt;pmdarima&lt;/a&gt; A statistical library designed to fill the void in Python&apos;s time series analysis capabilities, including the equivalent of R&apos;s &lt;code&gt;auto.arima&lt;/code&gt; function.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/facebook/prophet&quot;&gt;prophet&lt;/a&gt; Tool for producing high quality forecasts for time series data that has multiple seasonality with linear or non-linear growth.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/antoinecarme/pyaf&quot;&gt;pyaf&lt;/a&gt; PyAF is an Open Source Python library for Automatic Time Series Forecasting built on top of popular pydata modules.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/wwrechard/pydlm&quot;&gt;PyDLM&lt;/a&gt; Bayesian time series modeling package. Based on the Bayesian dynamic linear model (Harrison and West, 1999) and optimized for fast model fitting and inference.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/RJT1990/pyflux&quot;&gt;PyFlux&lt;/a&gt; Open source time series library for Python.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/PYFTS/pyFTS&quot;&gt;pyFTS&lt;/a&gt; An open source library for Fuzzy Time Series in Python.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/yzhao062/Pyod&quot;&gt;Pyod&lt;/a&gt; A Python toolbox for scalable outlier detection (Anomaly Detection).&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/WenjieDu/PyPOTS&quot;&gt;PyPOTS&lt;/a&gt; A python toolbox/library for data mining on partially-observed time series (A.K.A. irregularly-sampled time series), supporting tasks of forecasting/imputation/classification/clustering on incomplete multivariate time series with missing values.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/olivercliff/pyspi&quot;&gt;pyspi&lt;/a&gt; Comparative analysis of pairwise interactions in multivariate time series.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/business-science/pytimetk&quot;&gt;pytimetk&lt;/a&gt; The time series toolkit for python.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/kLabUM/rrcf&quot;&gt;rrcf&lt;/a&gt; Implementation of the Robust Random Cut Forest algorithm for anomaly detection on streams.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/mikekeith52/scalecast&quot;&gt;scalecast&lt;/a&gt; A scalable forecasting approach for Timeseries in Python&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/carlomazzaferro/scikit-hts&quot;&gt;scikit-hts&lt;/a&gt; Hierarchical Time Series Forecasting with a familiar API.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/dmbee/seglearn&quot;&gt;seglearn&lt;/a&gt; A python package for machine learning time series or sequences.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://gitlab.com/shyft-os/shyft&quot;&gt;shyft&lt;/a&gt; Time-series for python and c++, including distributed storage and calculations Hydrologic Forecasting Toolbox, high-performance flexible stacks, including calibration Energy-market models and micro services.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/cjekel/similarity_measures&quot;&gt;similarity_measures&lt;/a&gt; Quantify the difference between two arbitrary curves.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/JoaquinAmatRodrigo/skforecast&quot;&gt;skforecast&lt;/a&gt; Time series forecasting with scikit-learn models.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/alan-turing-institute/sktime&quot;&gt;sktime&lt;/a&gt; A &lt;code&gt;scikit-learn&lt;/code&gt; compatible Python toolbox for learning with time series.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/Nixtla/statsforecast&quot;&gt;statsforecast&lt;/a&gt; Lightning :zap: fast forecasting with statistical and econometric models.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.statsmodels.org/stable/tsa.html&quot;&gt;statsmodels.tsa&lt;/a&gt; Time Series Analysis (tsa) &lt;code&gt;statsmodels.tsa&lt;/code&gt; contains model classes and functions that are useful for time series analysis.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/TDAmeritrade/stumpy&quot;&gt;stumpy&lt;/a&gt; A powerful and scalable Python library that can be used for a variety of time series data mining tasks.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/davidhallac/TICC&quot;&gt;TICC&lt;/a&gt; A python solver for efficiently segmenting and clustering a multivariate time series.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/X-DataInitiative/tick&quot;&gt;tick&lt;/a&gt; Module for statistical learning, with a particular emphasis on time-dependent modelling.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/AzulGarza/timecopilot&quot;&gt;TimeCopilot&lt;/a&gt; An open-source forecasting agent that combines the power of large language models with state-of-the-art time series foundation models.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/microprediction/timemachines&quot;&gt;timemachines&lt;/a&gt; Continuously evaluated, functional, incremental, time-series forecasting.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/MBrouns/timeseers&quot;&gt;TimeSeers&lt;/a&gt; A hierarchical Bayesian Time Series model based on Prophet, written in PyMC3.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/google-research/timesfm&quot;&gt;TimesFM&lt;/a&gt; TimesFM (Time Series Foundation Model) is a pretrained time-series foundation model developed by Google Research for time-series forecasting.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://pypi.org/project/time-series-generator/&quot;&gt;Time Series Generator&lt;/a&gt; Provides a solution for the direct multi-step outputs limitation in Keras.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/datamllab/tods&quot;&gt;tods&lt;/a&gt; An Automated Time-series Outlier Detection System.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/philipdarke/torchtime&quot;&gt;torchtime&lt;/a&gt; Time series data sets for PyTorch.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/WenjieDu/TSDB&quot;&gt;TSDB&lt;/a&gt; Time-Series DataBase: A Python toolbox helping load time-series datasets easily.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/timeseriesAI/tsai&quot;&gt;tsai&lt;/a&gt; State-of-the-art Deep Learning library for Time Series and Sequences.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/WenjieZ/TSCV&quot;&gt;tscv&lt;/a&gt; Time Series Cross-Validation - an extension for scikit-learn.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/predict-idlab/tsflex&quot;&gt;tsflex&lt;/a&gt; Flexible time series feature extraction &amp;amp; processing.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/tslearn-team/tslearn&quot;&gt;tslearn&lt;/a&gt; The machine learning toolkit for time series analysis in Python.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/hsbc/tslumen&quot;&gt;tslumen&lt;/a&gt; A library for Time Series Exploratory Data Analysis (EDA).&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/cerlymarco/tsmoothie&quot;&gt;tsmoothie&lt;/a&gt; A python library for time-series smoothing and outlier detection in a vectorized way.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Date and Time&lt;/h4&gt; 
&lt;p&gt;&lt;em&gt;Libraries for working with dates and times.&lt;/em&gt;&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/sffjunkie/astral&quot;&gt;astral&lt;/a&gt; Python calculations for the position of the sun and moon.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/arrow-py/arrow&quot;&gt;Arrow&lt;/a&gt; - A Python library that offers a sensible and human-friendly approach to creating, manipulating, formatting and converting dates, times and timestamps.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/KoffeinFlummi/Chronyk&quot;&gt;Chronyk&lt;/a&gt; - A Python 3 library for parsing human-written times and dates.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/dateutil/dateutil&quot;&gt;dateutil&lt;/a&gt; - Extensions to the standard Python &lt;a href=&quot;https://docs.python.org/3/library/datetime.html&quot;&gt;datetime&lt;/a&gt; module.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/myusuf3/delorean/&quot;&gt;delorean&lt;/a&gt; - A library for clearing up the inconvenient truths that arise dealing with datetimes.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/timofurrer/maya&quot;&gt;maya&lt;/a&gt; - Datetimes for Humans.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/zachwill/moment&quot;&gt;moment&lt;/a&gt; - A Python library for dealing with dates/times. Inspired by &lt;a href=&quot;http://momentjs.com/&quot;&gt;Moment.js&lt;/a&gt;.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/sdispater/pendulum&quot;&gt;Pendulum&lt;/a&gt; - Python datetimes made easy.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/shinux/PyTime&quot;&gt;PyTime&lt;/a&gt; - An easy-to-use Python module which aims to operate date/time/datetime by string.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://launchpad.net/pytz&quot;&gt;pytz&lt;/a&gt; - World timezone definitions, modern and historical. Brings the &lt;a href=&quot;https://en.wikipedia.org/wiki/Tz_database&quot;&gt;tz database&lt;/a&gt; into Python.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/dirn/When.py&quot;&gt;when.py&lt;/a&gt; - Providing user-friendly functions to help perform common date and time actions.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Feature Engineering&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/raphaelvallat/antropy&quot;&gt;AntroPy&lt;/a&gt; Time-efficient algorithms for computing the entropy and complexity of time-series.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/chlubba/catch22&quot;&gt;catch22&lt;/a&gt; CAnonical Time-series CHaracteristics, 22 high-performing time-series features in C, Python and Julia.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/alteryx/featuretools&quot;&gt;featuretools&lt;/a&gt; An open source python library for automated feature engineering.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/google/temporian&quot;&gt;temporian&lt;/a&gt; Temporian is an open-source Python library for preprocessing ⚡ and feature engineering 🛠 temporal data 📈 for machine learning applications 🤖&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/Nixtla/tsfeatures&quot;&gt;tsfeatures&lt;/a&gt; Calculates various features from time series data. Python implementation of the R package tsfeatures.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/fraunhoferportugal/tsfel&quot;&gt;tsfel&lt;/a&gt; An intuitive library to extract features from time series.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/predict-idlab/tsflex&quot;&gt;tsflex&lt;/a&gt; Flexible &amp;amp; efficient time series feature extraction &amp;amp; processing package.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/blue-yonder/tsfresh&quot;&gt;tsfresh&lt;/a&gt; The package contains many feature extraction methods and a robust feature selection algorithm.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Time Series Segmentation &amp;amp; Change Point Detection&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/hildensia/bayesian_changepoint_detection&quot;&gt;bayesian_changepoint_detection&lt;/a&gt; Methods to get the probability of a change point in a time series. Both online and offline methods are available.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/ruipgil/changepy&quot;&gt;changepy&lt;/a&gt; Change point detection in time series in pure python.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/zhaokg/Rbeast&quot;&gt;RBEAST&lt;/a&gt; Bayesian Change-Point Detection and Time Series Decomposition.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/deepcharles/ruptures&quot;&gt;ruptures&lt;/a&gt; A Python library for off-line change point detection. This package provides methods for the analysis and segmentation of non-stationary signals.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/alan-turing-institute/TCPDBench&quot;&gt;TCPDBench&lt;/a&gt; Turing Change Point Detection Benchmark, a benchmark evaluation of change point detection algorithms.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Time Series Generation and Augmentation&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/sdv-dev/DeepEcho&quot;&gt;DeepEcho&lt;/a&gt; Synthetic Data Generation for mixed-type, multivariate time series.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/firmai/deltapy&quot;&gt;deltapy&lt;/a&gt; Tabular Data Augmentation &amp;amp; Feature Engineering.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/uchidalab/time_series_augmentation&quot;&gt;time_series_augmentation&lt;/a&gt; An example of time series augmentation methods with Keras.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/TimeSynth/TimeSynth&quot;&gt;TimeSynth&lt;/a&gt; A multipurpose library for synthetic time series in Python.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/arundo/tsaug&quot;&gt;tsaug&lt;/a&gt; A Python package for time series augmentation.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/alexandervnikitin/tsgm&quot;&gt;tsgm&lt;/a&gt; Synthetic time series generation and time series augmentations.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Visualization&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/altair-viz/altair&quot;&gt;atlair&lt;/a&gt; Declarative statistical visualization library for Python.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/matplotlib/matplotlib&quot;&gt;matplotlib&lt;/a&gt; A comprehensive library for creating static, animated, and interactive visualizations in Python.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/plotly/plotly.py&quot;&gt;plotly&lt;/a&gt; A graphing library makes interactive, publication-quality graphs.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/predict-idlab/plotly-resampler&quot;&gt;plotly-resampler&lt;/a&gt; Wrapper for Plotly figures, making large sequential plots scalable.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/mwaskom/seaborn&quot;&gt;seaborn&lt;/a&gt; A data visualization library based on &lt;a href=&quot;https://matplotlib.org&quot;&gt;matplotlib&lt;/a&gt; that provides a high-level interface for drawing attractive and informative statistical graphics.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/predict-idlab/tsdownsample&quot;&gt;tsdownsample&lt;/a&gt; Extremely fast time series downsampling for visualisation.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Benchmarking &amp;amp; Contests&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/microprediction/timeseries-elo-ratings&quot;&gt;timeseries-elo-ratings&lt;/a&gt; computes &lt;a href=&quot;https://microprediction.github.io/timeseries-elo-ratings/html_leaderboards/overall.html&quot;&gt;Elo ratings&lt;/a&gt;.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/microprediction/m6&quot;&gt;m6&lt;/a&gt; Provides utilities for the &lt;a href=&quot;https://mofc.unic.ac.cy/the-m6-competition/&quot;&gt;M6-Competition&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;Microprediction time-series &lt;a href=&quot;https://www.microprediction.com/competitions&quot;&gt;competitions&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/waico/SKAB&quot;&gt;SKAB&lt;/a&gt; Skoltech Anomaly Benchmark. Time-series data for evaluating Anomaly Detection algorithms.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;R&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://cran.r-project.org/package=bcp&quot;&gt;bcp&lt;/a&gt; Bayesian Analysis of Change Point Problems.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://google.github.io/CausalImpact/CausalImpact.html&quot;&gt;CausalImpact&lt;/a&gt; An R package for causal inference using Bayesian structural time-series models.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/rkillick/changepoint&quot;&gt;changepoint&lt;/a&gt; Implements various mainstream and specialised changepoint methods for finding single and multiple changepoints within data.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://cran.r-project.org/package=cpm&quot;&gt;cpm&lt;/a&gt; Sequential and Batch Change Detection Using Parametric and Nonparametric Methods.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/rkillick/EnvCpt&quot;&gt;EnvCpt&lt;/a&gt; Detection of Structural Changes in Climate and Environment Time Series.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/tidyverts/fable&quot;&gt;fable&lt;/a&gt; A &lt;a href=&quot;https://github.com/tidyverts&quot;&gt;tidyverts&lt;/a&gt; package for tidy time series forecasting.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/tidyverts/fasster&quot;&gt;fasster&lt;/a&gt; A &lt;a href=&quot;https://github.com/tidyverts&quot;&gt;tidyverts&lt;/a&gt; package for forecasting with additive switching of seasonality, trend and exogenous regressors.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/tidyverts/feasts&quot;&gt;feasts&lt;/a&gt; A &lt;a href=&quot;https://github.com/tidyverts&quot;&gt;tidyverts&lt;/a&gt; package for feature extraction and statistics for time series.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://cran.r-project.org/package=fpop&quot;&gt;fpop&lt;/a&gt; Segmentation using Optimal Partitioning and Function Pruning.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/config-i1/greybox&quot;&gt;greybox&lt;/a&gt; Regression model building and forecasting in R.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/business-science/modeltime&quot;&gt;modeltime&lt;/a&gt; Modeltime unlocks time series forecast models and machine learning in one framework.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/tdhock/penaltyLearning&quot;&gt;penaltyLearning&lt;/a&gt; Algorithms for supervised learning of penalty functions for change detection.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/hendersontrent/Rcatch22&quot;&gt;Rcatch22&lt;/a&gt; R package for calculation of 22 CAnonical Time-series CHaracteristics.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/config-i1/smooth&quot;&gt;smooth&lt;/a&gt; The set of smoothing functions used for time series analysis and in forecasting.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/hendersontrent/theft&quot;&gt;theft&lt;/a&gt; R package for Tools for Handling Extraction of Features from Time series.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/business-science/timetk&quot;&gt;timetk&lt;/a&gt; A &lt;code&gt;tidyverse&lt;/code&gt; toolkit to visualize, wrangle, and transform time series data.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/tidyverts/tsibble&quot;&gt;tsibble&lt;/a&gt; A &lt;a href=&quot;https://github.com/tidyverts&quot;&gt;tidyverts&lt;/a&gt; package with tidy temporal data frames and tools.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/PetoLau/TSrepr&quot;&gt;tsrepr&lt;/a&gt; TSrepr: R package for time series representations.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Java&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/patrickzib/SFA&quot;&gt;SFA&lt;/a&gt; Scalable Time Series Data Analytics.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/uea-machine-learning/tsml&quot;&gt;tsml&lt;/a&gt; Java time series machine learning tools in a Weka compatible toolkit.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;JavaScript&lt;/h3&gt; 
&lt;h4&gt;Visualization&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/square/cubism&quot;&gt;cubism&lt;/a&gt; A &lt;a href=&quot;http://d3js.org&quot;&gt;D3&lt;/a&gt; plugin for visualizing time series. Use Cubism to construct better realtime dashboards, pulling data from &lt;a href=&quot;https://github.com/square/cubism/wiki/Graphite&quot;&gt;Graphite&lt;/a&gt;, &lt;a href=&quot;https://github.com/square/cubism/wiki/Cube&quot;&gt;Cube&lt;/a&gt; and other sources.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/apache/echarts&quot;&gt;echarts&lt;/a&gt; A free, powerful charting and visualization library offering an easy way of adding intuitive, interactive, and highly customizable charts to your commercial products.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.fusioncharts.com/fusiontime&quot;&gt;fusiontime&lt;/a&gt; Helps you visualize time-series and stock data in JavaScript, with just a few lines of code.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/highcharts/highcharts&quot;&gt;highcharts&lt;/a&gt; A JavaScript charting library based on SVG, with fallbacks to VML and canvas for old browsers.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/awslabs/synchro-charts&quot;&gt;synchro-charts&lt;/a&gt; A front-end component library that provides a collection of components to visualize time-series data.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Spark&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/twosigma/flint&quot;&gt;flint&lt;/a&gt; A Time Series Library for Apache Spark.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;MATLAB&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/benfulcher/hctsa&quot;&gt;hctsa&lt;/a&gt; Highly comparative time-series analysis.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Annotation and Labeling&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/alan-turing-institute/AnnotateChange&quot;&gt;AnnotateChange&lt;/a&gt; - A simple flask application to collect annotations for the Turing Change Point Dataset, a benchmark dataset for change point detection algorithms.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/baidu/Curve&quot;&gt;Curve&lt;/a&gt; - An open-source tool to help label anomalies on time-series data&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/Microsoft/TagAnomaly&quot;&gt;TagAnomaly&lt;/a&gt; - Anomaly detection analysis and labeling tool, specifically for multiple time series (one time series per category)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/CrowdCurio/time-series-annotator&quot;&gt;time-series-annotator&lt;/a&gt; - Time Series Annotation Library implements classification tasks for time series.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/avenix/WDK&quot;&gt;WDK&lt;/a&gt; - The Wearables Development Toolkit (WDK) is a set of tools to facilitate the development of activity recognition applications with wearable devices.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Reading&lt;/h2&gt; 
&lt;h3&gt;Blogs&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://medium.com/pinterest-engineering/goku-building-a-scalable-and-high-performant-time-series-database-system-a8ff5758a181&quot;&gt;Goku: Building a Scalable and High-Performant Time Series Database System (Pinterest)&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Papers&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://arxiv.org/abs/2412.20512&quot;&gt;&lt;strong&gt;Dive into Time-Series Anomaly Detection: A Decade Review&lt;/strong&gt;&lt;/a&gt;, &lt;em&gt;Paul Boniol, Qinghua Liu, Mingyi Huang, Themis Palpanas, John Paparrizos&lt;/em&gt;, 2024&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;(https://arxiv.org/abs/2106.10466)&quot;&gt;&lt;strong&gt;TS2Vec: Towards Universal Representation of Time Series&lt;/strong&gt;&lt;/a&gt;, &lt;em&gt;Zhihan Yue, Yujing Wang, Juanyong Duan, Tianmeng Yang, Congrui Huang, Yunhai Tong, Bixiong Xu&lt;/em&gt;, 2022 - &lt;a href=&quot;https://github.com/yuezhihan/ts2vec&quot;&gt;code&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://proceedings.mlr.press/v139/xu21h&quot;&gt;&lt;strong&gt;Conformal prediction interval for dynamic time-series&lt;/strong&gt;&lt;/a&gt;, &lt;em&gt;Chen Xu, Yao Xie&lt;/em&gt;, International Conference on Machine Learning 2021 (long presentation) - &lt;a href=&quot;https://github.com/hamrel-cxu/EnbPI&quot;&gt;code&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://arxiv.org/abs/1809.04356v3&quot;&gt;&lt;strong&gt;Deep learning for time series classification: a review&lt;/strong&gt;&lt;/a&gt;, &lt;em&gt;H. I. Fawaz, G. Forestier, J. Weber, L. Idoumghar, P-A. Muller&lt;/em&gt;, Data Mining and Knowledge Discovery 2019 - &lt;a href=&quot;https://github.com/hfawaz/dl-4-tsc&quot;&gt;code&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://stanford.edu/~boyd/papers/ggs.html&quot;&gt;&lt;strong&gt;Greedy Gaussian Segmentation of Multivariate Time Series&lt;/strong&gt;&lt;/a&gt;, &lt;em&gt;D. Hallac, P. Nystrup, and S. Boyd&lt;/em&gt;, Advances in Data Analysis and Classification, 13(3), 727–751, 2019. - &lt;a href=&quot;https://github.com/cvxgrp/GGS&quot;&gt;code&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://arxiv.org/abs/1910.11162&quot;&gt;&lt;strong&gt;U-Time: A Fully Convolutional Network for Time Series Segmentation Applied to Sleep Staging&lt;/strong&gt;&lt;/a&gt;, &lt;em&gt;Mathias Perslev, Michael Jensen, Sune Darkner, Poul Jørgen Jennum, Christian Igel&lt;/em&gt;, &lt;em&gt;NeurIPS&lt;/em&gt;, 2019. - &lt;a href=&quot;https://github.com/perslev/U-Time&quot;&gt;code&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://arxiv.org/abs/cs/0605103&quot;&gt;&lt;strong&gt;A Better Alternative to Piecewise Linear Time Series Segmentation&lt;/strong&gt;&lt;/a&gt;, &lt;em&gt;Daniel Lemire&lt;/em&gt;, SIAM Data Mining, 2007. - &lt;a href=&quot;https://github.com/lemire/PiecewiseLinearTimeSeriesApproximation&quot;&gt;code&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://papers.nips.cc/paper/2019/file/c9efe5f26cd17ba6216bbe2a7d26d490-Paper.pdf&quot;&gt;&lt;strong&gt;Time-series Generative Adversarial Networks&lt;/strong&gt;&lt;/a&gt;, &lt;em&gt;Jinsung Yoon, Daniel Jarrett, Mihaela van der Schaar&lt;/em&gt;, NeurIPS, 2019. - &lt;a href=&quot;https://github.com/jsyoon0823/TimeGAN&quot;&gt;code&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://arxiv.org/abs/1511.03677&quot;&gt;&lt;strong&gt;Learning to Diagnose with LSTM Recurrent Neural Networks&lt;/strong&gt;&lt;/a&gt;, &lt;em&gt;Zachary C. Lipton, David C. Kale, Charles Elkan, Randall Wetzel&lt;/em&gt;, arXiv:1511.03677, 2015. - &lt;a href=&quot;https://github.com/aqibsaeed/Multilabel-timeseries-classification-with-LSTM&quot;&gt;code&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://openreview.net/forum?id=gjNcH0hj0LM&quot;&gt;&lt;strong&gt;Coherence-based Label Propagation over Time Series for Accelerated Active Learning&lt;/strong&gt;&lt;/a&gt;, &lt;em&gt;Yooju Shin, Susik Yoon, Sundong Kim, Hwanjun Song, Jae-Gil Lee, Byung Suk Lee&lt;/em&gt;, ICLR, 2022. - &lt;a href=&quot;https://github.com/kaist-dmlab/TCLP&quot;&gt;code&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.vldb.org/pvldb/vol8/p1816-teller.pdf&quot;&gt;Facebook Gorilla&lt;/a&gt;: &quot;Large-scale internet services aim to remain highly-available and responsive for their users even in the presence of unexpected failures. As these services have grown to support a global audience, they have scaled beyond a few systems running on hundreds of machines to thousands of individual systems running on many thousands of machines, often across multiple geo-replicated datacenters. An important requirement to operating these large scale services is to accurately monitor the health and performance of the underlying system and quickly identify and diagnose problems as they arise. Facebook uses a time series database (TSDB) to store system measuring data points and provides quick query functionalities on top. We next specify some of the constraints that we need to satisy for monitoring and operating Facebook and then describe Gorilla, our new inmemory TSDB that can store tens of millions of datapoints (e.g., CPU load, error rate, latency etc.) every second and respond queries over this data within milliseconds.&quot;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://dl.acm.org/doi/abs/10.14778/3705829.3705862&quot;&gt;Goku: A Schemaless Time Series Database for Large Scale Monitoring at Pinterest&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Books&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.cambridge.org/pl/academic/subjects/computer-science/pattern-recognition-and-machine-learning/bayesian-time-series-models?format=HB&quot;&gt;Bayesian Time Series Models&lt;/a&gt; 💲 &lt;em&gt;David Barber, A. Taylan Cemgil, Silvia Chiappa&lt;/em&gt;, Cambridge Academic Press 2011&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.knime.com/codeless-time-series-analysis-with-knime&quot;&gt;Codeless Time Series Analysis with KNIME&lt;/a&gt; 💲 &lt;em&gt;Corey Weisinger, Maarit Widmann, and Daniele Tonini&lt;/em&gt;, Packt Publishing 2022&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://otexts.com/fpp3/&quot;&gt;Forecasting principles and practice (3rd ed)&lt;/a&gt; 🆓 &lt;em&gt;Rob J Hyndman and George Athanasopoulos&lt;/em&gt; 2021&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.packtpub.com/product/practical-time-series-analysis/9781788290227&quot;&gt;Practical Time Series Analysis&lt;/a&gt; 💲 &lt;em&gt;Avishek Pal, PKS Prakash&lt;/em&gt;, Packt 2017&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/PacktPublishing/Practical-Time-Series-Analysis&quot;&gt;repo with code&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.oreilly.com/library/view/practical-time-series/9781492041641/&quot;&gt;Practical Time Series Analysis: Prediction with Statistics and Machine Learning&lt;/a&gt; 💲 &lt;em&gt;Aileen Nielsen&lt;/em&gt;, O’Reilly 2019 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/AileenNielsen/TimeSeriesAnalysisWithPython&quot;&gt;repo with code&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.packtpub.com/product/machine-learning-for-time-series-with-python/9781801819626&quot;&gt;Machine Learning for Time-Series with Python&lt;/a&gt; 💲 &lt;em&gt;Ben Auffarth&lt;/em&gt;, Packt Publishing 2021&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/PacktPublishing/Machine-Learning-for-Time-Series-with-Python&quot;&gt;repo with code&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://phdinds-aim.github.io/time_series_handbook/Preface/Preface.html&quot;&gt;Time Series Analysis Handbook&lt;/a&gt; 🆓 &lt;em&gt;Students of PhD in Data Science Batch 2023 at the Asian Institute of Management&lt;/em&gt;.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://amzn.to/3GITSpD&quot;&gt;Visualization of Time-Oriented Data&lt;/a&gt; 💲 &lt;em&gt;Wolfgang Aigner, Silvia Miksch, Heidrun Schumann, Christian Tominski&lt;/em&gt;, Springer-Verlag 2011&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Courses&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://courses.analyticsvidhya.com/courses/creating-time-series-forecast-using-python&quot;&gt;Analytics Vidhya - Time Series Forecasting using Python&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.coursera.org/projects/intro-time-series-analysis-in-r&quot;&gt;Coursera - Intro to Time Series Analysis in R&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.coursera.org/learn/tensorflow-sequences-time-series-and-prediction&quot;&gt;Coursera - Sequences, Time Series and Prediction&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.coursera.org/learn/practical-time-series-analysis&quot;&gt;Coursera - Practical Time Series Analysis&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://data4sci.com/timeseries&quot;&gt;Data For Science - Time Series for Everyone&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.kaggle.com/learn/time-series&quot;&gt;Kaggle - Time Series&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.udacity.com/course/time-series-forecasting--ud980&quot;&gt;Udacity - Time Series Forecasting&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Tutorials&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.pymc.io/projects/examples/en/latest/time_series/Forecasting_with_structural_timeseries.html&quot;&gt;Forecasting with Structural AR Timeseries | PyMC&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://scikit-learn.org/stable/auto_examples/applications/plot_cyclical_feature_engineering.html&quot;&gt;Time-related feature engineering - scikit learn&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Repos with Models&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/damitkwr/ESRNN-GPU&quot;&gt;ESRNN-GPU&lt;/a&gt; PyTorch GPU implementation of the ES-RNN model for time series forecasting.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/jaungiers/LSTM-Neural-Network-for-Time-Series-Prediction&quot;&gt;LSTM-Neural-Network-for-Time-Series-Prediction&lt;/a&gt; LSTM built using Keras Python package to predict time series steps and sequences.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/angus924/rocket&quot;&gt;ROCKET&lt;/a&gt; Exceptionally fast and accurate time series classification using random convolutional kernels.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/hzy46/TensorFlow-Time-Series-Examples&quot;&gt;TensorFlow-Time-Series-Examples&lt;/a&gt; Time Series Prediction with &lt;code&gt;tf.contrib.timeseries&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/zhykoties/TimeSeries&quot;&gt;TimeSeries&lt;/a&gt; Implementation of deep learning models for time series in PyTorch.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/cauchyturing/UCR_Time_Series_Classification_Deep_Learning_Baseline&quot;&gt;UCR_Time_Series_Classification_Deep_Learning_Baseline&lt;/a&gt; Fully Convlutional Neural Networks for state-of-the-art time series classification.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/ragulpr/wtte-rnn&quot;&gt;wtte-rnn&lt;/a&gt; WTTE-RNN a framework for churn and time to event prediction.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Applications&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/binjr/binjr&quot;&gt;binjr&lt;/a&gt; A Time Series Data Browser.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.comp-engine.org/&quot;&gt;CompEngine&lt;/a&gt; A self-organizing database of time-series data, that allows you to upload time-series data and interactively visualize similar data that have been measured by others.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Awesome lists&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/lmmentel/awesome-time-series&quot;&gt;https://github.com/lmmentel/awesome-time-series&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/cuge1995/awesome-time-series&quot;&gt;https://github.com/cuge1995/awesome-time-series&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/MaxBenChrist/awesome_time_series_in_python&quot;&gt;https://github.com/MaxBenChrist/awesome_time_series_in_python&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/vinta/awesome-python&quot;&gt;https://github.com/vinta/awesome-python&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/xephonhq/awesome-time-series-database&quot;&gt;https://github.com/xephonhq/awesome-time-series-database&lt;/a&gt; - A curated list of awesome time series databases, benchmarks and papers.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/microprediction/awesome-python-benchmarks&quot;&gt;https://github.com/microprediction/awesome-python-benchmarks&lt;/a&gt; - Timeseries benchmarking mostly.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/Alro10/deep-learning-time-series&quot;&gt;https://github.com/Alro10/deep-learning-time-series&lt;/a&gt; - List of state of the art papers focus on deep learning and resources, code and experiments using deep learning for time series forecasting.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/benfulcher/hctsa/wiki/Related-time-series-resources&quot;&gt;https://github.com/benfulcher/hctsa/wiki/Related-time-series-resources&lt;/a&gt; - A collection of good resources for time-series analysis (including in other programming languages like python and R).&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>MySQL</title>
      <link>https://tedneward.github.io/Research/storage/mysql/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/mysql/index.html</guid>
      	<description>
	&lt;h2&gt;Books&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://dev.mysql.com/doc/mysql-tutorial-excerpt/8.0/en/tutorial.html&quot;&gt;MySQL 8.0 Tutorial Excerpt&lt;/a&gt; (HTML) &lt;a href=&quot;https://downloads.mysql.com/docs/mysql-tutorial-excerpt-8.0-en.pdf&quot;&gt;(PDF)&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://goalkicker.com/MySQLBook/&quot;&gt;MySQL Notes for Professionals&lt;/a&gt; - Compiled from StackOverflow Documentation (PDF)&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Neo4J</title>
      <link>https://tedneward.github.io/Research/storage/neo4j/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/neo4j/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://neo4j.com/&quot;&gt;Website&lt;/a&gt; | Closed-source&lt;/p&gt; 
&lt;p&gt;Comes in local/desktop version (free) and cloud-hosted versions.&lt;/p&gt; 
&lt;p&gt;Uses &lt;a href=&quot;/languages/cypher&quot;&gt;Cypher&lt;/a&gt; query language for ad-hoc query of the nodes and arcs.&lt;/p&gt; 
&lt;h2&gt;Books&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://neo4j.com/fullstack-graphql-applications-with-grandstack/&quot;&gt;Fullstack GraphQL Applications with GRANDStack – Essential Excerpts&lt;/a&gt; - William Lyon (PDF) &lt;em&gt;(email requested)&lt;/em&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://neo4j.com/graph-algorithms-book/&quot;&gt;Graph Algorithms: Practical Examples in Apache Spark and Neo4j&lt;/a&gt; - Mark Needham and Amy E. Hodler (PDF, EPUB, MOBI) &lt;em&gt;(email requested)&lt;/em&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://neo4j.com/books/graph-databases/&quot;&gt;Graph Databases 2nd edition&lt;/a&gt; - Ian Robinson, Jim Webber and Emil Eifrém (PDF, EPUB, MOBI) &lt;em&gt;(email requested)&lt;/em&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://neo4j.com/graph-databases-for-dummies/&quot;&gt;Graph Databases For Dummies&lt;/a&gt; - Dr. Jim Webber and Rik Van Bruggen (PDF) &lt;em&gt;(email requested)&lt;/em&gt;&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Nocobase</title>
      <link>https://tedneward.github.io/Research/storage/nocobase/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/nocobase/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.nocobase.com/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/nocobase/nocobase&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>NuoDB</title>
      <link>https://tedneward.github.io/Research/storage/nuodb/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/nuodb/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://nuodb.com/&quot;&gt;Website&lt;/a&gt; | Looks commercial?&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Document storage model</title>
      <link>https://tedneward.github.io/Research/storage/models/document/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/models/document/index.html</guid>
      	<description>
	&lt;p&gt;Structure is conceptually &quot;star&quot;-like, with minimal (or no) relationships outside of the document recognized by the storage system. (Developers can, and usually will, store unique data elements across documents as a way of putting structure in at the application level, but this is typically unrecognized by the storage system itself.)&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Hierarchical storage model</title>
      <link>https://tedneward.github.io/Research/storage/models/hierarchical/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/models/hierarchical/index.html</guid>
      	<description>
	&lt;p&gt;(Placeholder)&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Relational storage model</title>
      <link>https://tedneward.github.io/Research/storage/models/relational/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/models/relational/index.html</guid>
      	<description>
	&lt;p&gt;Built, more or less, on the Codd model of relationships between tuples of data.&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;./codd.pdf&quot;&gt;Codd&apos;s original paper&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Codd&apos;s Twelve (Thirteen) Rules:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;&lt;em&gt;Rule 0:&lt;/em&gt;&lt;/strong&gt; &lt;strong&gt;The foundation rule:&lt;/strong&gt; For any system that is advertised as, or claimed to be, a relational data base management system, that system must be able to manage data bases entirely through its relational capabilities.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;&lt;em&gt;Rule 1:&lt;/em&gt;&lt;/strong&gt; &lt;strong&gt;The information rule:&lt;/strong&gt; All information in a relational data base is represented explicitly at the logical level and in exactly one way – by values in tables.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;&lt;em&gt;Rule 2:&lt;/em&gt;&lt;/strong&gt; &lt;strong&gt;The guaranteed access rule:&lt;/strong&gt; Each and every datum (atomic value) in a relational data base is guaranteed to be logically accessible by resorting to a combination of table name, primary key value and column name.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;&lt;em&gt;Rule 3:&lt;/em&gt;&lt;/strong&gt; &lt;strong&gt;Systematic treatment of null values:&lt;/strong&gt; Null values (distinct from the empty character string or a string of blank characters and distinct from zero or any other number) are supported in fully relational DBMS for representing missing information and inapplicable information in a systematic way, independent of data type.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;&lt;em&gt;Rule 4:&lt;/em&gt;&lt;/strong&gt; &lt;strong&gt;Dynamic online catalog based on the relational model:&lt;/strong&gt; The data base description is represented at the logical level in the same way as ordinary data, so that authorized users can apply the same relational language to its interrogation as they apply to the regular data.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;&lt;em&gt;Rule 5:&lt;/em&gt;&lt;/strong&gt; &lt;strong&gt;The comprehensive data sublanguage rule:&lt;/strong&gt; A relational system may support several languages and various modes of terminal use (for example, the fill-in-the-blanks mode). However, there must be at least one language whose statements are expressible, per some well-defined syntax, as character strings and that is comprehensive in supporting all of the following items:&lt;/p&gt; 
  &lt;ul&gt; 
   &lt;li&gt;Data definition.&lt;/li&gt; 
   &lt;li&gt;View definition.&lt;/li&gt; 
   &lt;li&gt;Data manipulation (interactive and by program).&lt;/li&gt; 
   &lt;li&gt;Integrity constraints.&lt;/li&gt; 
   &lt;li&gt;Authorization.&lt;/li&gt; 
   &lt;li&gt;Transaction boundaries (begin, commit and rollback).&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;&lt;em&gt;Rule 6:&lt;/em&gt;&lt;/strong&gt; &lt;strong&gt;The view updating rule:&lt;/strong&gt; All views that are theoretically updatable are also updatable by the system.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;&lt;em&gt;Rule 7:&lt;/em&gt;&lt;/strong&gt; &lt;strong&gt;Relational Operations Rule / Possible for high-level insert, update, and delete:&lt;/strong&gt; The capability of handling a base relation or a derived relation as a single operand applies not only to the retrieval of data but also to the insertion, update and deletion of data.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;&lt;em&gt;Rule 8:&lt;/em&gt;&lt;/strong&gt; &lt;strong&gt;Physical data independence:&lt;/strong&gt; Application programs and terminal activities remain logically unimpaired whenever any changes are made in either storage representations or access methods.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;&lt;em&gt;Rule 9:&lt;/em&gt;&lt;/strong&gt; &lt;strong&gt;Logical data independence:&lt;/strong&gt; Application programs and terminal activities remain logically unimpaired when information-preserving changes of any kind that theoretically permit unimpairment are made to the base tables.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;&lt;em&gt;Rule 10:&lt;/em&gt;&lt;/strong&gt; &lt;strong&gt;Integrity independence:&lt;/strong&gt; Integrity constraints specific to a particular relational data base must be definable in the relational data sublanguage and storable in the catalog, not in the application programs.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;&lt;em&gt;Rule 11:&lt;/em&gt;&lt;/strong&gt; &lt;strong&gt;Distribution independence:&lt;/strong&gt; The end-user must not be able to see that the data is distributed over various locations. Users should always get the impression that the data is located at one site only.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;&lt;em&gt;Rule 12:&lt;/em&gt;&lt;/strong&gt; &lt;strong&gt;The nonsubversion rule:&lt;/strong&gt; If a relational system has a low-level (single-record-at-a-time) language, that low level cannot be used to subvert or bypass the integrity rules and constraints expressed in the higher level relational language (multiple-records-at-a-time).&lt;/p&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Reading&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://opentextbc.ca/dbdesign01/&quot;&gt;Database Design – 2nd Edition&lt;/a&gt; - Adrienne Watt, Nelson Eng @ BCcampus Open Pressbooks (HTML, PDF, EPUB, Kindle)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.dcs.warwick.ac.uk/~hugh/TTM/Database-Explorations-revision-2.pdf&quot;&gt;Database Explorations&lt;/a&gt; (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://public.dhe.ibm.com/software/dw/db2/express-c/wiki/Database_fundamentals.pdf&quot;&gt;Database Fundamentals&lt;/a&gt; (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.dcs.warwick.ac.uk/~hugh/TTM/DTATRM.pdf&quot;&gt;Databases, Types, and The Relational Model: The Third Manifesto&lt;/a&gt; (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://webdam.inria.fr/Alice/&quot;&gt;Foundations of Databases&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.redbook.io&quot;&gt;Readings in Database Systems, 5th Ed.&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://people.cs.aau.dk/~csj/Thesis/&quot;&gt;Temporal Database Management&lt;/a&gt; - Christian S. Jensen&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://web.cecs.pdx.edu/~maier/TheoryBook/TRD.html&quot;&gt;The Theory of Relational Databases&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.thethirdmanifesto.com/&quot;&gt;The Third Manifesto&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.dcs.warwick.ac.uk/~hugh/TTM/Why-Are-There-No-Relational-DBMSs.pdf&quot;&gt;Why Are There No Relational DBMSs?&lt;/a&gt; - Hugh Darwen&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;/storage/models/ERModel-Chen.pdf&quot;&gt;The Entity-Relationship Model-Toward a Unified View of Data&lt;/a&gt; - Peter Pin-Shan Chen&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;Some interesting relational-oriented sites&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/decentralion/PokemonSQLTutorial&quot;&gt;PokemonSQLTutorial&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Vector storage model</title>
      <link>https://tedneward.github.io/Research/storage/models/vector/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/models/vector/index.html</guid>
      	<description>
	&lt;p&gt;&quot;A vector database is a data storage system used to manage, index, and query high-dimensional vector data. Vectors, in this context, represent data points in multi-dimensional space, often used in machine learning, data mining, and other advanced analytical applications. Vector databases are useful in tasks involving the computation of distances or similarities between vectors, such as recommendation systems, image and video recognition, and natural language processing. Unlike traditional databases that manage structured rows and columns, vector databases handle more complex, high-dimensional data representations, which are essential for applications requiring efficient similarity searches and pattern recognition. Some general purpose databases, such as PostgreSQL and Cassandra, now support both traditional data formats and vector data.&quot; --&lt;a href=&quot;https://www.instaclustr.com/education/vector-database/top-10-open-source-vector-databases/&quot;&gt;NetApp Instaclustr&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://www.pinecone.io/learn/vector-database/&quot;&gt;What is a vector database?&lt;/a&gt;: &quot;A vector database indexes and stores vector embeddings for fast retrieval and similarity search, with capabilities like CRUD operations, metadata filtering, horizontal scaling, and serverless.&quot;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://www.oracle.com/database/vector-database/&quot;&gt;What is a vector database?&lt;/a&gt;: &quot;A lesser-known data type, vectors, has seized the spotlight recently as an enabler of generative AI. But vectors—and databases capable of storing and analyzing them—have been toiling backstage for many years. They’re used in geospatial mapping and analysis for city planning, transportation logistics, and environmental analysis. More recently, vectors have been used in recommendation engines for retail products as well as music and video streaming sites.&quot;&lt;/p&gt; 
&lt;h2&gt;Implementations&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.pinecone.io/&quot;&gt;Pinecone&lt;/a&gt; (Commercial?)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.trychroma.com/&quot;&gt;Chroma&lt;/a&gt; &lt;a href=&quot;https://github.com/chroma-core/chroma&quot;&gt;Source&lt;/a&gt;: the open-source AI application database. Batteries included.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://turbopuffer.com/&quot;&gt;turbopuffer&lt;/a&gt; - Commercial?&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/weaviate/weaviate&quot;&gt;Weaviate&lt;/a&gt; (&lt;a href=&quot;https://weaviate.io/developers/weaviate&quot;&gt;Docs&lt;/a&gt;): an open source, AI-native vector database.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://milvus.io/&quot;&gt;Milvus&lt;/a&gt; &lt;a href=&quot;https://github.com/milvus-io/milvus&quot;&gt;Source&lt;/a&gt;: an open-source vector database built for GenAI applications.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://qdrant.tech/&quot;&gt;Qdrant&lt;/a&gt; &lt;a href=&quot;https://github.com/qdrant/qdrant&quot;&gt;Source&lt;/a&gt;: a vector similarity search engine and vector database.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;../../postgresql&quot;&gt;PostgresQL&lt;/a&gt; via pgvector&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;../../cassandra&quot;&gt;Cassandra&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;../../redis&quot;&gt;Redis&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;Valkey&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;../../cockroachdb&quot;&gt;CockroachDB&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Reading&lt;/h2&gt; 
&lt;h3&gt;Articles&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://thenewstack.io/how-to-master-vector-databases/&quot;&gt;https://thenewstack.io/how-to-master-vector-databases/&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://venturebeat.com/ai/vector-databases-shiny-object-syndrome-and-the-case-of-a-missing-unicorn&quot;&gt;Vector databases: Shiny object syndrome and the case of a missing unicorn&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://venturebeat.com/ai/from-shiny-object-to-sober-reality-the-vector-database-story-two-years-later&quot;&gt;From shiny object to sober reality: The vector database story, two years later&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>NDatabase</title>
      <link>https://tedneward.github.io/Research/storage/ndatabase/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/ndatabase/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://ndatabase.wixsite.com/home&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://archive.codeplex.com/&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Appears to be archived in CodePlex; not sure where new development is happening? Last copyright on the website is 2014.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Nextcloud</title>
      <link>https://tedneward.github.io/Research/storage/nextcloud/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/nextcloud/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://nextcloud.com/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/nextcloud/server&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>NocoDB</title>
      <link>https://tedneward.github.io/Research/storage/nocodb/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/nocodb/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.nocodb.com/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/nocodb&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Offers a &quot;signup&quot;--maybe cloud-hosted service?&lt;/p&gt; 
&lt;p&gt;Feature list:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Connects to any existing SQL database (MySQL, Postgres, MS SQL)&lt;/li&gt; 
 &lt;li&gt;Spreadsheet UI&lt;/li&gt; 
 &lt;li&gt;Views: Grid, Gallery, Kanban, Calendar, Custom&lt;/li&gt; 
 &lt;li&gt;Send Notifications (Slack)&lt;/li&gt; 
 &lt;li&gt;APIs: REST, GraphQL&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;Docker setup/run:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;SQLite: &lt;code&gt;docker run -d --name nocodb -v &quot;$(pwd)&quot;/nocodb:/usr/app/data/ -p 8080:8080 nocodb/nocodb/latest&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;MySQL: &lt;code&gt;docker run -d --name nocodb-mysql -v &quot;$(pwd)&quot;/nocodb:/usr/app/data/ -p 8080:8080 \ -e NC_DB=&quot;mysql2://host.docker.internal:3306?u=root&amp;amp;p=password&amp;amp;d=d1&quot; \ -e NC_AUTH_JWT_SECRET=&quot;569a1821-0a93-45e8-87ab-eb857f20a010&quot; \ nocodb/nocodb:latest&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;PostgreSQL: &lt;code&gt;docker run -d --name nocodb-postgres -v &quot;$(pwd)&quot;/nocodb:/usr/app/data/ -p 8080:8080 \ -e NC_DB=&quot;pg://host.docker.internal:5432?u=root&amp;amp;p=password&amp;amp;d=d1&quot; \ -e NC_AUTH_JWT_SECRET=&quot;569a1821-0a93-45e8-87ab-eb857f20a010&quot; \ nocodb/nocodb:latest&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;MSSQL: &lt;code&gt;docker run -d --name nocodb-mssql -v &quot;$(pwd)&quot;/nocodb:/usr/app/data/ -p 8080:8080 \ -e NC_DB=&quot;mssql://host.docker.internal:1433?u=root&amp;amp;p=password&amp;amp;d=d1&quot; \ -e NC_AUTH_JWT_SECRET=&quot;569a1821-0a93-45e8-87ab-eb857f20a010&quot; \ nocodb/nocodb:latest&lt;/code&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;... or use docker-compose:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;git clone https://github.com/nocodb/nocodb
# for MySQL
cd nocodb/docker-compose/mysql
# for PostgreSQL
cd nocodb/docker-compose/pg
# for MSSQL
cd nocodb/docker-compose/mssql
docker-compose up -d
&lt;/code&gt;&lt;/pre&gt; 
&lt;h2&gt;Articles&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.xda-developers.com/nocodb-guide/&quot;&gt;&quot;I replaced Airtable with NocoDb; here&apos;s how&quot;&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>ObjectBox</title>
      <link>https://tedneward.github.io/Research/storage/objectbox/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/objectbox/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://objectbox.io/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/objectbox/&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://objectbox.io/mongodb/&quot;&gt;MongoDB integration&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Double-entry storage model</title>
      <link>https://tedneward.github.io/Research/storage/models/double-entry/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/models/double-entry/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://pgrs.net/2025/06/17/double-entry-ledgers-missing-primitive-in-modern-software/&quot;&gt;Double-entry ledgers are a missing primitive in software&lt;/a&gt;: &quot;A double-entry ledger at its core is a few simple concepts put together:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;The current amount or balance of a thing&lt;/li&gt; 
 &lt;li&gt;A historical record of how the amount got to that amount (immutable, append only, etc)&lt;/li&gt; 
 &lt;li&gt;Where that amount came from at each step&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;&quot;The fact that every transfer only moves amounts, never creates them from scratch, is a built-in error check.2 And the historical record serves as an audit log.&quot;&lt;/p&gt; 
&lt;h2&gt;Implementations&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/pgr0ss/pgledger&quot;&gt;pgledger&lt;/a&gt;: pure PostgreSQL&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;/tools/ledger&quot;&gt;ledger&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Key-value storage model</title>
      <link>https://tedneward.github.io/Research/storage/models/key-value/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/models/key-value/index.html</guid>
      	<description>
	&lt;p&gt;(Placeholder)&lt;/p&gt; 
&lt;p&gt;Triple-stores, a la RDF, go in here?&lt;/p&gt; 
&lt;h2&gt;Reading&lt;/h2&gt; 
&lt;h3&gt;Articles/Blogs/Essays&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.nan.fyi/database&quot;&gt;&quot;Build Your Own Database&quot;&lt;/a&gt;: A step-by-step guide to building a key-value database from scratch.&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Spatial storage model</title>
      <link>https://tedneward.github.io/Research/storage/models/spatial/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/models/spatial/index.html</guid>
      	<description>
	&lt;p&gt;(Placeholder)&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Wide-column/columnar storage model</title>
      <link>https://tedneward.github.io/Research/storage/models/wide-column/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/models/wide-column/index.html</guid>
      	<description>
	&lt;p&gt;(Placeholder)&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Nebula Graph</title>
      <link>https://tedneward.github.io/Research/storage/nebula-graph/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/nebula-graph/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.nebula-graph.io/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/vesoft-inc/nebula&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Nitrite</title>
      <link>https://tedneward.github.io/Research/storage/nitrite/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/nitrite/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.dizitart.org/nitrite-database.html&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/nitrite/nitrite-java&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;h2&gt;Example&lt;/h2&gt; 
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;Nitrite db = Nitrite.builder()
    .compressed()
    .filePath(&quot;/tmp/test.db&quot;)
    .openOrCreate(&quot;user&quot;, &quot;password&quot;);

// Create a Nitrite Collection
NitriteCollection collection = db.getCollection(&quot;test&quot;);

// create a document to populate data
Document doc = createDocument(&quot;firstName&quot;, &quot;John&quot;)
     .put(&quot;lastName&quot;, &quot;Doe&quot;)
     .put(&quot;birthDay&quot;, new Date())
     .put(&quot;data&quot;, new byte[] {1, 2, 3})
     .put(&quot;fruits&quot;, new ArrayList&amp;lt;String&amp;gt;() {{ add(&quot;apple&quot;); add(&quot;orange&quot;); }})
     .put(&quot;note&quot;, &quot;a quick brown fox jump over the lazy dog&quot;);

// insert the document
collection.insert(doc);

// update the document
collection.update(eq(&quot;firstName&quot;, &quot;John&quot;), createDocument(&quot;lastName&quot;, &quot;Wick&quot;));
&lt;/code&gt;&lt;/pre&gt; 
&lt;h2&gt;Articles&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://tkainrad.dev/posts/nitrite-embedded-nosql-db/&quot;&gt;&quot;Nitrite as an embedded NoSQL database for Java&quot;&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Noms</title>
      <link>https://tedneward.github.io/Research/storage/noms/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/noms/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/attic-labs/noms&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Noms is a decentralized database philosophically descendant from the Git version control system.&lt;/p&gt; 
&lt;p&gt;Like Git, Noms is:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Versioned: By default, all previous versions of the database are retained. You can trivially track how the database evolved to its current state, easily and efficiently compare any two versions, or even rewind and branch from any previous version.&lt;/li&gt; 
 &lt;li&gt;Synchronizable: Instances of a single Noms database can be disconnected from each other for any amount of time, then later reconcile their changes efficiently and correctly.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;Unlike Git, Noms is a database, so it also:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Primarily stores structured data, not files and directories (see: the Noms type system)&lt;/li&gt; 
 &lt;li&gt;Scales well to large amounts of data and concurrent clients&lt;/li&gt; 
 &lt;li&gt;Supports atomic transactions (a single instance of Noms is CP, but Noms is typically run in production backed by S3, in which case it is &quot;effectively CA&quot;)&lt;/li&gt; 
 &lt;li&gt;Supports efficient indexes (see: Noms prolly-trees)&lt;/li&gt; 
 &lt;li&gt;Features a flexible query model (see: GraphQL)&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;A Noms database can reside within a file system or in the cloud:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;The (built-in) NBS ChunkStore implementation provides two back-ends which provide persistence for Noms databases: one for storage in a file system and one for storage in an S3 bucket.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;Finally, because Noms is content-addressed, it yields a very pleasant programming model.&lt;/p&gt; 
&lt;p&gt;Working with Noms is declarative. You don&apos;t INSERT new data, UPDATE existing data, or DELETE old data. You simply declare what the data ought to be right now. If you commit the same data twice, it will be deduplicated because of content-addressing. If you commit almost the same data, only the part that is different will be written.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>ObjectDB</title>
      <link>https://tedneward.github.io/Research/storage/objectdb/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/objectdb/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.objectdb.com/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://www.objectdb.com/download&quot;&gt;Download&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Akavache</title>
      <link>https://tedneward.github.io/Research/storage/akavache/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/akavache/index.html</guid>
      	<description>
	&lt;p&gt;&quot;Akavache is an asynchronous, persistent (i.e. writes to disk) key-value store created for writing desktop and mobile applications in C#, based on SQLite3. Akavache is great for both storing important data (i.e. user settings) as well as cached local data that expires.&quot;&lt;/p&gt; 
&lt;p&gt;&quot;Akavache is a library that makes common app patterns easy, and unifies caching of different object types (i.e. HTTP responses vs. JSON objects vs. images). It&apos;s built on a core key-value byte array store (conceptually similar to a Dictionary&amp;lt;string, byte[]&amp;gt;), and on top of that store, extensions are added to support:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Arbitrary objects via JSON.NET&lt;/li&gt; 
 &lt;li&gt;Fetching and loading Images and URLs from the Internet&lt;/li&gt; 
 &lt;li&gt;Storing and automatically encrypting User Credentials&quot;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;&lt;a href=&quot;https://github.com/reactiveui/Akavache&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>BBolt</title>
      <link>https://tedneward.github.io/Research/storage/bbolt/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/bbolt/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/etcd-io/bbolt&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;bbolt is a fork of Ben Johnson&apos;s &lt;a href=&quot;../bolt&quot;&gt;Bolt&lt;/a&gt; key/value store. The purpose of this fork is to provide the Go community with an active maintenance and development target for Bolt; the goal is improved reliability and stability. bbolt includes bug fixes, performance enhancements, and features not found in Bolt while preserving backwards compatibility with the Bolt API.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Build Your Own redis</title>
      <link>https://tedneward.github.io/Research/storage/byoredis/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/byoredis/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://build-your-own.org/redis/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://build-your-own.org/redis/src.tgz&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Table of Contents&lt;/p&gt; 
&lt;p&gt;Part 1. Getting Started&lt;/p&gt; 
&lt;ol&gt; 
 &lt;li&gt;&lt;a href=&quot;https://build-your-own.org/redis/01_intro_redis.html&quot;&gt;Introduction&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://build-your-own.org/redis/02_intro_sockets.html&quot;&gt;Introduction to Sockets&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://build-your-own.org/redis/03_hello_cs.html&quot;&gt;Hello Server/Client&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://build-your-own.org/redis/04_proto.html&quot;&gt;Protocol Parsing&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://build-your-own.org/redis/05_event_loop_intro.html&quot;&gt;The Event Loop and Nonblocking IO&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://build-your-own.org/redis/06_event_loop_impl.html&quot;&gt;The Event Loop Implementation&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://build-your-own.org/redis/07_basic_server.html&quot;&gt;Basic Server: get, set, del&lt;/a&gt;&lt;/li&gt; 
&lt;/ol&gt; 
&lt;p&gt;Part 2. Essential Topics&lt;/p&gt; 
&lt;ol&gt; 
 &lt;li&gt;&lt;a href=&quot;https://build-your-own.org/redis/08_hashtables.html&quot;&gt;Data Structure: Hashtables&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://build-your-own.org/redis/09_serialization.html&quot;&gt;Data Serialization&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://build-your-own.org/redis/10_avltree.html&quot;&gt;The AVL Tree: Implementation and Testing&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://build-your-own.org/redis/11_sortedset.html&quot;&gt;The AVL Tree and the Sorted Set&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://build-your-own.org/redis/12_timer.html&quot;&gt;The Event Loop and Timers&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://build-your-own.org/redis/13_heap.html&quot;&gt;The Heap Data Structure and the TTL&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://build-your-own.org/redis/14_thread.html&quot;&gt;The Thread Pool and Asynchronous Tasks&lt;/a&gt;&lt;/li&gt; 
&lt;/ol&gt; 
&lt;p&gt;Appendixes&lt;/p&gt; 
&lt;ol&gt; 
 &lt;li&gt;&lt;a href=&quot;https://build-your-own.org/redis/a1_hints.html&quot;&gt;Hints to exercises&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://build-your-own.org/redis/a2_reading.html&quot;&gt;Further Reading&lt;/a&gt;&lt;/li&gt; 
&lt;/ol&gt;
	</description>
    </item>
    <item>
      <title>Cloudflare Durable Objects (D1)</title>
      <link>https://tedneward.github.io/Research/storage/cloudflared1/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/cloudflared1/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.cloudflare.com/lp/d1/&quot;&gt;Website&lt;/a&gt; |&lt;/p&gt; 
&lt;p&gt;It uses a different data model than the traditional SQL data model, which looks and works a lot like a document-oriented database like MongoDB. We know that in a traditional SQL database, data is stored in tables consisting of rows and columns. Consider a table called “employees” with the following columns as “id”, “name”, “age”, and “department”. In contrast, CloudFare D1 stores data in the form of objects like a document database. So to translate the above example, we have an object called “Employee” that has the following properties: “id”, “name”, “age”, and “department”.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Couchbase</title>
      <link>https://tedneward.github.io/Research/storage/couchbase/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/couchbase/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.couchbase.com/&quot;&gt;Website&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Community Editions are open-source.&lt;/p&gt; 
&lt;hr&gt; 
&lt;h1&gt;Couchbase Mobile&lt;/h1&gt; 
&lt;p&gt;Formerly Couchbase Lite.&lt;/p&gt; 
&lt;p&gt;Mobile syncing client to Couchbase.&lt;/p&gt; 
&lt;p&gt;Source: &lt;a href=&quot;https://github.com/couchbase/couchbase-lite-ios&quot;&gt;iOS/macOS&lt;/a&gt; | &lt;a href=&quot;https://github.com/couchbase/couchbase-lite-core&quot;&gt;C++ &quot;core&quot;&lt;/a&gt; | &lt;a href=&quot;https://github.com/couchbase/couchbase-lite-net&quot;&gt;.NET&lt;/a&gt; | &lt;a href=&quot;https://github.com/couchbase/couchbase-lite-java&quot;&gt;Java&lt;/a&gt; | &lt;a href=&quot;https://github.com/couchbase/couchbase-lite-android&quot;&gt;Android&lt;/a&gt; | &lt;a href=&quot;https://github.com/couchbase/couchbase-lite-java-common&quot;&gt;Java and Android common&lt;/a&gt; | &lt;a href=&quot;https://github.com/couchbase/couchbase-lite-android-ce&quot;&gt;Android Community Edition&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>DBM</title>
      <link>https://tedneward.github.io/Research/storage/dbm/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/dbm/index.html</guid>
      	<description>
	&lt;p&gt;DBM allows an application program to store key-value pairs in a file and reuse them later. Each of keys and values is a string or a sequence of bytes. The key of each record must be unique within the database and a value is associated to it. You can retrieve a stored record with its key very quickly. Thanks to simple structure of DBM, its performance can be extremely high.&lt;/p&gt; 
&lt;h2&gt;Implementations&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt; &lt;p&gt;C++: &lt;a href=&quot;https://dbmx.net/tkrzw/&quot;&gt;Tkrzw: a set of implementations of DBM&lt;/a&gt;: &quot;Tkrzw is a C++ library implementing DBM with various algorithms. It features high degrees of performance, concurrency, scalability and durability. The following classes are provided.&lt;/p&gt; 
  &lt;ul&gt; 
   &lt;li&gt;HashDBM : File database manager implementation based on hash table.&lt;/li&gt; 
   &lt;li&gt;TreeDBM : File database manager implementation based on B+ tree.&lt;/li&gt; 
   &lt;li&gt;SkipDBM : File database manager implementation based on skip list.&lt;/li&gt; 
   &lt;li&gt;TinyDBM : On-memory database manager implementation based on hash table.&lt;/li&gt; 
   &lt;li&gt;BabyDBM : On-memory database manager implementation based on B+ tree.&lt;/li&gt; 
   &lt;li&gt;CacheDBM : On-memory database manager implementation with LRU deletion.&lt;/li&gt; 
   &lt;li&gt;Std(Hash|Tree)DBM : On-memory DBM implementations using std::unordered_map and std::map.&lt;/li&gt; 
   &lt;li&gt;(Poly|Shard)DBM : Polymorphic and sharding database manager adapters.&lt;/li&gt; 
   &lt;li&gt;AsyncDBM : Asynchronous database manager adapter.&lt;/li&gt; 
   &lt;li&gt;(File|Mem)Index : Secondary index implementations.&lt;/li&gt; 
  &lt;/ul&gt; &lt;p&gt;&quot;You can use some bridging interfaces to use Tkrzw in other programming languages than C++. Currently, C, Java, Python, Ruby, and Go interfaces are provided. The C interface is bundled in the main package. The other interfaces are packaged separately.&quot;&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;C++: &lt;a href=&quot;https://dbmx.net/kyotocabinet/&quot;&gt;Kyoto Cabinet&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt;C: &lt;a href=&quot;https://dbmx.net/tokyocabinet/&quot;&gt;Tokyo Cabinet&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>DiceDB</title>
      <link>https://tedneward.github.io/Research/storage/dicedb/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/dicedb/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://dicedb.io/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/dicedb/dice&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Docker: &lt;code&gt;docker run -p 7379:7379 dicedb/dicedb&lt;/code&gt;&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;open source under GNU AGPL 3.0&lt;/li&gt; 
 &lt;li&gt;Redis-compliant - a drop-in (36.4%) replacement of Redis (here&apos;s why)&lt;/li&gt; 
 &lt;li&gt;Reactive - native support for query subscriptions and push&lt;/li&gt; 
 &lt;li&gt;Scalable - scales out and scales in with load *&lt;/li&gt; 
 &lt;li&gt;Highly available - failovers and durability *&lt;/li&gt; 
 &lt;li&gt;Unified cache - multi-tenant and shared everything architecture *&lt;/li&gt; 
 &lt;li&gt;Optimized for modern hardware - multi-threaded with shared-nothing architecture *&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;and we aim to be the high-performance caching backbone for modern architecture.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>DragonflyDB</title>
      <link>https://tedneward.github.io/Research/storage/dragonflydb/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/dragonflydb/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.dragonflydb.io/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/dragonflydb/dragonfly&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Claims to be API-compatible with Redis or memcached.&lt;/p&gt; 
&lt;p&gt;Single binary.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>dynomite</title>
      <link>https://tedneward.github.io/Research/storage/dynomite/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/dynomite/index.html</guid>
      	<description>
	&lt;p&gt;&quot;Dynomite, inspired by &lt;a href=&quot;http://www.allthingsdistributed.com/files/amazon-dynamo-sosp2007.pdf&quot;&gt;Dynamo whitepaper&lt;/a&gt;, is a thin, distributed dynamo layer for different storage engines and protocols. Currently these include Redis and Memcached. Dynomite supports multi-datacenter replication and is designed for high availability.&lt;/p&gt; 
&lt;p&gt;&quot;The ultimate goal with Dynomite is to be able to implement high availability and cross-datacenter replication on storage engines that do not inherently provide that functionality. The implementation is efficient, not complex (few moving parts), and highly performant.&quot;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://github.com/Netflix/dynomite&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>EventStoreDB</title>
      <link>https://tedneward.github.io/Research/storage/eventstoredb/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/eventstoredb/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.eventstore.com/eventstoredb&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/EventStore/EventStore&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>FaunaDB</title>
      <link>https://tedneward.github.io/Research/storage/faunadb/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/faunadb/index.html</guid>
      	<description>
	&lt;p&gt;&quot;The database built for serverless, featuring native GraphQL. Add a full-featured global datastore to your apps in minutes. Access effortlessly from the browser and from mobile. Never again worry about data correctness, capacity, redundancy, latency, and availability. FaunaDB is a global serverless database that gives you ubiquitous, low latency access to app data, without sacrificing data correctness and scale. It eliminates layers of app code for manually handling data anomalies, security, and scale, creating a friendlier dev experience for you and better app experience for your users. Relational, document and graph access to the same set of data using modern APIs such as GraphQL that are easy to work with. No cold starts, and no additional middleware necessary. 100% ACID, with globally consistent reads and writes without compromising latency and scale. Trust your app data. Eliminate unnecessary code. Data automatically replicated across global regions instantly, correctly. Requests are routed automatically to the region closest to the user for low-latency reads and writes ensuring snappiest possible app experience. Start risk-free with one of the most generous free tiers available. Throttling-free transparent scaling, so your app never encounters unplanned capacity hiccups or outages. Eliminate complexity with built-in authorization that is easy to use, yet powerful. Lockdown data with a rich, attribute-based security model. Never leave your data unprotected. Sign up and go. Never again deal with database provisioning, clustering, backups, and maintenance. Spans multiple clouds so you never see downtime. It just works.&quot;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://fauna.com/&quot;&gt;Website&lt;/a&gt; | No Github?&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Flyway</title>
      <link>https://tedneward.github.io/Research/storage/flyway/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/flyway/index.html</guid>
      	<description>
	&lt;p&gt;Evolve your database schema easily and reliably across all your instances | &lt;a href=&quot;https://flywaydb.org&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/flyway/flyway&quot;&gt;Github&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>GraphEngine</title>
      <link>https://tedneward.github.io/Research/storage/graphengine/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/graphengine/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.graphengine.io/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/Microsoft/GraphEngine&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;The distributed RAM store provides a globally addressable high-performance key-value store over a cluster of machines. Through the RAM store, GE enables the fast random data access power over a large distributed data set.&lt;/p&gt; 
&lt;p&gt;The capability of fast data exploration and distributed parallel computing makes GE a natural large graph processing platform. GE supports both low-latency online query processing and high-throughput offline analytics on billion-node large graphs.&lt;/p&gt; 
&lt;h4&gt;Strongly-typed RAM Store&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;strong&gt;Schema Matters.&lt;/strong&gt; Schema does matter when we need to process data efficiently. Strongly-typed data modeling is crucial for compact data storage, fast data access, and clear data semantics.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;One Byte Counts.&lt;/strong&gt; GE is good at managing billions of run-time objects of varied sizes. One byte counts as the number of objects goes large. GE provides fast memory allocation and efficient memory reallocation with high memory utilization ratios.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;GE fits in where cache is not good enough.&lt;/strong&gt; GE makes use of RAM to speed up the data access as well as the computation. RAM is directly used as run-time storage instead of just being used for serving static resources.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;General Computation Engine&lt;/h4&gt; 
&lt;p&gt;GE is also a flexible computation engine powered by declarative message passing. GE is for you, if you are building a system that needs to perform fine-grained user-specified server-side computation.&lt;/p&gt; 
&lt;p&gt;From the perspective of graph computation, GE is not a graph system specifically optimized for a certain graph operation. Instead, with its built-in data and computation modeling capability, we can develop graph computation modules with ease. In other words, GE can easily morph into a system supporting a specific graph computation.&lt;/p&gt; 
&lt;h4&gt;General-purpose Large Scale Graph Processing Engine&lt;/h4&gt; 
&lt;p&gt;GE is a graph data management system. It is designed to manage real-life graphs with rich associated data instead of just graph topology.&lt;/p&gt; 
&lt;p&gt;On the one hand, it addresses the grand random data access challenge of graph computation at the bottom layer. On the other hand, it addresses the diversity issue of both graph data and graph computation by allowing users to freely specify their own graph models as well as the computation paradigms.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>HyperGraphDB</title>
      <link>https://tedneward.github.io/Research/storage/hypergraphdb/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/hypergraphdb/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;http://www.hypergraphdb.org/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/hypergraphdb/hypergraphdb&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;h3&gt;Example: Hello World&lt;/h3&gt; 
&lt;pre&gt;&lt;code&gt;HyperGraph graph = new HyperGraph(&quot;/path/to/workdir/bje&quot;);
String hello = graph.get(graph.add(&quot;Hello World&quot;)); 
System.out.println(hello.toLowerCase());
graph.close();
&lt;/code&gt;&lt;/pre&gt; 
&lt;ul&gt; 
 &lt;li&gt;graph.add returns something that graph.get consumes - HGHandle, that&apos;s how atoms are referred to.&lt;/li&gt; 
 &lt;li&gt;graph.get returns a String object with working toLowerCase method - this shows that hypergraphDB is also an object-oriented database.&lt;/li&gt; 
 &lt;li&gt;if you manage several hypergraph instances, use HGEnvironment.get(location).&lt;/li&gt; 
 &lt;li&gt;do not forget to close after usage, because that might lead to corruption. It&apos;s recommended to wrap your code in a try block, and ensure graph.close() in a finally block.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Example: Store/retrieve data&lt;/h3&gt; 
&lt;pre&gt;&lt;code&gt;String someObject = &quot;Lorem ipsum&quot;;
HGHandle handle1 = graph.add(someObject);
System.out.println(graph.get(handleToSomeObject));
System.out.println(((String) graph.get(handle1)).toUpperCase());
&lt;/code&gt;&lt;/pre&gt; 
&lt;ul&gt; 
 &lt;li&gt;graph.add(...) returnes a &quot;handle&quot; with which you can access the datum directly (as seen in graph.get a line below). A handle generally is an auto-generated database ID.&lt;/li&gt; 
 &lt;li&gt;using add/get to store and retrieve data is not necessarily the typical way hypergraphdb is used because: 
  &lt;ul&gt; 
   &lt;li&gt;graph.get() requires you to know the handle. This is often not the case, especially when you want data that you did not store just moments ago (hence most of the time! :-) ). Therefore most accesses typically happen by querying.&lt;/li&gt; 
   &lt;li&gt;If graph.add(someObject) is called more than once (for example by accident, each time you run a given program), you would end up with duplicates that can be disturbing when querying.&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;the second println demonstrate that we get a fully functional java object, in that case, it has a working toUpperCase method. This shows that hypergraphDB is not only a graph-database, but also a full object-oriented database.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Example: Store and retrieve data without knowing the handle - querying basics&lt;/h3&gt; 
&lt;p&gt;Querying is done conveniently by using the static helper class &quot;hg&quot;:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;import org.hypergraphdb.HGQuery.hg.*;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;We stored only one element in our database, so we would immediately find &quot;Lorem ipsum&quot; simply by querying for type String:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;System.out.println(hg.getOne(graph, hg.type(String.class)));
-&amp;gt; &quot;Lorem ipsum&quot;;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;hg.getOne returns you any one (of possibly many) matching result as a ready-to-use object, just as did graph.get. But often we have several items that match a certain criteria. We get can get those packed in a List, with hg.getAll: In order to have two atoms, we just add the same object as above:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;HGHandle handle2 = graph.add(someObject);
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;and then query for all Strings:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;for (Object s : hg.getAll(graph, hg.type(String.class)))
    System.out.println(s);
-&amp;gt; Lorem ipsum Lorem ipsum
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;We get two results here, that happen to be distinct duplicate copies of the same data (we prove that later).&lt;/p&gt; 
&lt;p&gt;As you see, querying is generally used in one of this ways:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;hg.getOne (graphInstance, QueryCondition); // -&amp;gt;  any one matching object.
hg.getAll (graphInstance, QueryCondition); // -&amp;gt;  all matching objects as a List.
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;where &quot;QueryCondition&quot; in our example is hg.type(String.class), but of course there is more.&lt;/p&gt; 
&lt;h3&gt;Query&lt;/h3&gt; 
&lt;p&gt;Sometimes you need handles and also you do not want to dereference and deserialize all results of a query into memory. To query by returning handles is easy. It&apos;s the same as with getOne/getAll, but instead of h.getOne you use hg.findOne. Instead of hg.getAll, use hg.findAll.&lt;/p&gt; 
&lt;p&gt;We use this to confirm that we created actual duplicate atoms in the &quot;Lorem ipsum&quot; example above. We printout the handles, and check for equality with the handles obtained before:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;for (Object s : hg.findAll(graph, hg.type(String.class)))
{
  System.out.println(s);
  System.out.println((s.equals(handle1) || s.equals(handle2)));
}
-&amp;gt; 259b3dbd-4e4f-4566-b850-1029f99e6d1b true dceadb0c-318b-4249-917a-559d2f077fcc true
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;Store data uniquely&lt;/h3&gt; 
&lt;p&gt;How to make sure that a given data is stored only once, even when -by accident or not- the data is stored twice?&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;String object2 = &quot;dolor sit amet&quot;;
HGHandle noDup1 = hg.assertAtom(graph, object2);
HGHandle noDup2 = hg.assertAtom(graph, object2);  //trying hard to duplicate
System.out.println(&quot;Are those two handles duplicates, i.e. two distinct handles? : &quot; + (!noDup1.equals(noDup2)));
-&amp;gt; &quot;Are those two handles duplicates, i.e. two distinct handles? : false&quot;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Note that logically there is a cost associated with checking if a given datum already exists. If you don&apos;t need unique atoms, graph.add is faster.&lt;/p&gt; 
&lt;h3&gt;Create Links and query for Links&lt;/h3&gt; 
&lt;p&gt;Till now there was nothing graph, only object-oriented database functionality. We also did not do particularly interesting queries.&lt;/p&gt; 
&lt;p&gt;Let&apos;s make a link and query for it:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;HGHandle duplicateLink = graph.add(new HGPlainLink(handle1, handle2));
List&amp;lt;HGHandle&amp;gt; dupsList = hg.findAll(graph, hg.link(handle1, handle2));
System.out.println(&quot;querying for link returned that duplicate Link? :&quot; + dupsList.contains(duplicateLink));
=&amp;gt; querying for link returned that duplicate Link? :true
&lt;/code&gt;&lt;/pre&gt;
	</description>
    </item>
    <item>
      <title>InfiniteGraph</title>
      <link>https://tedneward.github.io/Research/storage/infinitegraph/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/infinitegraph/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://objectivity.com/infinitegraph/&quot;&gt;Website&lt;/a&gt; |&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Apache Jena</title>
      <link>https://tedneward.github.io/Research/storage/jena/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/jena/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://jena.apache.org/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://gitbox.apache.org/repos/asf?p=jena.git&quot;&gt;Source&lt;/a&gt; or &lt;a href=&quot;https://github.com/apache/jena&quot;&gt;Github Mirror&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>KDB+</title>
      <link>https://tedneward.github.io/Research/storage/kdb/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/kdb/index.html</guid>
      	<description>
	&lt;p&gt;kdb+ is&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;a high-performance cross-platform historical timeseries columnar database&lt;/li&gt; 
 &lt;li&gt;an in-memory compute engine&lt;/li&gt; 
 &lt;li&gt;a realtime streaming processor&lt;/li&gt; 
 &lt;li&gt;an expressive query and programming language called q&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;kdb+ is a database. You can use it through interfaces such as ODBC, or from Python, but its power and performance are best accessed through its own language, q.&lt;/p&gt; 
&lt;p&gt;Q is a general-purpose programming language. You can write programs for anything in q.&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;http://www.kx.com/kdb-plus.php&quot;&gt;Website&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>LensVM</title>
      <link>https://tedneward.github.io/Research/storage/lensvm/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/lensvm/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://docs.source.network/lensvm&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/sourcenetwork/lens&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>LiteDB</title>
      <link>https://tedneward.github.io/Research/storage/litedb/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/litedb/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.litedb.org/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/mbdavid/litedb&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Features:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Portable UWP and Xamarin iOS/Android&lt;/li&gt; 
 &lt;li&gt;ACID transactions&lt;/li&gt; 
 &lt;li&gt;Single datafile (like SQLite)&lt;/li&gt; 
 &lt;li&gt;Recovery data in writing failure (WAL mode)&lt;/li&gt; 
 &lt;li&gt;Map your POCO class to BsonDocument&lt;/li&gt; 
 &lt;li&gt;Fluent API for custom mapping&lt;/li&gt; 
 &lt;li&gt;Cross collections references (DbRef)&lt;/li&gt; 
 &lt;li&gt;Store files and stream data (like GridFS in MongoDB)&lt;/li&gt; 
 &lt;li&gt;LINQ query support&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;Nearly 1-for-1 feature parity with any Mongo-esque document database.&lt;/p&gt; 
&lt;p&gt;Quick example:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-cs&quot;&gt;// Create your POCO class entity
public class Customer
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string[] Phones { get; set; }
    public bool IsActive { get; set; }
}

// Open database (or create if doesn&apos;t exist)
using(var db = new LiteDatabase(@&quot;C:\Temp\MyData.db&quot;))
{
    // Get a collection (or create, if doesn&apos;t exist)
    var col = db.GetCollection&amp;lt;Customer&amp;gt;(&quot;customers&quot;);

    // Create your new customer instance
    var customer = new Customer
    { 
        Name = &quot;John Doe&quot;, 
        Phones = new string[] { &quot;8000-0000&quot;, &quot;9000-0000&quot; }, 
        IsActive = true
    };
	
    // Insert new customer document (Id will be auto-incremented)
    col.Insert(customer);
	
    // Update a document inside a collection
    customer.Name = &quot;Jane Doe&quot;;
	
    col.Update(customer);
	
    // Index document using document Name property
    col.EnsureIndex(x =&amp;gt; x.Name);
	
    // Use LINQ to query documents (filter, sort, transform)
    var results = col.Query()
        .Where(x =&amp;gt; x.Name.StartsWith(&quot;J&quot;))
        .OrderBy(x =&amp;gt; x.Name)
        .Select(x =&amp;gt; new { x.Name, NameUpper = x.Name.ToUpper() })
        .Limit(10)
        .ToList();

    // Let&apos;s create an index in phone numbers (using expression). It&apos;s a multikey index
    col.EnsureIndex(x =&amp;gt; x.Phones); 

    // and now we can query phones
    var r = col.FindOne(x =&amp;gt; x.Phones.Contains(&quot;8888-5555&quot;));
}
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Custom class mapping&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-cs&quot;&gt;BsonMapper.Global.RegisterType&amp;lt;DateTimeOffset&amp;gt;
(
    serialize: obj =&amp;gt;
    {
        var doc = new BsonDocument();
        doc[&quot;DateTime&quot;] = obj.DateTime.Ticks;
        doc[&quot;Offset&quot;] = obj.Offset.Ticks;
        return doc;
    },
    deserialize: doc =&amp;gt; new DateTimeOffset(doc[&quot;DateTime&quot;].AsInt64, new TimeSpan(doc[&quot;Offset&quot;].AsInt64))
);
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;File (binary) storage&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-cs&quot;&gt;// Get file storage with Int Id
var storage = db.GetStorage&amp;lt;int&amp;gt;();

// Upload a file from file system to database
storage.Upload(123, @&quot;C:\Temp\picture-01.jpg&quot;);

// And download later
storage.Download(123, @&quot;C:\Temp\copy-of-picture-01.jpg&quot;);
&lt;/code&gt;&lt;/pre&gt;
	</description>
    </item>
    <item>
      <title>MariaDB</title>
      <link>https://tedneward.github.io/Research/storage/mariadb/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/mariadb/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://mariadb.com/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/mariadb-developers&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Metadata-Connect</title>
      <link>https://tedneward.github.io/Research/storage/metadata-connect/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/metadata-connect/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://objectivity.com/metadata-connect/&quot;&gt;Website&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>ArangoDB</title>
      <link>https://tedneward.github.io/Research/storage/arangodb/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/arangodb/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.arangodb.com/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/arangodb/arangodb&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Provides its own query language (AQL). Compares itself against &lt;a href=&quot;../mongodb&quot;&gt;MongoDB&lt;/a&gt;, &lt;a href=&quot;../neo4j&quot;&gt;Neo4j&lt;/a&gt;, and &lt;a href=&quot;../cassandra&quot;&gt;Cassandra&lt;/a&gt;.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>BerkeleyDB</title>
      <link>https://tedneward.github.io/Research/storage/berkeleydb/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/berkeleydb/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://docs.oracle.com/cd/E17076_04/html/index.html&quot;&gt;Website&lt;/a&gt; &lt;a href=&quot;https://libdb.org/&quot;&gt;Older website&lt;/a&gt; | &lt;a href=&quot;https://github.com/berkeleydb/libdb&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Cassandra</title>
      <link>https://tedneward.github.io/Research/storage/cassandra/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/cassandra/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://cassandra.apache.org/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://gitbox.apache.org/repos/asf/cassandra.git&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://cassandra.apache.org/doc/latest/&quot;&gt;Docs&lt;/a&gt;:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://cassandra.apache.org/doc/latest/cassandra/architecture/index.html&quot;&gt;Architecture&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://cassandra.apache.org/doc/latest/cassandra/data_modeling/index.html&quot;&gt;Data Modeling&lt;/a&gt; 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.datastax.com/blog/basic-rules-cassandra-data-modeling&quot;&gt;&quot;Basic Rules of Cassandra Data Modeling&quot;&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://cassandra.apache.org/doc/latest/cassandra/cql/index.html&quot;&gt;Cassandra Query Language&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://cassandra.apache.org/doc/latest/cassandra/tools/index.html&quot;&gt;Tools&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://cassandra.apache.org/_/native_protocol.html&quot;&gt;Native Protocols&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>CockroachDB</title>
      <link>https://tedneward.github.io/Research/storage/cockroachdb/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/cockroachdb/index.html</guid>
      	<description>
	&lt;p&gt;&quot;A relational database for next generation, cloud-native applications. CockroachDB offers the familiarity and power of SQL with the comfort of your existing ORMs. Automated sharding ensures great performance as you scale. CockroachDB offers a multi-region database that operates with single-region latency and ensures data is always available and an RPO of zero.&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://www.cockroachlabs.com/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/cockroachdb/cockroach&quot;&gt;Github&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>CouchDB</title>
      <link>https://tedneward.github.io/Research/storage/couchdb/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/couchdb/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://couchdb.apache.org/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/apache/couchdb&quot;&gt;Source&lt;/a&gt; | &lt;a href=&quot;http://docs.couchdb.com/en/latest/intro/index.html&quot;&gt;Docs&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;http://guide.couchdb.org/&quot;&gt;CouchDB: The Definitive Guide&lt;/a&gt; | &lt;a href=&quot;https://github.com/oreilly/couchdb-guide&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;h2&gt;Reading&lt;/h2&gt; 
&lt;h3&gt;Books&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;http://guide.couchdb.org&quot;&gt;CouchDB: The Definitive Guide&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;hr&gt; 
&lt;p&gt;&lt;a href=&quot;https://github.com/couchapp/couchapp&quot;&gt;CouchApps&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>DefraDb</title>
      <link>https://tedneward.github.io/Research/storage/defradb/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/defradb/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://docs.source.network/defradb&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/sourcenetwork/defradb&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;DefraDB is an application-centric database that prioritizes data ownership, personal privacy, and information security. Its data model, powered by the convergence of MerkleCRDTs and the content-addressability of IPLD, enables a multi-write-master architecture. It features DQL, a query language compatible with GraphQL but providing extra convenience. By leveraging peer-to-peer infrastructure, it can be deployed nimbly in novel topologies. Access control is determined by a relationship-based DSL, supporting document or field-level policies, secured by the SourceHub infrastructure. DefraDB is a core part of the Source technologies that enable new paradigms of local-first software, edge compute, access-control management, application-centric features, data trustworthiness, and much more.&lt;br&gt; &apos;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Ditto</title>
      <link>https://tedneward.github.io/Research/storage/ditto/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/ditto/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.ditto.com/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://docs.ditto.live/home/introduction&quot;&gt;Docs&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>DuckDB</title>
      <link>https://tedneward.github.io/Research/storage/duckdb/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/duckdb/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://duckdb.org/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/duckdb/duckdb&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;When to use DuckDB&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Processing and storing tabular datasets, e.g. from CSV or Parquet files&lt;/li&gt; 
 &lt;li&gt;Interactive data analysis, e.g. Joining &amp;amp; aggregate multiple large tables&lt;/li&gt; 
 &lt;li&gt;Concurrent large changes, to multiple large tables, e.g. appending rows, adding/removing/updating columns&lt;/li&gt; 
 &lt;li&gt;Large result set transfer to client&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;When to not use DuckDB&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;High-volume transactional use cases (e.g. tracking orders in a webshop)&lt;/li&gt; 
 &lt;li&gt;Large client/server installations for centralized enterprise data warehousing&lt;/li&gt; 
 &lt;li&gt;Writing to a single database from multiple concurrent processes&lt;/li&gt; 
 &lt;li&gt;Multiple concurrent processes reading from a single writable database&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Articles&lt;/h2&gt; 
&lt;p&gt;&lt;a href=&quot;https://thenewstack.io/duckdb-in-process-python-analytics-for-not-quite-big-data/&quot;&gt;&quot;DuckDB: In-Process Python Analytics for Not-Quite-Big Data&quot;&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Eclipse Store</title>
      <link>https://tedneward.github.io/Research/storage/eclipsestore/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/eclipsestore/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://eclipsestore.io/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/eclipse-store/store&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;h2&gt;Reading&lt;/h2&gt; 
&lt;h3&gt;Articles&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;InfoQ: &lt;a href=&quot;https://www.infoq.com/presentations/eclipse-store/&quot;&gt;Ultra-Fast In-Memory Database Applications with Java&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>eXistdb</title>
      <link>https://tedneward.github.io/Research/storage/existdb/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/existdb/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://exist-db.org/exist/apps/homepage/index.html&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/eXist-db/exist&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://learning.oreilly.com/library/view/exist/9781449337094/&quot;&gt;Book&lt;/a&gt; (OReilly Safari)&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>FerretDB</title>
      <link>https://tedneward.github.io/Research/storage/ferretdb/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/ferretdb/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.ferretdb.com/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/ferretdb&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;h2&gt;Articles&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://blog.ferretdb.io/building-dynamic-forms-with-formio-ferretdb/&quot;&gt;https://blog.ferretdb.io/building-dynamic-forms-with-formio-ferretdb/&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>FoundationDB</title>
      <link>https://tedneward.github.io/Research/storage/foundationdb/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/foundationdb/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.foundationdb.org/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/apple/foundationdb/&quot;&gt;Source&lt;/a&gt; | &lt;a href=&quot;https://apple.github.io/foundationdb/&quot;&gt;Docs&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;FoundationDB is a distributed database designed to handle large volumes of structured data across clusters of commodity servers. It organizes data as an ordered key-value store and employs ACID transactions for all operations. It is especially well-suited for read/write workloads but also has excellent performance for write-intensive workloads. Users interact with the database using a API language binding. You can begin local development today.&lt;/p&gt; 
&lt;h2&gt;Reading&lt;/h2&gt; 
&lt;h3&gt;Articles&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://thenewstack.io/foundationdb-a-distributed-database-that-cant-be-killed/#&quot;&gt;&quot;FoundationDB: A Distributed Database that Can&apos;t Be Killed&quot;&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h1&gt;Data Modeling&lt;/h1&gt; 
&lt;p&gt;FoundationDB&apos;s core provides a simple data model coupled with powerful transactions. This combination allows building richer data models and libraries that inherit the scalability, performance, and integrity of the database. The goal of data modeling is to design a mapping of data to keys and values that enables effective storage and retrieval. Good decisions will yield an extensible, efficient abstraction. This document covers the fundamentals of data modeling with FoundationDB.&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;For general guidance on application development using FoundationDB, see :doc:&lt;code&gt;developer-guide&lt;/code&gt;.&lt;/li&gt; 
 &lt;li&gt;For detailed API documentation specific to each supported language, see :doc:&lt;code&gt;api-reference&lt;/code&gt;.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h1&gt;The core data model&lt;/h1&gt; 
&lt;p&gt;FoundationDB&apos;s core data model is an ordered key-value store. Also known as an ordered associative array, map, or dictionary, this is a common data structure composed of a collection of key-value pairs in which all keys are unique. Starting with this simple model, an application can create higher-level data models by mapping their elements to individual keys and values.&lt;/p&gt; 
&lt;p&gt;In FoundationDB, both keys and values are simple byte strings. Apart from storage and retrieval, the database does not interpret or depend on the content of values. In contrast, keys are treated as members of a total order, the lexicographic order over the underlying bytes, in which keys are sorted by each byte in order. For example:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;code&gt;&apos;0&apos;&lt;/code&gt; is sorted before &lt;code&gt;&apos;1&apos;&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;&apos;apple&apos;&lt;/code&gt; is sorted before &lt;code&gt;&apos;banana&apos;&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;&apos;apple&apos;&lt;/code&gt; is sorted before &lt;code&gt;&apos;apple123&apos;&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;keys starting with &lt;code&gt;&apos;mytable\&apos;&lt;/code&gt; are sorted together (e.g. &lt;code&gt;&apos;mytable\row1&apos;&lt;/code&gt;, &lt;code&gt;&apos;mytable\row2&apos;&lt;/code&gt;, ...)&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;The ordering of keys is especially relevant for range operations. An application should structure keys to produce an ordering that allows efficient data retrieval with range reads.&lt;/p&gt; 
&lt;p&gt;.. _encoding-data-types:&lt;/p&gt; 
&lt;h1&gt;Encoding data types&lt;/h1&gt; 
&lt;p&gt;Because keys and values in FoundationDB are always byte strings, an application developer must serialize other data types (e.g., integers, floats, arrays) before storing them in the database. For values, the main concerns for serialization are simply CPU and space efficiency. For keys, there&apos;s an additional consideration: it&apos;s often important for keys to preserve the order of the data types (whether primitive or composite) they encode. For example:&lt;/p&gt; 
&lt;h2&gt;Integers&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;The standard tuple layer provides an order-preserving, signed, variable length encoding.&lt;/li&gt; 
 &lt;li&gt;For positive integers, a big-endian fixed length encoding is order-preserving.&lt;/li&gt; 
 &lt;li&gt;For signed integers, a big-endian fixed length two&apos;s-complement encoding with the most significant (sign) bit inverted is order-preserving.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Unicode strings&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;For unicode strings ordered lexicographically by unicode code point, use UTF-8 encoding. (This approach is used by the tuple layer.)&lt;/li&gt; 
 &lt;li&gt;For unicode strings ordered by a particular collation (for example, a case insensitive ordering for a particular language), use an appropriate string collation transformation and then apply UTF-8 encoding. Internationalization or &quot;locale&quot; libraries in most environments and programming languages provide a string collation transformation, for example &lt;code&gt;C &amp;lt;http://pubs.opengroup.org/onlinepubs/7908799/xsh/wcsxfrm.html&amp;gt;&lt;/code&gt;&lt;em&gt;, &lt;code&gt;C++ &amp;lt;http://www.cplusplus.com/reference/std/locale/collate/transform/&amp;gt;&lt;/code&gt;&lt;/em&gt;, &lt;code&gt;Python &amp;lt;http://docs.python.org/py3k/library/locale.html#locale.strxfrm&amp;gt;&lt;/code&gt;&lt;em&gt;, &lt;code&gt;Ruby &amp;lt;https://github.com/ninjudd/icunicode#readme&amp;gt;&lt;/code&gt;&lt;/em&gt;, &lt;code&gt;Java &amp;lt;http://docs.oracle.com/javase/1.5.0/docs/api/java/text/Collator.html#getCollationKey(java.lang.String)&amp;gt;&lt;/code&gt;&lt;em&gt;, the &lt;code&gt;ICU &amp;lt;http://icu-project.org/apiref/icu4c/classCollator.html#ae524fd43a06d4429e2c76bef35874d4c&amp;gt;&lt;/code&gt;&lt;/em&gt; library, etc. Usually the output of this function is a unicode string, which needs to be further encoded in a code-point ordered encoding such as UTF-8 to get a byte string.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Floating point numbers&lt;/h2&gt; 
&lt;p&gt;The tuple layer provides an order-preserving, signed, fixed length encoding for both single- and double-precision floating point&lt;br&gt; numbers based off of the IEEE big-endian encoding with some modifications to make it correctly ordered. Within this representation,&lt;br&gt; -0 and +0 are not equal and negative NaN values will sort before all non-NaN values and positive NaN values will sort after&lt;br&gt; all non-NaN values. Otherwise, the representation is consistent with the mathematical ordering.&lt;/p&gt; 
&lt;h2&gt;Composite types&lt;/h2&gt; 
&lt;p&gt;An application&apos;s data is often represented using composite types, such as structures or records with multiple fields. It&apos;s very useful for the application to use &lt;em&gt;composite&lt;/em&gt; keys to store such data. In FoundationDB, composite keys can be conveniently represented as &lt;em&gt;tuples&lt;/em&gt; that are mapped to individual keys for storage.&lt;/p&gt; 
&lt;p&gt;.. note:: For the purpose of illustration, we&apos;ll use the FoundationDB&apos;s Python language binding, including the :py:func:&lt;code&gt;@fdb.transactional &amp;lt;fdb.transactional&amp;gt;&lt;/code&gt; decorator described in :doc:&lt;code&gt;api-python&lt;/code&gt;. The design patterns illustrated are applicable to all of the :doc:&lt;code&gt;languages &amp;lt;api-reference&amp;gt;&lt;/code&gt; supported by FoundationDB.&lt;/p&gt; 
&lt;p&gt;.. _data-modeling-tuples:&lt;/p&gt; 
&lt;h1&gt;Tuples&lt;/h1&gt; 
&lt;p&gt;FoundationDB&apos;s keys are ordered, making tuples a particularly useful tool for data modeling. FoundationDB provides a :ref:&lt;code&gt;tuple layer &amp;lt;api-python-tuple-layer&amp;gt;&lt;/code&gt; (available in each language binding) that encodes tuples into keys. This layer lets you store data using a tuple like &lt;code&gt;(state, county)&lt;/code&gt; as a key. Later, you can perform reads using a prefix like &lt;code&gt;(state,)&lt;/code&gt;. The layer works by preserving the natural ordering of the tuples.&lt;/p&gt; 
&lt;p&gt;You could implement a naive encoding of tuples of strings into keys by using a tab character as a simple delimiter. You could do this with the following Python code::&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;def tuple_to_key_with_tab(tup):
    return &apos;\t&apos;.join(str(i) for i in tup)

# Example: Order first by state, then by county
@fdb.transactional
def set_county_population(tr, state, county, pop):
    tr[tuple_to_key_with_tab((state, county))] = str(pop)
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;In this example, population figures for the United States are stored using keys formed from the tuple of state and county.&lt;/p&gt; 
&lt;p&gt;Of course, this encoding would only work if all the bytes in the individual keys in the tuple were greater than the delimiter byte. Therefore, FoundationDB&apos;s built-in tuple layer implements a more robust encoding supporting elements of various data types: byte strings, unicode strings, signed integers, floating-point numbers, booleans, UUIDs, null values, and nested tuples.&lt;/p&gt; 
&lt;p&gt;.. note:: The tuple layer&apos;s encoding is compatible between languages, although some languages are limited in what data types they support. For language-specific documentation of the tuple layer, see the corresponding :doc:&lt;code&gt;api-reference&lt;/code&gt; documentation.&lt;/p&gt; 
&lt;p&gt;Because of its ordering of keys, FoundationDB supports efficient range reads on any set of keys that share a prefix. The tuple layer preserves the ordering of tuples sorted by element from left to right; as a result, the leftmost elements of a tuple will always represent a prefix in keyspace and can be used for range reads. A basic principle of data modeling with the tuple layer is to order tuple elements to facilitate such range reads. The examples below illustrate this principle.&lt;/p&gt; 
&lt;p&gt;Sometimes data attributes will have a natural order of containment imposed by your domain. A common example is geographic attributes, such as state and county in the Unites States. By constructing keys from tuples of the form &lt;code&gt;(state, county)&lt;/code&gt;, where state is the first tuple element, all data for states will be stored in an adjacent range of keys. This ordering allows you to retrieve the populations for all counties in a given state with a single range read. You could use the tuple layer with the following functions::&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;@fdb.transactional
def set_county_population(tr, state, county, pop):
    tr[fdb.tuple.pack((state, county))] = str(pop)

@fdb.transactional
def get_county_populations_in_state(tr, state):
    return [int(pop) for k, pop in tr[fdb.tuple.range((state,))]]
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Date/timestamp attributes form another example with a natural containment order. If you have attributes of year, month, day, hour, minute, and/or second, you can order them from larger to smaller units in your keys. As a result, you&apos;ll be able to retrieve temporally contiguous data with range reads, as above.&lt;/p&gt; 
&lt;h1&gt;A few simple models&lt;/h1&gt; 
&lt;p&gt;Let&apos;s begin with a few examples of simple data models built on tuples with :ref:&lt;code&gt;subspaces &amp;lt;developer-guide-sub-keyspaces&amp;gt;&lt;/code&gt;.&lt;/p&gt; 
&lt;h2&gt;Arrays&lt;/h2&gt; 
&lt;p&gt;You can easily map arrays to the key-value store using tuples. To model a named, one-dimensional array, you can construct a key for each array element using the array name as the subspace and the array index as the second tuple element.&lt;/p&gt; 
&lt;p&gt;For example, suppose you have a &lt;code&gt;&apos;temps2012&apos;&lt;/code&gt; array containing a year&apos;s worth of daily temperature averages. The temperatures are indexed by an integer ranging from 1 to 365 representing the day. Your keys would then be constructed from tuples of the form &lt;code&gt;(&apos;temps2012&apos;, day)&lt;/code&gt;.&lt;/p&gt; 
&lt;p&gt;To set and get array elements with this technique, you can use Python functions such as::&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;@fdb.transactional
def array_set(tr, array_space, index, value):
    tr[array_space[index]] = str(value)

@fdb.transactional
def array_get(tr, array_space, index):
    return tr[array_space[index]]

temp_array = Subspace((&apos;temps2012&apos;,))

@fdb.transactional
def add_temp(tr, day, temp):
    array_set(tr, temp_array, day, temp)

@fdb.transactional
def get_temp(tr, day):
    val = array_get(tr, temp_array, day)
    if val.present():
        return int(val)
    else:
        return None
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;This approach has a few nice properties:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;It can be extended to multidimensional arrays simply by adding additional array indexes to the tuples.&lt;/li&gt; 
 &lt;li&gt;Unassigned elements consume no storage, so sparse arrays are stored efficiently.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;The tuple layer makes these properties easy to achieve, and most well-designed data models using tuples will share them.&lt;/p&gt; 
&lt;p&gt;An array can only have a single value for each index. Likewise, the key-value store can only have a single value for each key. The simple mapping above takes advantage of this correspondence to store the array value as a physical value. In contrast, some data structures are designed to store multiple values. In these cases, data models can store the logical values within the key itself, as illustrated next.&lt;/p&gt; 
&lt;h2&gt;Multimaps&lt;/h2&gt; 
&lt;p&gt;A multimap is a generalization of an associative array in which each key may be associated with multiple values. Multimaps are often implemented as associative arrays in which the values are sets rather than primitive data types.&lt;/p&gt; 
&lt;p&gt;Suppose you have a multimap that records student enrollment in classes, with students as keys and classes as values. Each student can be enrolled in more than one class, so you need to map the key-value pairs of the multimap (with their multiple values) to the database.&lt;/p&gt; 
&lt;p&gt;A simple approach is to use the multimap name (say, &lt;code&gt;&apos;enroll&apos;&lt;/code&gt;) as the subspace and construct a key from a tuple of the form &lt;code&gt;(&apos;enroll&apos;, student, class_name)&lt;/code&gt; for each class in which a student is enrolled. Each class will generate a unique key, allowing as many classes as needed. Moreover, all the data in the multimap will be captured in the key, so you can just use an empty string for its value. Using this approach, you can add a class for a student or get all the student&apos;s classes with the Python functions::&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;@fdb.transactional
def multi_set(tr, multi_space, index, value):
    tr[multi_space.pack((index, value))] = &apos;&apos;

@fdb.transactional
def multi_get(tr, multi_space, index):
    pairs = tr[multi_space.range((index,))]
    return [multi_space.unpack(k)[-1] for k, v in pairs]

@fdb.transactional
def multi_is_element(tr, multi_space, index, value):
    val = tr[multi_space.pack((index, value))]
    return val.present()

enroll_space = Subspace((&apos;enroll&apos;,))

@fdb.transactional
def add_class(tr, student, class_name):
    multi_set(tr, enroll_space, student, class_name)

@fdb.transactional
def get_classes(tr, student):
    return multi_get(tr, enroll_space, student)
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;The &lt;code&gt;range()&lt;/code&gt; method in :py:func:&lt;code&gt;multi_get&lt;/code&gt; returns all keys in the subspace that encode tuples with the specified tuple as a prefix. The &lt;code&gt;[-1]&lt;/code&gt; extracts the last element of the tuple unpacked from the key, which in this case will encode a class.&lt;/p&gt; 
&lt;p&gt;As this model for multimaps illustrates, data that is treated as a value at one level may be mapped to a key in the database. (The reverse may also occur, as shown in the discussion of indirection below.) Data modeling in FoundationDB is not dictated by how your data is represented in your programming language.&lt;/p&gt; 
&lt;p&gt;.. _data-modeling-tables:&lt;/p&gt; 
&lt;h2&gt;Tables&lt;/h2&gt; 
&lt;p&gt;You can easily use tuples to store data in tabular form with rows and columns. The simplest data model for a table is to make each cell in the table a key-value pair. To do this, you construct a key from a tuple containing the row and column identifiers. As with the array model, unassigned cells in tables constructed using this technique will consume no storage, so sparse tables can be stored efficiently. As a result, a table can safely have a very large number of columns.&lt;/p&gt; 
&lt;p&gt;You can make your model row-oriented or column-oriented by placing either the row or column first in the tuple, respectively. Because the lexicographic order sorts tuple elements from left to right, access is optimized for the element placed first. Placing the row first makes it efficient to read all the cells in a particular row; reversing the order makes reading a column more efficient.&lt;/p&gt; 
&lt;p&gt;Using the table name as the subspace, we could implement the common row-oriented version in Python as follows::&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;@fdb.transactional
def table_set_cell(tr, table_space, row, column, value):
    tr[table_space.pack((row, column))] = str(value)

@fdb.transactional
def table_get_cell(tr, table_space, row, column):
    return tr[table_space.pack((row, column))]

@fdb.transactional
def table_set_row(tr, table_space, row, cols):
    del tr[table_space.range((row,))]
    for c, v in cols.iteritems():
        table_set_cell(tr, table_space, row, c, v)

@fdb.transactional
def table_get_row(tr, table_space, row):
    cols = {}
    for k, v in tr[table_space.range((row,))]:
        _, c = table_space.unpack(k)
        cols[c] = v
    return cols
&lt;/code&gt;&lt;/pre&gt; 
&lt;h2&gt;Versionstamps&lt;/h2&gt; 
&lt;p&gt;A common data model is to index your data with a sequencing prefix to allow log scans or tails of recent data. This index requires a unique, monotonically increasing value, like an AUTO_INCREMENT PRIMARY KEY in SQL. This could be implemented at the client level by reading the value for conflict checks before every increment. A better solution is the versionstamp, which can be generated at commit-time with no read conflict ranges, providing a unique sequence ID in a single conflict-free write.&lt;/p&gt; 
&lt;p&gt;Versioning commits provides FoundationDB with MVCC guarantees and transactional integrity. Versionstamps write the transaction&apos;s commit version as a value to an arbitrary key as part of the same transaction, allowing the client to leverage the version&apos;s unique and serial properties. Because the versionstamp is generated at commit-time, the versionstamped key cannot be read in the same transaction that it is written, and the versionstamp&apos;s value will be unknown until the transaction is committed. After the transaction is committed, the versionstamp can be obtained.&lt;/p&gt; 
&lt;p&gt;The versionstamp guarantees uniqueness and monotonically increasing values for the entire lifetime of a single FDB cluster. This is even true if the cluster is restored from a backup, as a restored cluster will begin at a higher version than when the backup was taken. Special care must be taken when moving data between two FoundationDB clusters containing versionstamps, as the differing cluster versions might break the monotonicity.&lt;/p&gt; 
&lt;p&gt;There are two concepts of versionstamp depending on your context. At the fdb_c client level, or any binding outside of the Tuple layer, the &apos;versionstamp&apos; is 10 bytes: the transaction&apos;s commit version (8 bytes) and transaction batch order (2 bytes). The user can manually add 2 additional bytes to provide application level ordering. The tuple layer provides a useful api for getting and setting both the 10 byte system version and the 2 byte user version. In the context of the Tuple layer, the &apos;versionstamp&apos; is all 12 bytes. For examples on how to use the versionstamp in the python binding, see the :doc:&lt;code&gt;api-python&lt;/code&gt; documentation.&lt;/p&gt; 
&lt;p&gt;.. _data-modeling-entity-relationship:&lt;/p&gt; 
&lt;h1&gt;Entity-relationship models&lt;/h1&gt; 
&lt;p&gt;Entity-relationship models are often used to describe a database at various levels of abstraction. In this methodology, a &lt;em&gt;logical&lt;/em&gt; data model consisting of entities, attributes, and relationships is defined before mapping it to a &lt;em&gt;physical&lt;/em&gt; data models specifying keys and other implementation features. Entity-relationship models can be easily modeled in FoundationDB using tuples.&lt;/p&gt; 
&lt;h2&gt;Attributes&lt;/h2&gt; 
&lt;p&gt;Suppose you&apos;re storing entity-relationship data for users in an &lt;code&gt;&apos;ER&apos;&lt;/code&gt; subspace. You might identify each entity with a unique identifier and define a key for each attribute with the tuple &lt;code&gt;(&apos;ER&apos;, entity_ID, attribute)&lt;/code&gt;. You could then store the user&apos;s region using the Python functions::&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;ER_space = Subspace((&apos;ER&apos;,))

@fdb.transactional
def add_attribute_value(tr, entity_ID, attribute, value):
    tr[ER_space.pack((entity_ID, attribute))] = str(value)

@fdb.transactional
def get_attribute_value(tr, entity_ID, attribute):
    return tr[ER_space.pack((entity_ID, attribute))]

@fdb.transactional
def add_user_region(tr, user_ID, region):
    add_attribute_value(tr, user_ID, &apos;region&apos;, region)
&lt;/code&gt;&lt;/pre&gt; 
&lt;h2&gt;Relationships&lt;/h2&gt; 
&lt;p&gt;Using the pattern we saw above with multimaps, you can store relationships and related entities as an element of the key and use an empty string as the physical value. Suppose your users can belong to one or more groups. To add a user to a group or retrieve all groups to which a user belongs, you can use the Python functions::&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;@fdb.transactional
def add_relationship(tr, relationship, primary_key, foreign_key):
    tr[ER_space.pack((relationship, primary_key, foreign_key))] = &apos;&apos;

@fdb.transactional
def get_relationships(tr, relationship):
    return [ER_space.unpack(k)[1:] 
            for k, v in tr.get_range_startswith(ER_space.pack((relationship,)), 
                                        streaming_mode=fdb.StreamingMode.want_all)]

@fdb.transactional
def get_related_entities(tr, relationship, primary_key):
    items = tr[ER_space.range((relationship, primary_key))]
    return [ER_space.unpack(k)[-1] for k, v in items]

@fdb.transactional
def is_related_entity(tr, relationship, primary_key, foreign_key):
    return tr[ER_space.pack((relationship, primary_key, foreign_key))].present()

@fdb.transactional
def add_user_to_group(tr, user_ID, group_name):
    add_relationship(tr, &apos;belongs_to&apos;, user_ID, group_name)

@fdb.transactional
def get_users_groups(tr, user_ID):
   return get_related_entities(tr, &apos;belongs_to&apos;, user_ID)
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;You can extend this code by adding indexes for the related entities (see below) and enforcement of relationship cardinalities (one-to-many, etc.).&lt;/p&gt; 
&lt;p&gt;.. _data-modeling-indexes:&lt;/p&gt; 
&lt;h1&gt;Indexes&lt;/h1&gt; 
&lt;p&gt;A common technique is to store the same data in different ways to allow efficient retrieval for multiple use cases, creating indexes. This technique is especially useful when there are many more reads than writes. For example, you may find it most convenient to store user data based on &lt;code&gt;user_ID&lt;/code&gt; but sometimes need to retrieve users based on their region. An index allows this retrieval to be performed efficiently.&lt;/p&gt; 
&lt;p&gt;An index can have a very simple tuple structure consisting of an unique subspace, the relationship being indexed, and a value: &lt;code&gt;(subspace_for_index, relationship, value)&lt;/code&gt;. Placing the relationship before the value is what allows efficient retrieval of all the associated values with a single range read.&lt;/p&gt; 
&lt;p&gt;With FoundationDB&apos;s transactions, you can easily build an index and guarantee that it stays in sync with the data: just update the index in the same transaction that updates the data.&lt;/p&gt; 
&lt;p&gt;For example, suppose you&apos;d like to add an index to efficiently look up users by region. You can augment the Python function :py:func:&lt;code&gt;add_user&lt;/code&gt; with the index and add a new function for retrieval::&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;user_space = Subspace((&apos;user&apos;,))
region_index = Subspace((&apos;region_idx&apos;,))

@fdb.transactional
def add_user(tr, user_ID, name, region):
    tr[user_space.pack((user_ID, region))] = str(name)
    tr[region_index.pack((region, user_ID))] = &apos;&apos;

@fdb.transactional
def get_users_in_region(tr, region):
    items = tr[region_index.range((region,))]
    return [region_index.unpack(k)[-1] for k, v in items]
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;To apply this technique to a real use case, you would add code to your update transaction to delete outdated index entries. Note that this approach lets you add as many indexes as desired by updating all the indexes in the same transaction.&lt;/p&gt; 
&lt;h1&gt;Composite models&lt;/h1&gt; 
&lt;p&gt;Most of the techniques we&apos;ve discussed can be freely combined. Let&apos;s look at adding indexes to our basic data model for tables.&lt;/p&gt; 
&lt;p&gt;We&apos;ve already seen a way to store tabular data in a row-oriented order using table names as subspaces. You can extend this model by simultaneously storing the table in both row-oriented and column-oriented layouts, allowing efficient retrieval of either an entire row or an entire column. We&apos;ll create nested subspaces for the indexes using the subscripting syntax we saw above::&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;table_space = Subspace((&apos;table&apos;,))
row_index = table_space[&apos;row_idx&apos;]
col_index = table_space[&apos;col_idx&apos;]

@fdb.transactional
def table_set_cell(tr, row_index, col_index, row, column, value):
    tr[row_index.pack((row, column))] = str(value)
    tr[col_index.pack((column, row))] = str(value)

@fdb.transactional
def table_get_cell(tr, row_index, row, column):
    return tr[row_index.pack((row, column))]

@fdb.transactional
def table_get_row(tr, row_index, row):
    cols = {}
    for k, v in tr[row_index.range((row,))]:
        r, c = row_index.unpack(k)
        cols[c] = v
    return cols

@fdb.transactional
def table_get_col(tr, col_index, col):
    rows = {}
    for k, v in tr[col_index.range((col,))]:
        c, r = col_index.unpack(k)
        rows[r] = v
    return rows
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;.. _data-modeling-hierarchies:&lt;/p&gt; 
&lt;h1&gt;Hierarchies&lt;/h1&gt; 
&lt;p&gt;Many applications work with hierarchical data represented by nested dictionaries or similar composite data types. Such data is often serialized to or deserialized from a format such as JSON or XML. Looking at a hierarchical object as a tree, you can use a tuple to represent the full path to each leaf (sometimes called a &quot;materialized path&quot;). By storing each full path as a key, you get an index for each leaf. FoundationDB can then efficiently retrieve any individual piece of data or entire sub-tree.&lt;/p&gt; 
&lt;p&gt;For example, suppose you have hierarchical data such as the following nested dictionaries and lists::&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;{&apos;user&apos;: {  &apos;jones&apos;: 
            {   &apos;friendOf&apos;: &apos;smith&apos;,
                &apos;group&apos;: [&apos;sales&apos;, &apos;service&apos;]},
            &apos;smith&apos;: 
            {   &apos;friendOf&apos;: &apos;jones&apos;,
                &apos;group&apos;: [&apos;dev&apos;, &apos;research&apos;]}}}
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;To distinguish the list elements from dictionary elements and preserve the order of the lists, you can just include the index of each list element before it in the tuple. Using this technique, the data above would be converted to the following tuples::&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;[(&apos;user&apos;, &apos;jones&apos;, &apos;friendOf&apos;, &apos;smith&apos;), 
(&apos;user&apos;, &apos;jones&apos;, &apos;group&apos;, 0, &apos;sales&apos;), 
(&apos;user&apos;, &apos;jones&apos;, &apos;group&apos;, 1, &apos;service&apos;), 
(&apos;user&apos;, &apos;smith&apos;, &apos;friendOf&apos;, &apos;jones&apos;), 
(&apos;user&apos;, &apos;smith&apos;, &apos;group&apos;, 0, &apos;dev&apos;), 
(&apos;user&apos;, &apos;smith&apos;, &apos;group&apos;, 1, &apos;research&apos;)]
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Suppose you&apos;d like to use this representation to implement a nested keyspace, i.e., a key-value store in which values can themselves be nested dictionaries or lists. Your application receives a stream of serialized JSON objects in which different objects may contain data about the same entities, so you&apos;d like to store the data in a common nested keyspace.&lt;/p&gt; 
&lt;p&gt;You can deserialize the data using Python&apos;s standard &lt;code&gt;json&lt;/code&gt; module, generate the corresponding set of paths as tuples, and store each tuple in a &lt;code&gt;&apos;hier&apos;&lt;/code&gt; subspace::&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;import json, itertools

hier_space = Subspace((&apos;hier&apos;,))

EMPTY_OBJECT = -2
EMPTY_ARRAY = -1

def to_tuples(item):
    if item == {}:
        return [(EMPTY_OBJECT, None)]
    elif item == []:
        return [(EMPTY_ARRAY, None)]
    elif type(item) == dict:
        return [(k,) + sub for k, v in item.iteritems() for sub in to_tuples(v)]
    elif type(item) == list:
        return [(k,) + sub for k, v in enumerate(item) for sub in to_tuples(v)]
    else:
        return [(item,)]

@fdb.transactional
def insert_hier(tr, hier):
    if type(hier) == str:
        hier = json.loads(hier)
    for tup in to_tuples(hier):
        tr[hier_space.pack(tup)] = &apos;&apos;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;You can then retrieve any sub-tree from the nested keyspace by giving the partial path to its root. The partial path will just be a tuple that your query function uses as a key prefix for a range read. For example, to retrieve the data for &lt;code&gt;&apos;smith&apos;&lt;/code&gt; from the hierarchy above, you would use &lt;code&gt;(&apos;user&apos;, &apos;smith&apos;)&lt;/code&gt;.&lt;/p&gt; 
&lt;p&gt;The retrieved data will be a list of tuples. The final step before returning the data is to convert it back to a nested data structure::&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;def from_tuples(tuples):
    first = tuples[0]  # The first tuple will tell us what kind of object we have

    if len(first) == 1: return first[0]  # Primitive value
    if first == (EMPTY_OBJECT,None): return {}
    if first == (EMPTY_ARRAY, None): return []

    # For an object or array, we need to group the tuples by their first element
    groups = [list(g) for k, g in itertools.groupby(tuples, lambda t:t[0])]

    if first[0] == 0:   # array
        return [from_tuples([t[1:] for t in g]) for g in groups]
    else:    # object
        return dict((g[0][0], from_tuples([t[1:] for t in g])) for g in groups)

@fdb.transactional
def get_sub_hier(tr, prefix):
    return from_tuples([hier_space.unpack(k)
                        for k, v in tr[hier_space.range(prefix)]])
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;.. _data-modeling-documents:&lt;/p&gt; 
&lt;h1&gt;Documents&lt;/h1&gt; 
&lt;p&gt;Suppose you&apos;d like to use the above representation to implement a simple document-oriented data model. As before, your application receives serialized data in JSON, only now you&apos;d like to store each JSON object as an independent document. To do so, you just need to ensure that each tuple created for that object is stored with a unique identifier for the document. If a &lt;code&gt;doc_id&lt;/code&gt; has not already been supplied, you can randomly generate one.&lt;/p&gt; 
&lt;p&gt;To store a path, you can construct a composite key in a &lt;code&gt;&apos;doc&apos;&lt;/code&gt; subspace, with the &lt;code&gt;doc_id&lt;/code&gt; as the next element, followed by the remainder of the path. You can store the leaf (the last element of the tuple) as the value, which enables storage of larger data sizes (see :ref:&lt;code&gt;data-modeling-performance-guidelines&lt;/code&gt;)::&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;import random

doc_space = Subspace((&apos;doc&apos;,))

@fdb.transactional
def insert_doc(tr, doc):
    if type(doc) == str:
        doc = json.loads(doc)
    if not &apos;doc_id&apos; in doc:
        doc[&apos;doc_id&apos;] = random.randint(0, 100000000)
    for tup in to_tuples( doc ):
        tr[doc_space.pack((doc[&apos;doc_id&apos;],) + tup[:-1])] = fdb.tuple.pack((tup[-1],))
    return doc[&apos;doc_id&apos;]

@fdb.transactional
def get_doc(tr, doc_id):
    return from_tuples([doc_space.unpack(k)[1:] + fdb.tuple.unpack(v)
                        for k, v in tr[doc_space.range((doc_id,))]])
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;.. _data-modeling-indirection:&lt;/p&gt; 
&lt;h1&gt;Indirection&lt;/h1&gt; 
&lt;p&gt;It is sometimes beneficial to add a level of indirection to a data model. Instead of using key-value pairs to directly store application data, you can instead store a reference to that data. This approach can be used to model any data structure that would normally use references. You just need to perform any modifications to the data structure in a transaction that leaves it in a consistent state.&lt;/p&gt; 
&lt;p&gt;Suppose you want to maintain data in a singly linked list. The application data can use a tuple structure like those of single-valued relationships. Links will be similar but will use node identifiers as their values. Here is an example of removing the next node from the list::&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;node_space = Subspace((&apos;node&apos;,))

@fdb.transactional
def remove_next_node(tr, node_ID):
    next_ID = tr[node_space.pack((node_ID, &apos;next&apos;))]
    if next_ID != &apos;&apos;:
        next_next_ID = tr[node_space.pack((next_ID, &apos;next&apos;))]
        tr[node_space.pack((node_ID, &apos;next&apos;))] = next_next_ID
        del tr[node_space.range((next_ID,))]
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;FoundationDB&apos;s transactional guarantees ensure that, even when multiple clients are concurrently modifying the same linked list, the structure will be maintained in a consistent way.&lt;/p&gt; 
&lt;p&gt;.. _data-modeling-performance-guidelines:&lt;/p&gt; 
&lt;h1&gt;Key and value sizes&lt;/h1&gt; 
&lt;p&gt;How you map your application data to keys and values can have a dramatic impact on performance. Below are some guidelines to consider as you design a data model. (For more general discussion of performance considerations, see :ref:&lt;code&gt;developer-guide-peformance-considerations&lt;/code&gt;.)&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt; &lt;p&gt;Structure keys so that range reads can efficiently retrieve the most frequently accessed data.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;If you perform a range read that is, in total, much more than 1 kB, try to restrict your range as much as you can while still retrieving the needed data.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Structure keys so that no single key needs to be updated too frequently, which can cause transaction conflicts.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;If a key is updated more than 10-100 times per second, try to split it into multiple keys.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt;For example, if a key is storing a counter, split the counter into N separate counters that are randomly incremented by clients. The total value of the counter can then read by adding up the N individual ones.&lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Keep key sizes small.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Try to keep key sizes below 1 kB. (Performance will be best with key sizes below 32 bytes and &lt;em&gt;cannot&lt;/em&gt; be more than 10 kB.)&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt;When using the tuple layer to encode keys (as is recommended), select short strings or small integers for tuple elements. Small integers will encode to just two bytes.&lt;/li&gt; 
 &lt;li&gt;If your key sizes are above 1 kB, try either to move data from the key to the value, split the key into multiple keys, or encode the parts of the key more efficiently (remembering to preserve any important ordering).&lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Keep value sizes moderate.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Try to keep value sizes below 10 kB. (Value sizes &lt;em&gt;cannot&lt;/em&gt; be more than 100 kB.)&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt;If your value sizes are above 10 kB, consider splitting the value across multiple keys.&lt;/li&gt; 
 &lt;li&gt;If you read values with sizes above 1 kB but use only a part of each value, consider splitting the values using multiple keys.&lt;/li&gt; 
 &lt;li&gt;If you frequently perform individual reads on a set of values that total to fewer than 200 bytes, try either to combine the values into a single value or to store the values in adjacent keys and use a range read.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Large Values and Blobs&lt;/h2&gt; 
&lt;p&gt;If your keys or values are much larger than the above guidelines, it may be difficult to find a data model that resizes them appropriately. Unstructured data, such as binary large objects, can be especially challenging to segment manually. In this case, a good option is to use our blob layer. See our tutorial on :doc:&lt;code&gt;Managing Large Values and Blobs &amp;lt;largeval&amp;gt;&lt;/code&gt; for further discussion.&lt;/p&gt; 
&lt;h1&gt;Example: Class Scheduling&lt;/h1&gt; 
&lt;p&gt;This tutorial provides a walkthrough of designing and building a simple application in Python using FoundationDB. In this tutorial, we use a few simple data modeling techniques. For a more in-depth discussion of data modeling in FoundationDB, see &lt;a href=&quot;https://apple.github.io/foundationdb/data-modeling.html&quot;&gt;here&lt;/a&gt;.&lt;/p&gt; 
&lt;h1&gt;First steps&lt;/h1&gt; 
&lt;p&gt;Let&apos;s begin with &quot;Hello world.&quot;&lt;/p&gt; 
&lt;p&gt;Open a Python interactive interpreter and import the FoundationDB API module::&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;$ python
&amp;gt;&amp;gt;&amp;gt; import fdb
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Before using the API, we need to specify the API version. This allows programs to maintain compatibility even if the API is modified in future versions::&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;&amp;gt;&amp;gt;&amp;gt; fdb.api_version(740)
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Next, we open a FoundationDB database. The API will connect to the FoundationDB cluster indicated by the :ref:&lt;code&gt;default cluster file &amp;lt;default-cluster-file&amp;gt;&lt;/code&gt;. ::&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;&amp;gt;&amp;gt;&amp;gt; db = fdb.open()
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;We are ready to use the database. In Python, using the &lt;code&gt;[]&lt;/code&gt; operator on the db object is a convenient syntax for performing a read or write on the database. First, let&apos;s simply write a key-value pair:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;&amp;gt;&amp;gt;&amp;gt; db[b&apos;hello&apos;] = b&apos;world&apos;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;When this command returns without exception, the modification is durably stored in FoundationDB! Under the covers, this function creates a transaction with a single modification. We&apos;ll see later how to do multiple operations in a single transaction. For now, let&apos;s read back the data::&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;&amp;gt;&amp;gt;&amp;gt; print &apos;hello&apos;, db[b&apos;hello&apos;]
hello world
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;If this is all working, it looks like we are ready to start building a real application. For reference, here&apos;s the full code for &quot;hello world&quot;::&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;import fdb
fdb.api_version(740)
db = fdb.open()
db[b&apos;hello&apos;] = b&apos;world&apos;
print &apos;hello&apos;, db[b&apos;hello&apos;]
&lt;/code&gt;&lt;/pre&gt; 
&lt;h1&gt;Class scheduling application&lt;/h1&gt; 
&lt;p&gt;Let&apos;s say we&apos;ve been asked to build a class scheduling system for students and administrators. We&apos;ll walk through the design and implementation of this application. Instead of typing everything in as you follow along, look at the :ref:&lt;code&gt;tutorial-appendix&lt;/code&gt; for a finished version of the program. You may want to refer to this code as we walk through the tutorial.&lt;/p&gt; 
&lt;h2&gt;Requirements&lt;/h2&gt; 
&lt;p&gt;We&apos;ll need to let users list available classes and track which students have signed up for which classes. Here&apos;s a first cut at the functions we&apos;ll need to implement::&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;available_classes()      # returns list of classes
signup(studentID, class) # signs up a student for a class
drop(studentID, class)   # drops a student from a class
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;.. _tutorial-data-model:&lt;/p&gt; 
&lt;h2&gt;Data model&lt;/h2&gt; 
&lt;p&gt;First, we need to design a :doc:&lt;code&gt;data model &amp;lt;data-modeling&amp;gt;&lt;/code&gt;. A data model is just a method for storing our application data using keys and values in FoundationDB. We seem to have two main types of data: (1) a list of classes and (2) a record of which students will attend which classes. Let&apos;s keep attending data like this::&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;# (&apos;attends&apos;, student, class) = &apos;&apos;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;We&apos;ll just store the key with a blank value to indicate that a student is signed up for a particular class. For this application, we&apos;re going to think about a key-value pair&apos;s key as a :ref:&lt;code&gt;tuple &amp;lt;data-modeling-tuples&amp;gt;&lt;/code&gt;. Encoding a tuple of data elements into a key is a very common pattern for an ordered key-value store.&lt;/p&gt; 
&lt;p&gt;We&apos;ll keep data about classes like this::&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;# (&apos;class&apos;, class_name) = seats_available
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Similarly, each such key will represent an available class. We&apos;ll use &lt;code&gt;seats_available&lt;/code&gt; to record the number of seats available.&lt;/p&gt; 
&lt;h2&gt;Directories and Subspaces&lt;/h2&gt; 
&lt;p&gt;FoundationDB includes a few tools that make it easy to model data using this approach. Let&apos;s begin by&lt;br&gt; opening a :ref:&lt;code&gt;directory &amp;lt;developer-guide-directories&amp;gt;&lt;/code&gt; in the database::&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;import fdb
fdb.api_version(740)

db = fdb.open()
scheduling = fdb.directory.create_or_open(db, (&apos;scheduling&apos;,))
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;The :meth:&lt;code&gt;create_or_open&lt;/code&gt; method returns a :ref:&lt;code&gt;subspace &amp;lt;developer-guide-sub-keyspaces&amp;gt;&lt;/code&gt; where we&apos;ll store our application data. Each subspace has a fixed prefix it uses when defining keys. The prefix corresponds to the first element of a tuple. We decided that we wanted &lt;code&gt;&apos;attends&apos;&lt;/code&gt; and &lt;code&gt;&apos;class&apos;&lt;/code&gt; as our prefixes, so we&apos;ll create new subspaces for them within the &lt;code&gt;scheduling&lt;/code&gt; subspace.::&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;course = scheduling[&apos;class&apos;]
attends = scheduling[&apos;attends&apos;]
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Subspaces have a :meth:&lt;code&gt;pack&lt;/code&gt; method for defining keys. To store the records for our data model, we can use &lt;code&gt;attends.pack((s, c))&lt;/code&gt; and &lt;code&gt;course.pack((c,))&lt;/code&gt;.&lt;/p&gt; 
&lt;h2&gt;Transactions&lt;/h2&gt; 
&lt;p&gt;We&apos;re going to rely on the powerful guarantees of transactions to help keep all of our modifications straight, so let&apos;s look at a nice way that the FoundationDB Python API lets you write a transactional function. By using a decorator, an entire function is wrapped in a transaction. Let&apos;s write the very simple &lt;code&gt;add_class&lt;/code&gt; function we will use to populate the database&apos;s class list::&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;@fdb.transactional
def add_class(tr, c):
    tr[course.pack((c,))] = fdb.tuple.pack((100,))
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;:py:func:&lt;code&gt;@fdb.transactional &amp;lt;fdb.transactional&amp;gt;&lt;/code&gt; is a Python decorator that makes a normal function a transactional function. All functions decorated this way &lt;em&gt;need to have a parameter named&lt;/em&gt; &lt;code&gt;tr&lt;/code&gt;. This parameter is passed the transaction that the function should use to do reads and writes.&lt;/p&gt; 
&lt;p&gt;When &lt;em&gt;calling&lt;/em&gt; a transactionally decorated function, however, you can pass a database instead of a transaction for the &lt;code&gt;tr&lt;/code&gt; parameter. The decorator &lt;em&gt;automatically creates a transaction and implements a retry loop&lt;/em&gt; to ensure that the transaction eventually commits.&lt;/p&gt; 
&lt;p&gt;For a FoundationDB database &lt;code&gt;db&lt;/code&gt;::&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;add_class(db, &apos;class1&apos;)
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;is equivalent to something like::&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;tr = db.create_transaction()
while True:
    try:
        add_class(tr, &apos;class1&apos;)
        tr.commit().wait()
        break
    except fdb.FDBError as e:
        tr.on_error(e).wait()
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;If instead you pass a :class:&lt;code&gt;Transaction&lt;/code&gt; for the &lt;code&gt;tr&lt;/code&gt; parameter, the transaction will be used directly, and it is assumed that the caller implements appropriate retry logic for errors. This permits transactionally decorated functions to be composed into larger transactions.&lt;/p&gt; 
&lt;p&gt;Note that by default, the operation will be retried an infinite number of times and the transaction will never time out. It is therefore recommended that the client choose a default transaction retry limit or timeout value that is suitable for their application. This can be set either at the transaction level using the &lt;code&gt;set_retry_limit&lt;/code&gt; or &lt;code&gt;set_timeout&lt;/code&gt; transaction options or at the database level with the &lt;code&gt;set_transaction_retry_limit&lt;/code&gt; or &lt;code&gt;set_transaction_timeout&lt;/code&gt; database options. For example, one can set a one minute timeout on each transaction and a default retry limit of 100 by calling::&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;db.options.set_transaction_timeout(60000)  # 60,000 ms = 1 minute
db.options.set_transaction_retry_limit(100)
&lt;/code&gt;&lt;/pre&gt; 
&lt;h2&gt;Making some sample classes&lt;/h2&gt; 
&lt;p&gt;Let&apos;s make some sample classes and put them in the &lt;code&gt;class_names&lt;/code&gt; variable. The Python &lt;code&gt;itertools&lt;/code&gt; module is used to make individual classes from combinations of class types, levels, and times::&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;import itertools

# Generate 1,620 classes like &apos;9:00 chem for dummies&apos;
levels = [&apos;intro&apos;, &apos;for dummies&apos;, &apos;remedial&apos;, &apos;101&apos;,
          &apos;201&apos;, &apos;301&apos;, &apos;mastery&apos;, &apos;lab&apos;, &apos;seminar&apos;]
types = [&apos;chem&apos;, &apos;bio&apos;, &apos;cs&apos;, &apos;geometry&apos;, &apos;calc&apos;,
         &apos;alg&apos;, &apos;film&apos;, &apos;music&apos;, &apos;art&apos;, &apos;dance&apos;]
times = [str(h) + &apos;:00&apos; for h in range(2, 20)]
class_combos = itertools.product(times, types, levels)
class_names = [&apos; &apos;.join(tup) for tup in class_combos]
&lt;/code&gt;&lt;/pre&gt; 
&lt;h2&gt;Initializing the database&lt;/h2&gt; 
&lt;p&gt;We initialize the database with our class list::&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;@fdb.transactional
def init(tr):
    del tr[scheduling.range(())]  # Clear the directory
    for class_name in class_names:
        add_class(tr, class_name)
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;After :func:&lt;code&gt;init&lt;/code&gt; is run, the database will contain all of the sample classes we created above.&lt;/p&gt; 
&lt;h2&gt;Listing available classes&lt;/h2&gt; 
&lt;p&gt;Before students can do anything else, they need to be able to retrieve a list of available classes from the database. Because FoundationDB sorts its data by key and therefore has efficient range-read capability, we can retrieve all of the classes in a single database call. We find this range of keys with :meth:&lt;code&gt;course.range&lt;/code&gt;.::&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;@fdb.transactional
def available_classes(tr):
    return [course.unpack(k)[0] for k, v in tr[course.range(())]]
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;In general, the :meth:&lt;code&gt;Subspace.range&lt;/code&gt; method returns a Python &lt;code&gt;slice&lt;/code&gt; representing all the key-value pairs starting with the specified tuple. In this case, we want all classes, so we call :meth:&lt;code&gt;course.range&lt;/code&gt; with the empty tuple &lt;code&gt;()&lt;/code&gt;. FoundationDB&apos;s &lt;code&gt;tr[slice]&lt;/code&gt; function returns an iterable list of key-values in the range specified by the slice. We unpack the key &lt;code&gt;k&lt;/code&gt; and value &lt;code&gt;v&lt;/code&gt; in a comprehension. To extract the class name itself, we unpack the key into a tuple using the :meth:&lt;code&gt;Subspace.unpack&lt;/code&gt; method and take the first field. (The first and second parts of the tuple, the &lt;code&gt;scheduling&lt;/code&gt; and &lt;code&gt;course&lt;/code&gt; subspace prefixes, are removed by the &lt;code&gt;unpack&lt;/code&gt; hence the reason we take the first field of the tuple.)&lt;/p&gt; 
&lt;h2&gt;Signing up for a class&lt;/h2&gt; 
&lt;p&gt;We finally get to the crucial function. A student has decided on a class (by name) and wants to sign up. The &lt;code&gt;signup&lt;/code&gt; function will take a student (&lt;code&gt;s&lt;/code&gt;) and a class (&lt;code&gt;c&lt;/code&gt;)::&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;@fdb.transactional
def signup(tr, s, c):
    rec = attends.pack((s, c))
    tr[rec] = b&apos;&apos;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;We simply insert the appropriate record (with a blank value).&lt;/p&gt; 
&lt;h2&gt;Dropping a class&lt;/h2&gt; 
&lt;p&gt;Dropping a class is similar to signing up::&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;@fdb.transactional
def drop(tr, s, c):
    rec = attends.pack((s, c))
    del tr[rec]
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Of course, to actually drop the student from the class, we need to be able to delete a record from the database. We do this with the &lt;code&gt;del tr[key]&lt;/code&gt; syntax.&lt;/p&gt; 
&lt;h2&gt;Done?&lt;/h2&gt; 
&lt;p&gt;We report back to the project leader that our application is done---students can sign up for, drop, and list classes. Unfortunately, we learn that a new problem has been discovered: popular classes are being over-subscribed. Our application now needs to enforce the class size constraint as students add and drop classes.&lt;/p&gt; 
&lt;h2&gt;Seats are limited!&lt;/h2&gt; 
&lt;p&gt;Let&apos;s go back to the data model. Remember that we stored the number of seats in the class in the value of the key-value entry in the class list. Let&apos;s refine that a bit to track the &lt;em&gt;remaining&lt;/em&gt; number of seats in the class. The initialization can work the same way. (In our example, all classes initially have 100 seats), but the &lt;code&gt;available_classes&lt;/code&gt;, &lt;code&gt;signup&lt;/code&gt;, and &lt;code&gt;drop&lt;/code&gt; functions are going to have to change. Let&apos;s start with &lt;code&gt;available_classes&lt;/code&gt;:&lt;/p&gt; 
&lt;p&gt;.. code-block:: python&lt;br&gt; :emphasize-lines: 4&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;@fdb.transactional
def available_classes(tr):
    return [course.unpack(k)[0] for k, v in tr[course.range(())]
            if fdb.tuple.unpack(v)[0]]
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;This is easy -- we simply add a condition to check that the value is non-zero. Let&apos;s check out &lt;code&gt;signup&lt;/code&gt; next:&lt;/p&gt; 
&lt;p&gt;.. code-block:: python&lt;br&gt; :emphasize-lines: 4,5,6,7,8,9&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;@fdb.transactional
def signup(tr, s, c):
    rec = attends.pack((s, c))
    if tr[rec].present(): return  # already signed up

    seats_left = fdb.tuple.unpack(tr[course.pack((c,))])[0]
    if not seats_left: raise Exception(&apos;No remaining seats&apos;)

    tr[course.pack((c,))] = fdb.tuple.pack((seats_left - 1,))
    tr[rec] = b&apos;&apos;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;We now have to check that we aren&apos;t already signed up, since we don&apos;t want a double sign up to decrease the number of seats twice. Then we look up how many seats are left to make sure there is a seat remaining so we don&apos;t push the counter into the negative. If there is a seat remaining, we decrement the counter.&lt;/p&gt; 
&lt;p&gt;Similarly, the &lt;code&gt;drop&lt;/code&gt; function is modified as follows:&lt;/p&gt; 
&lt;p&gt;.. code-block:: python&lt;br&gt; :emphasize-lines: 4,5&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;@fdb.transactional
def drop(tr, s, c):
    rec = attends.pack((s, c))
    if not tr[rec].present(): return  # not taking this class
    tr[course.pack((c,))] = fdb.tuple.pack((fdb.tuple.unpack(tr[course.pack((c,))])[0] + 1,))
    del tr[rec]
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Once again we check to see if the student is signed up and if not, we can just return as we don&apos;t want to incorrectly increase the number of seats. We then adjust the number of seats by one by taking the current value, incrementing it by one, and then storing back.&lt;/p&gt; 
&lt;h2&gt;Concurrency and consistency&lt;/h2&gt; 
&lt;p&gt;The &lt;code&gt;signup&lt;/code&gt; function is starting to get a bit complex; it now reads and writes a few different key-value pairs in the database. One of the tricky issues in this situation is what happens as multiple clients/students read and modify the database at the same time. Couldn&apos;t two students both see one remaining seat and sign up at the same time?&lt;/p&gt; 
&lt;p&gt;These are tricky issues without simple answers---unless you have transactions! Because these functions are defined as FoundationDB transactions, we can have a simple answer: Each transactional function behaves as if it is the only one modifying the database. There is no way for a transaction to &apos;see&apos; another transaction change the database, and each transaction ensures that either all of its modifications occur or none of them do.&lt;/p&gt; 
&lt;p&gt;Looking deeper, it is, of course, possible for two transactions to conflict. For example, if two people both see a class with one seat and sign up at the same time, FoundationDB must allow only one to succeed. This causes one of the transactions to fail to commit (which can also be caused by network outages, crashes, etc.). To ensure correct operation, applications need to handle this situation, usually via retrying the transaction. In this case, the conflicting transaction will be retried automatically by the &lt;code&gt;@fdb.transactional&lt;/code&gt; decorator and will eventually lead to the correct result, a &apos;No remaining seats&apos; exception.&lt;/p&gt; 
&lt;h2&gt;Idempotence&lt;/h2&gt; 
&lt;p&gt;Occasionally, a transaction might be retried even after it succeeds (for example, if the client loses contact with the cluster at just the wrong moment). This can cause problems if transactions are not written to be idempotent, i.e. to have the same effect if committed twice as if committed once. There are generic design patterns for :ref:&lt;code&gt;making any transaction idempotent &amp;lt;developer-guide-unknown-results&amp;gt;&lt;/code&gt;, but many transactions are naturally idempotent. For example, all of the transactions in this tutorial are idempotent.&lt;/p&gt; 
&lt;h2&gt;More features?!&lt;/h2&gt; 
&lt;p&gt;Of course, as soon as our new version of the system goes live, we hear of a trick that certain students are using. They are signing up for all classes immediately, and only later dropping those that they don&apos;t want to take. This has led to an unusable system, and we have been asked to fix it. We decide to limit students to five classes:&lt;/p&gt; 
&lt;p&gt;.. code-block:: python&lt;br&gt; :emphasize-lines: 9,10&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;@fdb.transactional
def signup(tr, s, c):
    rec = attends.pack((s, c))
    if tr[rec].present(): return  # already signed up

    seats_left = fdb.tuple.unpack(tr[course.pack((c,))])[0]
    if not seats_left: raise Exception(&apos;No remaining seats&apos;)

    classes = tr[attends.range((s,))]
    if len(list(classes)) == 5: raise Exception(&apos;Too many classes&apos;)

    tr[course.pack((c,))] = fdb.tuple.pack((seats_left - 1,))
    tr[rec] = b&apos;&apos;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Fortunately, we decided on a data model that keeps all of the attending records for a single student together. With this approach, we can use a single range read in the &lt;code&gt;attends&lt;/code&gt; subspace to retrieve all the classes that a student is signed up for. We simply throw an exception if the number of classes has reached the limit of five.&lt;/p&gt; 
&lt;h2&gt;Composing transactions&lt;/h2&gt; 
&lt;p&gt;Oh, just one last feature, we&apos;re told. We have students that are trying to switch from one popular class to another. By the time they drop one class to free up a slot for themselves, the open slot in the other class is gone. By the time they see this and try to re-add their old class, that slot is gone too! So, can we make it so that a student can switch from one class to another without this worry?&lt;/p&gt; 
&lt;p&gt;Fortunately, we have FoundationDB, and this sounds an awful lot like the transactional property of atomicity---the all-or-nothing behavior that we already rely on. All we need to do is to &lt;em&gt;compose&lt;/em&gt; the &lt;code&gt;drop&lt;/code&gt; and &lt;code&gt;signup&lt;/code&gt; functions into a new &lt;code&gt;switch&lt;/code&gt; function. This makes the &lt;code&gt;switch&lt;/code&gt; function exceptionally easy::&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;@fdb.transactional
def switch(tr, s, old_c, new_c):
    drop(tr, s, old_c)
    signup(tr, s, new_c)
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;The simplicity of this implementation belies the sophistication of what FoundationDB is taking care of for us.&lt;/p&gt; 
&lt;p&gt;By dropping the old class and signing up for the new one inside a single transaction, we ensure that either both steps happen, or that neither happens. The first notable thing about the &lt;code&gt;switch&lt;/code&gt; function is that it is transactionally decorated, but it also calls the transactionally decorated functions &lt;code&gt;signup&lt;/code&gt; and &lt;code&gt;drop&lt;/code&gt;. Because these decorated functions can accept either a database or an existing transaction as the &lt;code&gt;tr&lt;/code&gt; argument, the switch function can be called with a database by a simple client, and a new transaction will be automatically created. However, once this transaction is created and passed in as &lt;code&gt;tr&lt;/code&gt;, the calls to &lt;code&gt;drop&lt;/code&gt; and &lt;code&gt;signup&lt;/code&gt; both share the same &lt;code&gt;tr&lt;/code&gt;. This ensures that they see each other&apos;s modifications to the database, and all of the changes that both of them make in sequence are made transactionally when the switch function returns. This compositional capability is very powerful.&lt;/p&gt; 
&lt;p&gt;Also note that, if an exception is raised, for example, in &lt;code&gt;signup&lt;/code&gt;, the exception is not caught by &lt;code&gt;switch&lt;/code&gt; and so will be thrown to the calling function. In this case, the transaction object (owned by the decorator) is destroyed, automatically rolling back all database modifications, leaving the database completely unchanged by the half-executed function.&lt;/p&gt; 
&lt;h2&gt;Are we done?&lt;/h2&gt; 
&lt;p&gt;Yep, we’re done and ready to deploy. If you want to see this entire application in one place plus some multithreaded testing code to simulate concurrency, look at the :ref:&lt;code&gt;tutorial-appendix&lt;/code&gt;, below.&lt;/p&gt; 
&lt;h2&gt;Deploying and scaling&lt;/h2&gt; 
&lt;p&gt;Since we store all state for this application in FoundationDB, deploying and scaling this solution up is impressively painless. Just run a web server, the UI, this back end, and point the whole thing at FoundationDB. We can run as many computers with this setup as we want, and they can all hit the database at the same time because of the transactional integrity of FoundationDB. Also, since all of the state in the system is stored in the database, any of these computers can fail without any lasting consequences.&lt;/p&gt; 
&lt;h1&gt;Next steps&lt;/h1&gt; 
&lt;ul&gt; 
 &lt;li&gt;See :doc:&lt;code&gt;data-modeling&lt;/code&gt; for guidance on using tuple and subspaces to enable effective storage and retrieval of data.&lt;/li&gt; 
 &lt;li&gt;See :doc:&lt;code&gt;developer-guide&lt;/code&gt; for general guidance on development using FoundationDB.&lt;/li&gt; 
 &lt;li&gt;See the :doc:&lt;code&gt;API References &amp;lt;api-reference&amp;gt;&lt;/code&gt; for detailed API documentation.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;.. _tutorial-appendix:&lt;/p&gt; 
&lt;h1&gt;Appendix: SchedulingTutorial.py&lt;/h1&gt; 
&lt;p&gt;Here&apos;s the code for the scheduling tutorial::&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;import itertools
import traceback

import fdb
import fdb.tuple

fdb.api_version(740)


####################################
##        Initialization          ##
####################################

# Data model:
# (&apos;attends&apos;, student, class) = &apos;&apos;
# (&apos;class&apos;, class_name) = seats_left

db = fdb.open()
db.options.set_transaction_timeout(60000)  # 60,000 ms = 1 minute
db.options.set_transaction_retry_limit(100)
scheduling = fdb.directory.create_or_open(db, (&apos;scheduling&apos;,))
course = scheduling[&apos;class&apos;]
attends = scheduling[&apos;attends&apos;]

@fdb.transactional
def add_class(tr, c):
    tr[course.pack((c,))] = fdb.tuple.pack((100,))

# Generate 1,620 classes like &apos;9:00 chem for dummies&apos;
levels = [&apos;intro&apos;, &apos;for dummies&apos;, &apos;remedial&apos;, &apos;101&apos;,
          &apos;201&apos;, &apos;301&apos;, &apos;mastery&apos;, &apos;lab&apos;, &apos;seminar&apos;]
types = [&apos;chem&apos;, &apos;bio&apos;, &apos;cs&apos;, &apos;geometry&apos;, &apos;calc&apos;,
         &apos;alg&apos;, &apos;film&apos;, &apos;music&apos;, &apos;art&apos;, &apos;dance&apos;]
times = [str(h) + &apos;:00&apos; for h in range(2, 20)]
class_combos = itertools.product(times, types, levels)
class_names = [&apos; &apos;.join(tup) for tup in class_combos]

@fdb.transactional
def init(tr):
    del tr[scheduling.range(())]  # Clear the directory
    for class_name in class_names:
        add_class(tr, class_name)


####################################
##  Class Scheduling Functions    ##
####################################


@fdb.transactional
def available_classes(tr):
    return [course.unpack(k)[0] for k, v in tr[course.range(())]
            if fdb.tuple.unpack(v)[0]]


@fdb.transactional
def signup(tr, s, c):
    rec = attends.pack((s, c))
    if tr[rec].present(): return  # already signed up

    seats_left = fdb.tuple.unpack(tr[course.pack((c,))])[0]
    if not seats_left: raise Exception(&apos;No remaining seats&apos;)

    classes = tr[attends.range((s,))]
    if len(list(classes)) == 5: raise Exception(&apos;Too many classes&apos;)

    tr[course.pack((c,))] = fdb.tuple.pack((seats_left - 1,))
    tr[rec] = b&apos;&apos;


@fdb.transactional
def drop(tr, s, c):
    rec = attends.pack((s, c))
    if not tr[rec].present(): return  # not taking this class
    tr[course.pack((c,))] = fdb.tuple.pack((fdb.tuple.unpack(tr[course.pack((c,))])[0] + 1,))
    del tr[rec]


@fdb.transactional
def switch(tr, s, old_c, new_c):
    drop(tr, s, old_c)
    signup(tr, s, new_c)

####################################
##           Testing              ##
####################################

import random
import threading

def indecisive_student(i, ops):
    student_ID = &apos;s{:d}&apos;.format(i)
    all_classes = class_names
    my_classes = []

    for i in range(ops):
        class_count = len(my_classes)
        moods = []
        if class_count: moods.extend([&apos;drop&apos;, &apos;switch&apos;])
        if class_count &amp;lt; 5: moods.append(&apos;add&apos;)
        mood = random.choice(moods)

        try:
            if not all_classes:
                all_classes = available_classes(db)
            if mood == &apos;add&apos;:
                c = random.choice(all_classes)
                signup(db, student_ID, c)
                my_classes.append(c)
            elif mood == &apos;drop&apos;:
                c = random.choice(my_classes)
                drop(db, student_ID, c)
                my_classes.remove(c)
            elif mood == &apos;switch&apos;:
                old_c = random.choice(my_classes)
                new_c = random.choice(all_classes)
                switch(db, student_ID, old_c, new_c)
                my_classes.remove(old_c)
                my_classes.append(new_c)
        except Exception as e:
            traceback.print_exc()
            print(&quot;Need to recheck available classes.&quot;)
            all_classes = []

def run(students, ops_per_student):
    threads = [
        threading.Thread(target=indecisive_student, args=(i, ops_per_student))
        for i in range(students)]
    for thr in threads: thr.start()
    for thr in threads: thr.join()
    print(&quot;Ran {} transactions&quot;.format(students * ops_per_student))

if __name__ == &quot;__main__&quot;:
    init(db)
    print(&quot;initialized&quot;)
    run(10, 10)
&lt;/code&gt;&lt;/pre&gt;
	</description>
    </item>
    <item>
      <title>Harbour</title>
      <link>https://tedneward.github.io/Research/storage/harbour/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/harbour/index.html</guid>
      	<description>
	&lt;p&gt;Harbour consists of a compiler and runtime libraries with multiple UI and database backends, its own make system and a large collection of libraries and interfaces to many popular APIs.&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://harbour.github.io/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/harbour/core&quot;&gt;Source&lt;/a&gt; | &lt;a href=&quot;https://harbour.wiki/&quot;&gt;Wiki&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Last stable release (3.0.0), in 2011.&lt;/p&gt; 
&lt;p&gt;Transpiles to C, but also has a runtime that can execute embedded code/instructions (&quot;PCODE&quot;), which can be either in a binary format or a source format.&lt;/p&gt; 
&lt;h2&gt;FAQ&lt;/h2&gt; 
&lt;h4&gt;What is Harbour?&lt;/h4&gt; 
&lt;p&gt;Harbour is an open-source implementation of a xBase computer language, that is compatible on any platforms supporting C based applications, meaning MS Windows, Mac OS, Linux, Unix, iOS, and can generate 32-bit and 64-bit applications and libraries.&lt;br&gt; xBase is the generic term for all programming languages that derive from the original dBASE programming language and database formats (&lt;a href=&quot;https://en.wikipedia.org/wiki/XBase&quot;&gt;https://en.wikipedia.org/wiki/XBase&lt;/a&gt;) that was first released in 1979. Harbour is classified as a 4GL language since its compiler generates pure C source code. Harbour-generated applications are self-contained, meaning they do not require external runtime libraries. Harbour programs can be compiled to use an embedded VM (virtual machine including in final EXE), or without any VM (could run faster but bigger executable). Harbour has an embedded “stand-by” compiler that is similar to VFP’s macros.&lt;br&gt; Harbour can be classified as an object-oriented, functional and data-centric language that also supports procedures and functions. Harbour can also generate multi-threaded applications, such as web and socket servers. Virtually any C libraries can be embedded with Harbour.&lt;/p&gt; 
&lt;h4&gt;Where does it come from?&lt;/h4&gt; 
&lt;p&gt;The original Harbour implementation was started in 1999 as a 100% clone of Clipper, a defunct language that was a compiler version of dBase. During the last 20 years, Harbour went through majors changes, in part due to a forked version called xHarbour. Most features of xHarbour, a commercial fork, are now re-implemented in Harbour, for the exception of a form builder (closer to FoxPro for Windows than VFP). Most of the development of Harbour was done by a handful of extremely skilled C developers. All the source code and contributor information can be found on GitHub at &lt;a href=&quot;https://github.com/harbour/core&quot;&gt;https://github.com/harbour/core&lt;/a&gt;&lt;/p&gt; 
&lt;h4&gt;What could Harbour be used for?&lt;/h4&gt; 
&lt;p&gt;Since Harbour generates pure C code and has a powerful preprocessor, any other C code and libraries can be merged in. You can even write C code inside your PRG files.&lt;/p&gt; 
&lt;p&gt;Harbour can be used to create Desktop apps, Web apps, COM objects (32-bit and 64-bit), and device-drivers. I even saw someone compile Harbour with Objective-C and create a native iOS app, and another person created a WebAssembly.&lt;/p&gt; 
&lt;h4&gt;How does Harbour work?&lt;/h4&gt; 
&lt;p&gt;Harbour is a language and a series of tools. Its syntax is originally from Clipper but has evolved to include all other modern language features like OOP, Hash Arrays (Python Dictionaries), UTF8 support, multi-threading, multi-OS support. Harbour has its root in C, which means that most of the C tooling is also in Harbour. It has a preprocessor, a compiler, a make tool (optional) and a debugger (replaceable). It does not have a CLI, but Visual Code can be used to facilitate rapid prototyping and debugging.&lt;/p&gt; 
&lt;h2&gt;Examples&lt;/h2&gt; 
&lt;p&gt;Hello world&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;// Typical welcome message

PROCEDURE Main()

   ? &quot;Hello, world!&quot;

   RETURN
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Interesting example using two (!) console windows simultaneously&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;/*
 * demonstration/test code for using more then one console window.
 *    It needs GT driver which supports such functionality, i.e.
 *    GTWVT in MS-Windows or GTXWC in XWindow.
 *
 * Copyright 2008 Przemyslaw Czerpak &amp;lt;druzus / at / priv.onet.pl&amp;gt;
 *
 */

#include &quot;box.ch&quot;

#ifdef __PLATFORM__WINDOWS
   #if ! defined( __HBSCRIPT__HBSHELL )
      REQUEST HB_GT_WVT_DEFAULT
   #endif
   #define THREAD_GT &quot;WVT&quot;
#else
   REQUEST HB_GT_STD_DEFAULT
   #define THREAD_GT &quot;XWC&quot;
#endif

proc main()
   local pGT, pGT1, pGT2

#if defined( __HBSCRIPT__HBSHELL )
   #if defined( __PLATFORM__WINDOWS )
      hbshell_gtSelect( &quot;GTWVT&quot; )
   #elif defined( __PLATFORM__UNIX )
      hbshell_gtSelect( &quot;GTXWC&quot; )
   #endif
#endif

   ? &quot;This is small test for using more then one console window.&quot;
   ? &quot;It needs GT which supports such functionality i.e. GTWVT in&quot;
   ? &quot;MS-Windows or GTXWC in XWindow&quot;
   wait

   ? &quot;Create two new GTs:&quot;
   pGT1 := hb_gtCreate( THREAD_GT )
   ? &quot;1 =&amp;gt;&quot;, pGT1
   pGT2 := hb_gtCreate( THREAD_GT )
   ? &quot;2 =&amp;gt;&quot;, pGT1

   pGT := hb_gtSelect( pGT1 )
   SetColor( &quot;W+/R&quot; )
   DispBox( 10, 10, 20, 50, HB_B_DOUBLE_UNI + &quot; &quot; )
   ?? &quot;This test is shown in 1-st GT window&quot;

   hb_gtSelect( pGT2 )
   SetColor( &quot;W+/B&quot; )
   DispBox( 15, 30, 20, 70, HB_B_DOUBLE_UNI + &quot; &quot; )
   ?? &quot;This test is shown in 2-nd GT window&quot;

   hb_gtSelect( pGT )
   ? &quot;New console window should be visible now&quot;
   wait

   ? &quot;Destroy 1-st window...&quot;
   pGT1 := NIL
   ?? &quot;done&quot;
   wait

   ? &quot;Destroy 2-nd window...&quot;
   pGT2 := NIL
   ?? &quot;done&quot;

   wait &quot;Press any key to exit&quot;

return
&lt;/code&gt;&lt;/pre&gt; 
&lt;h2&gt;Other sources&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://harbour.wiki/&quot;&gt;Wiki&lt;/a&gt;: A collection of articles on Harbour and surrounds&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>iBoxDB</title>
      <link>https://tedneward.github.io/Research/storage/iboxdb/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/iboxdb/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://iboxdb.github.io/index.html&quot;&gt;Website&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;No source?&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>InfluxDB</title>
      <link>https://tedneward.github.io/Research/storage/influxdb/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/influxdb/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.influxdata.com/&quot;&gt;Website&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>JavaScript Database (JSDB)</title>
      <link>https://tedneward.github.io/Research/storage/jsdb/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/jsdb/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/small-tech/jsdb&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;From the README:&lt;/p&gt; 
&lt;h4&gt;Use case&lt;/h4&gt; 
&lt;p&gt;A small and simple data layer for basic persistence and querying. Built for us in Small Web places and used in Site.js and Place.&lt;/p&gt; 
&lt;h4&gt;Features&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt; &lt;p&gt;Transparent: if you know how to work with arrays and objects and call methods in JavaScript, you already know how to use JSDB? It’s not called JavaScript Database for nothing.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Automatic: it just works. No configuration.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;100% code coverage: meticulously tested. Note that this does not mean it is bug free ;)&lt;/p&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Limitations&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt; &lt;p&gt;Small Data: this is for small data, not Big Data™.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;For Node.js: will not work in the browser. (Although data tables are plain ECMAScript Modules (ESM; es6 modules) and can be loaded in the browser.)&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Runs on untrusted nodes: this is for data kept on untrusted nodes (servers). Use it judiciously if you must for public data, configuration data, etc. If you want to store personal data or model human communication, consider end-to-end encrypted and peer-to-peer replicating data structures instead to protect privacy and freedom of speech. Keep an eye on the work taking place around the Hypercore Protocol.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;In-memory: all data is kept in memory and, without tweaks, cannot exceed 1.4GB in size. While JSDB will work with large datasets, that’s not its primary purpose and it’s definitely not here to help you farm people for their data, so please don’t use it for that. (If that’s what you want, quite literally every other database out there is for your use case so please use one of those instead.)&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Streaming writes on update: writes are streamed to disk to an append-only transaction log as JavaScript statements and are both quick (in the single-digit miliseconds region on a development laptop with an SSD drive) and as safe as we can make them (synchronous at the kernel level).&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;No schema, no migrations: again, this is meant to be a very simple persistence, query, and observation layer for local server-side data. If you want schemas and migrations, take a look at nearly every other database out there.&lt;/p&gt; &lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Keyv</title>
      <link>https://tedneward.github.io/Research/storage/keyv/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/keyv/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/jaredwray/keyv&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Install Keyv: &lt;code&gt;npm install --save keyv&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;By default everything is stored in memory, you can optionally also install a storage adapter.&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;npm install --save @keyv/redis
npm install --save @keyv/mongo
npm install --save @keyv/sqlite
npm install --save @keyv/postgres
npm install --save @keyv/mysql
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Create a new Keyv instance, passing your connection string if applicable. Keyv will automatically load the correct storage adapter.&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;const Keyv = require(&apos;keyv&apos;);

// One of the following
const keyv = new Keyv();
const keyv = new Keyv(&apos;redis://user:pass@localhost:6379&apos;);
const keyv = new Keyv(&apos;mongodb://user:pass@localhost:27017/dbname&apos;);
const keyv = new Keyv(&apos;sqlite://path/to/database.sqlite&apos;);
const keyv = new Keyv(&apos;postgresql://user:pass@localhost:5432/dbname&apos;);
const keyv = new Keyv(&apos;mysql://user:pass@localhost:3306/dbname&apos;);

// Handle DB connection errors
keyv.on(&apos;error&apos;, err =&amp;gt; console.log(&apos;Connection Error&apos;, err));

await keyv.set(&apos;foo&apos;, &apos;expires in 1 second&apos;, 1000); // true
await keyv.set(&apos;foo&apos;, &apos;never expires&apos;); // true
await keyv.get(&apos;foo&apos;); // &apos;never expires&apos;
await keyv.delete(&apos;foo&apos;); // true
await keyv.clear(); // undefined
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;You can namespace your Keyv instance to avoid key collisions and allow you to clear only a certain namespace while using the same database.&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;const users = new Keyv(&apos;redis://user:pass@localhost:6379&apos;, { namespace: &apos;users&apos; });
const cache = new Keyv(&apos;redis://user:pass@localhost:6379&apos;, { namespace: &apos;cache&apos; });

await users.set(&apos;foo&apos;, &apos;users&apos;); // true
await cache.set(&apos;foo&apos;, &apos;cache&apos;); // true
await users.get(&apos;foo&apos;); // &apos;users&apos;
await cache.get(&apos;foo&apos;); // &apos;cache&apos;
await users.clear(); // undefined
await users.get(&apos;foo&apos;); // undefined
await cache.get(&apos;foo&apos;); // &apos;cache&apos;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;You can also use third-party storage adapters or build your own. Keyv will wrap these storage adapters in TTL functionality and handle complex types internally.&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;const Keyv = require(&apos;keyv&apos;);
const myAdapter = require(&apos;./my-storage-adapter&apos;);

const keyv = new Keyv({ store: myAdapter });
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Any store that follows the Map api will work.&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;new Keyv({ store: new Map() });
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;For example, quick-lru is a completely unrelated module that implements the Map API.&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;const Keyv = require(&apos;keyv&apos;);
const QuickLRU = require(&apos;quick-lru&apos;);

const lru = new QuickLRU({ maxSize: 1000 });
const keyv = new Keyv({ store: lru });
&lt;/code&gt;&lt;/pre&gt;
	</description>
    </item>
    <item>
      <title>LevelDB</title>
      <link>https://tedneward.github.io/Research/storage/leveldb/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/leveldb/index.html</guid>
      	<description>
	&lt;p&gt;You are probably using LevelDB without knowing it since it&apos;s part of the Chrome browser (exposed as &lt;a href=&quot;indexeddb.html&quot;&gt;IndexedDB&lt;/a&gt;). If we compare it to Redis, it&apos;s even lighter, has more reliable writes and, unlike Redis, you don&apos;t store your entire data in memory but in the file system. Another difference is Redis has more data structures (sets, lists, etc.) that LevelDB is lacking. The similarity is that both store key-value pairs and both can save JSON. C/C++ library.&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://github.com/google/leveldb&quot;&gt;Github&lt;/a&gt; | &lt;a href=&quot;https://github.com/google/leveldb/blob/master/doc/index.md&quot;&gt;Documentation&lt;/a&gt; is bundled with the source&lt;/p&gt; 
&lt;h2&gt;Features and limitations&lt;/h2&gt; 
&lt;p&gt;Keys and values are arbitrary byte arrays.&lt;/p&gt; 
&lt;p&gt;Data is stored sorted by key.&lt;/p&gt; 
&lt;p&gt;Callers can provide a custom comparison function to override the sort order.&lt;/p&gt; 
&lt;p&gt;The basic operations are Put(key,value), Get(key), Delete(key).&lt;/p&gt; 
&lt;p&gt;Multiple changes can be made in one atomic batch.&lt;/p&gt; 
&lt;p&gt;Users can create a transient snapshot to get a consistent view of data.&lt;/p&gt; 
&lt;p&gt;Forward and backward iteration is supported over the data.&lt;/p&gt; 
&lt;p&gt;Data is automatically compressed using the Snappy compression library.&lt;/p&gt; 
&lt;p&gt;External activity (file system operations etc.) is relayed through a virtual interface so users can customize the operating system interactions.&lt;/p&gt; 
&lt;p&gt;This is not a SQL database. It does not have a relational data model, it does not support SQL queries, and it has no support for indexes.&lt;/p&gt; 
&lt;p&gt;Only a single process (possibly multi-threaded) can access a particular database at a time.&lt;/p&gt; 
&lt;p&gt;There is no client-server support builtin to the library. An application that needs such support will have to wrap their own server around the library.&lt;/p&gt; 
&lt;p&gt;What situations is it good for?&lt;br&gt; * Whenever you need an easy way to persist data without worrying about RAM but with speed very close to memory access&lt;br&gt; * Smartphones, Raspberry Pi or similar small device&lt;br&gt; * Offline web apps - if you use LevelDB on the server you might be able to use the same code for the browser storage (&lt;a href=&quot;indexeddb.html&quot;&gt;IndexedDB&lt;/a&gt;)&lt;br&gt; * Building block for a database. LevelDB (or a variant) is used in BigTable, Hadoop’s HBase, Cassandra and Riak.&lt;/p&gt; 
&lt;h3&gt;Example (in NodeJS)&lt;/h3&gt; 
&lt;p&gt;&lt;code&gt;npm install [levelup](https://www.npmjs.com/package/levelup)&lt;/code&gt;: most popular node package for LevelDB&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;var levelup = require(&apos;levelup&apos;)
var db = levelup(&apos;./mydb&apos;)

db.put(&apos;post!&apos; + Date.now(), {author: &apos;fred&apos;, title: &apos;Angular&apos;, content: &apos;&amp;lt;p&amp;gt; bla bla bla &amp;lt;/p&amp;gt;&apos;}, {encoding:&apos;json&apos;}, function (err) {
  if (err) return console.log(&apos;Ooops!&apos;, err) // some kind of I/O error

  db.put(&apos;post!&apos; + Date.now(), {author: &apos;fred&apos;, title: &apos;Responsive Design&apos;, content: &apos;&amp;lt;p&amp;gt; blu blu blu &amp;lt;/p&amp;gt;&apos;}, {encoding:&apos;json&apos;}, function (err) {
    if (err) return console.log(&apos;Ooops!&apos;, err) // some kind of I/O error

    // to get a stream of all posts in reverse chronological order
    db.createReadStream({ reverse: true, encoding: &apos;json&apos; })
     .on(&apos;data&apos;, function (data) {
        console.log(data.key, &apos;=&apos;, data.value)
      })
      .on(&apos;error&apos;, function (err) {
        console.log(&apos;Oh my!&apos;, err)
      })
      .on(&apos;close&apos;, function () {
        console.log(&apos;Stream closed&apos;)
      })
      .on(&apos;end&apos;, function () {
        console.log(&apos;Stream ended&apos;)
      })
  })
});
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;API is very simple (basic CRUD ops). Keys must be unique, hence the use of Date.now() (which returns a ridiculous number of seconds representing now); keys are strings.&lt;/p&gt; 
&lt;h2&gt;Resources&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;Podcast episode about LevelDB - &lt;a href=&quot;http://nodeup.com/fortyone&quot;&gt;http://nodeup.com/fortyone&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;Blog post about LevelDB Internals - &lt;a href=&quot;http://www.igvita.com/2012/02/06/sstable-and-log-structured-storage-leveldb/&quot;&gt;http://www.igvita.com/2012/02/06/sstable-and-log-structured-storage-leveldb/&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;Slides by the creator of LevelUp - Rod Vagg - &lt;a href=&quot;http://rvagg.github.com/presentations/nodejsdub/#/&quot;&gt;http://rvagg.github.com/presentations/nodejsdub/#/&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;GUI for LevelDB, built by Paolo Fragomeni - &lt;a href=&quot;https://github.com/hij1nx/levelweb&quot;&gt;https://github.com/hij1nx/levelweb&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>LokiJS</title>
      <link>https://tedneward.github.io/Research/storage/lokijs/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/lokijs/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;http://techfort.github.io/LokiJS/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/techfort/LokiJS&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;LokiJS is a document oriented database written in javascript, published under MIT License. Its purpose is to store javascript objects as documents in a nosql fashion and retrieve them with a similar mechanism. Runs in node (including cordova/phonegap and node-webkit), nativescript and the browser. LokiJS is ideal for the following scenarios:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;client-side in-memory db is ideal (e.g., a session store)&lt;/li&gt; 
 &lt;li&gt;performance critical applications&lt;/li&gt; 
 &lt;li&gt;cordova/phonegap mobile apps where you can leverage the power of javascript and avoid interacting with native databases&lt;/li&gt; 
 &lt;li&gt;data sets loaded into a browser page and synchronised at the end of the work session&lt;/li&gt; 
 &lt;li&gt;node-webkit desktop apps&lt;/li&gt; 
 &lt;li&gt;nativescript mobile apps that mix the power and ubiquity of javascript with native performance and ui&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;LokiJS supports indexing and views and achieves high-performance through maintaining unique and binary indexes (indices) for data.&lt;/p&gt; 
&lt;p&gt;If you&apos;re working in a node.js environment, run &lt;code&gt;npm install lokijs&lt;/code&gt; and make sure to call &lt;code&gt;var loki = require(&apos;lokijs&apos;)&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;Creating the db:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;var db = new loki(&apos;Example&apos;);
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Create a collection, specifying name, Type, index fields and whether the collection is transactional:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;var users = db.addCollection(&apos;users&apos;, { indices: [&apos;email&apos;] });
// note that indices can be a single string or an array of strings
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Note that indexes and transactional flag are optional parameters. Transactions in LokiJS simply allow you to run operations and automatically restore the database to the stage it was before the beginning of the transaction if an error occurred.&lt;/p&gt; 
&lt;p&gt;Add a bunch of users in the database:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;var odin = users.insert( { name : &apos;odin&apos;, email: &apos;odin.soap@lokijs.org&apos;, age: 38 } );
var thor = users.insert( { name : &apos;thor&apos;, email : &apos;thor.soap@lokijs.org&apos;, age: 25 } );
var stan = users.insert( { name : &apos;stan&apos;, email : &apos;stan.soap@lokijs.org&apos;, age: 29 } );
var oliver = users.insert( { name : &apos;oliver&apos;, email : &apos;oliver.soap@lokijs.org&apos;, age: 31 } );
var hector = users.insert( { name : &apos;hector&apos;, email : &apos;hector.soap@lokijs.org&apos;, age: 15} );
var achilles = users.insert( { name : &apos;achilles&apos;, email : &apos;achilles.soap@lokijs.org&apos;, age: 31 } );
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Operate an update:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;stan.name = &apos;Stan Laurel&apos;;
// update object (this really only syncs the index)
users.update(stan);
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;DynamicViews (recommended approach):&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;var dv = users.addDynamicView(&apos;a_complex_view&apos;);
dv.applyWhere(function aCustomFilter(obj){
  return obj.name.length  &amp;lt; 5 &amp;amp;&amp;amp; obj.age &amp;gt; 30;
});
//view the data
console.log(dv.data());

// apply some changes
users.insert({ name: &apos;ratatosk&apos;, email: &apos;rata@tosk.r&apos;, age: 10320 });
// behold the dynamicview updating itself by inspecting the data
console.log(dv.data());
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;&apos;Where&apos; filter functions:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;function ageView(obj){
  return obj.age &amp;gt; 30;
}
// a little more complicated, users with names longer than 3 characters and age over 30
function aCustomFilter(obj){
  return obj.name.length  &amp;lt; 5 &amp;amp;&amp;amp; obj.age &amp;gt; 30;
}

// test the filters
var result = users.where(ageView);
var anotherResult = users.where(aCustomFilter);
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Map Reduce (live example on lokijs.org ):&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;function getDuration( obj ){
  return obj.complete ? null : obj.duration;
}


function getAverage( array ){
  var cumulator = 0;
  var i = array.length &amp;gt;&amp;gt;&amp;gt; 0;
  var actual = 0;
  while(i--){
    if(array[i] != null){
      cumulator += array[i];
      actual++;
    }
  }
  return ( cumulator / actual).toFixed(2);
}

var avgDuration = todos.mapReduce( getDuration, getAverage );
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Querying via method chaining :&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;users.chain()
  .find({&apos;age&apos;:{&apos;$gt&apos;: 25}})
  .where(function(obj){ return obj.name.indexOf(&quot;in&quot;) != -1 })
  .simplesort(&quot;age&quot;)
  .offset(50)
  .limit(10)
  .data()
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Simple named transform :&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;users.addTransform(&apos;progeny&apos;, [
  {
    type: &apos;find&apos;,
    value: {
      &apos;age&apos;: {&apos;$lte&apos;: 40}
    }
  },
  {
    type: &apos;simplesort&apos;,
    property: &apos;age&apos;,
    desc: true
  }
]);

var results = users.chain(&apos;progeny&apos;).data();
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;&lt;a href=&quot;https://github.com/techfort/LokiJS/tree/master/examples&quot;&gt;Examples&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>MarkdownDB</title>
      <link>https://tedneward.github.io/Research/storage/markdowndb/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/markdowndb/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://markdowndb.com/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/datopian/markdowndb&quot;&gt;Source&lt;/a&gt; | &lt;a href=&quot;https://markdowndb.com/blog/basic-tutorial&quot;&gt;Tutorial&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Stores to a SQLite database.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Minio</title>
      <link>https://tedneward.github.io/Research/storage/minio/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/minio/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://min.io/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/minio/minio&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;em&gt;Entered maintenance mode&lt;/em&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>ArcadeDB</title>
      <link>https://tedneward.github.io/Research/storage/arcadedb/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/arcadedb/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://arcadedb.com/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/ArcadeData/arcadedb&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;ArcadeDB is fully transactional DBMS with support for ACID transactions, structured and unstructured data, native graph engine (no joins but links between records), full-text indexing, geospatial querying, and advanced security.&lt;/p&gt; 
&lt;p&gt;ArcadeDB supports the following models:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Graph Database (compatible with Neo4j Cypher, Apache Tinkerpop Gremlin and OrientDB SQL)&lt;/li&gt; 
 &lt;li&gt;Document Database (compatible with the MongoDB driver + MongoDB queries and OrientDB SQL)&lt;/li&gt; 
 &lt;li&gt;Key/Value (compatible with the Redis driver)&lt;/li&gt; 
 &lt;li&gt;Search Engine&lt;/li&gt; 
 &lt;li&gt;Time Series&lt;/li&gt; 
 &lt;li&gt;Vector Embedding&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;ArcadeDB understands multiple languages:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;SQL (from OrientDB SQL)&lt;/li&gt; 
 &lt;li&gt;Neo4j Cypher (Open Cypher)&lt;/li&gt; 
 &lt;li&gt;Apache Gremlin (Apache Tinkerpop v3.7.x)&lt;/li&gt; 
 &lt;li&gt;GraphQL Language&lt;/li&gt; 
 &lt;li&gt;MongoDB Query Language&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;ArcadeDB can be used as:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Embedded from any language on top of the Java Virtual Machine&lt;/li&gt; 
 &lt;li&gt;Remotely by using HTTP/JSON&lt;/li&gt; 
 &lt;li&gt;Remotely by using a Postgres driver (ArcadeDB implements Postgres Wire protocol)&lt;/li&gt; 
 &lt;li&gt;Remotely by using a Redis driver (only a subset of the operations are implemented)&lt;/li&gt; 
 &lt;li&gt;Remotely by using a MongoDB driver (only a subset of the operations are implemented)&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Bolt</title>
      <link>https://tedneward.github.io/Research/storage/bolt/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/bolt/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/boltdb/bolt&quot;&gt;Source&lt;/a&gt; (Archived/&quot;done&quot;)&lt;/p&gt; 
&lt;p&gt;The goal of the project is to provide a simple, fast, and reliable database for projects that don&apos;t require a full database server such as Postgres or MySQL.&lt;/p&gt; 
&lt;p&gt;Since Bolt is meant to be used as such a low-level piece of functionality, simplicity is key. The API will be small and only focus on getting values and setting values.&lt;/p&gt; 
&lt;p&gt;Project Status: &quot;Bolt is stable, the API is fixed, and the file format is fixed. Full unit test coverage and randomized black box testing are used to ensure database consistency and thread safety. Bolt is currently used in high-load production environments serving databases as large as 1TB. Many companies such as Shopify and Heroku use Bolt-backed services every day.&quot;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Cayley</title>
      <link>https://tedneward.github.io/Research/storage/cayley/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/cayley/index.html</guid>
      	<description>
	&lt;p&gt;&quot;Features:&lt;br&gt; * Built-in query editor, visualizer and REPL&lt;br&gt; * Multiple query languages:&lt;br&gt; * Gizmo: query language inspired by Gremlin&lt;br&gt; * GraphQL-inspired query language&lt;br&gt; * MQL: simplified version for Freebase fans&lt;br&gt; * Modular: easy to connect to your favorite programming languages and back-end stores&lt;br&gt; * Production ready: well tested and used by various companies for their production workloads&lt;br&gt; * Fast: optimized specifically for usage in applications&quot;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://cayley.io/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/cayleygraph/cayley&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Coherence</title>
      <link>https://tedneward.github.io/Research/storage/coherence/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/coherence/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;http://coherence.java.net/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/oracle/coherence&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>CrateDB</title>
      <link>https://tedneward.github.io/Research/storage/cratedb/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/cratedb/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://crate.io/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/crate/crate&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Blog:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://crate.io/blog/handling-dynamic-objects-in-cratedb&quot;&gt;&quot;Handling Dynamic Objects in CrateDB&quot;&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://crate.io/blog/analyzing-and-visualizing-twitter-conversations&quot;&gt;&quot;Analyzing and Visualizing Twitter Conversations&quot;&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://crate.io/blog/indexing-and-storage-in-cratedb&quot;&gt;&quot;Indexing and Storage in CrateDB&quot;&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Apache Derby</title>
      <link>https://tedneward.github.io/Research/storage/derby/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/derby/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://db.apache.org/derby/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://db.apache.org/derby/manuals/index.html&quot;&gt;Docs&lt;/a&gt; | &lt;a href=&quot;https://db.apache.org/derby/papers/derby_web.html&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Full-featured, runs either client-server or embedded. Also supports Java stored procedures.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>DocumentDB</title>
      <link>https://tedneward.github.io/Research/storage/documentdb/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/documentdb/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://documentdb.io/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/documentdb/documentdb&quot;&gt;Source&lt;/a&gt; | &lt;a href=&quot;https://documentdb.io/docs/&quot;&gt;Docs&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;It offers a native implementation of document-oriented NoSQL database, enabling seamless CRUD operations on BSON data types within a PostgreSQL framework. Beyond basic operations, DocumentDB empowers you to execute complex workloads, including full-text searches, geospatial queries, and vector embeddings on your dataset, delivering robust functionality and flexibility for diverse data management needs.&lt;/p&gt; 
&lt;p&gt;The project comprises of two PostgreSQL primary components, which work together to support document operations.&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;pg_documentdb_core : PostgreSQL extension introducing BSON datatype support and operations for native Postgres.&lt;/li&gt; 
 &lt;li&gt;pg_documentdb : The public API surface for DocumentDB providing CRUD functionality on documents in the store.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Articles&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://opensource.microsoft.com/blog/2025/01/23/documentdb-open-source-announcement/&quot;&gt;&quot;DocumentDB: Open-Source Announcement&quot;&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://venturebeat.com/data-infrastructure/aws-microsoft-and-google-unite-behind-linux-foundation-documentdb-database-to-cut-enterprise-costs-and-limit-vendor-lock-in&quot;&gt;https://venturebeat.com/data-infrastructure/aws-microsoft-and-google-unite-behind-linux-foundation-documentdb-database-to-cut-enterprise-costs-and-limit-vendor-lock-in&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>DyBase</title>
      <link>https://tedneward.github.io/Research/storage/dybase/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/dybase/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;http://www.garret.ru/~knizhnik/dybase.html&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;http://www.garret.ru/~knizhnik/dybase-020.zip&quot;&gt;Sources (ZIP)&lt;/a&gt; | &lt;a href=&quot;http://www.garret.ru/~knizhnik/dybase/doc/dybase.html&quot;&gt;Docs&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>EdgeDB</title>
      <link>https://tedneward.github.io/Research/storage/edgedb/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/edgedb/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.edgedb.com/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/edgedb/edgedb&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>eXtremeDB</title>
      <link>https://tedneward.github.io/Research/storage/extremedb/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/extremedb/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.mcobject.com/extremedbfamily/&quot;&gt;Website&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Filestash</title>
      <link>https://tedneward.github.io/Research/storage/filestash/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/filestash/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.filestash.app/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/mickael-kerjean/filestash&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Geode</title>
      <link>https://tedneward.github.io/Research/storage/geode/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/geode/index.html</guid>
      	<description>
	&lt;p&gt;&quot;Geode pools memory, CPU, network resources, and optionally local disk across multiple processes to manage application objects and behavior. It uses dynamic replication and data partitioning techniques to implement high availability, improved performance, scalability, and fault tolerance. In addition to being a distributed data container, Apache Geode is an in-memory data management system that provides reliable asynchronous event notifications and guaranteed message delivery.&quot;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://geode.apache.org/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;http://github.com/apache/geode&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>HBase</title>
      <link>https://tedneward.github.io/Research/storage/hbase/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/hbase/index.html</guid>
      	<description>
	
	</description>
    </item>
    <item>
      <title>Database/Data storage implementation</title>
      <link>https://tedneward.github.io/Research/storage/implementation/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/implementation/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.reddit.com/r/databasedevelopment/&quot;&gt;/r/databasedevelopment&lt;/a&gt;&lt;/p&gt; 
&lt;h2&gt;Build your own....&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.codeproject.com/Articles/7410/Implementation-of-a-B-Tree-Database-Class&quot;&gt;B-Tree Implementation&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://transactional.blog/building-berkeleydb/&quot;&gt;Building BerkeleyDB&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/amit-davidson/Building-a-NoSQL-database-from-zero&quot;&gt;Building a NoSQL database from zero&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://betterprogramming.pub/build-a-nosql-database-from-the-scratch-in-1000-lines-of-code-8ed1c15ed924&quot;&gt;Build a NoSQL database from scratch in 1000 lines of code&lt;/a&gt; (in Go)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://blog.rajdeep-das.com/building-a-distributed-database-step-by-step-part-1-abc7d944e52d&quot;&gt;Building a Distributed Database&lt;/a&gt; &lt;a href=&quot;https://github.com/Prashant47/distributed-database&quot;&gt;Source&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.nan.fyi/database&quot;&gt;Build your own database&lt;/a&gt;: build a key-value database from the ground up&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://technicaldeft.com/build-a-database-server&quot;&gt;Build a Database server&lt;/a&gt;: Book ($34, with 14-day refund)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://skyzh.github.io/mini-lsm/&quot;&gt;Mini-LSM&lt;/a&gt;: Build a simple key-value storage engine in a week. Extend it in the second and third weeks.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/amit-davidson/LibraDB&quot;&gt;LibraDB&lt;/a&gt;: &quot;... a simple, persistent key/value store written in pure Go. The project aims to provide a working yet simple example of a working database.&quot;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/awelm/simpledb&quot;&gt;simpledb&lt;/a&gt;: A simple database built from scratch that has some the basic RDBMS features (SQL query parser, transactions, query optimizer)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://medium.com/swlh/how-to-build-a-relational-database-from-scratch-e208061027c7&quot;&gt;&quot;How to build a relational database from scratch&quot;&lt;/a&gt; (Medium members only)&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;C&lt;/strong&gt;: &lt;a href=&quot;https://cstack.github.io/db_tutorial/&quot;&gt;&lt;em&gt;Let&apos;s Build a Simple Database&lt;/em&gt;&lt;/a&gt; Build a clone of sqlite from scratch (&lt;a href=&quot;https://github.com/cstack/db_tutorial&quot;&gt;Source&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;C++&lt;/strong&gt;: &lt;a href=&quot;https://build-your-own.org/redis&quot;&gt;&lt;em&gt;Build Your Own Redis from Scratch&lt;/em&gt;&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;C++&lt;/strong&gt;: &lt;a href=&quot;https://www.codeproject.com/Articles/7410/Implementation-of-a-B-Tree-Database-Class&quot;&gt;&lt;em&gt;Implementation of a B-Tree Class&lt;/em&gt;&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;C#&lt;/strong&gt;: &lt;a href=&quot;https://www.codeproject.com/Articles/1029838/Build-Your-Own-Database&quot;&gt;&lt;em&gt;Build Your Own Database&lt;/em&gt;&lt;/a&gt; (&lt;a href=&quot;https://github.com/nam178/FooDB&quot;&gt;Source&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Clojure&lt;/strong&gt;: &lt;a href=&quot;http://aosabook.org/en/500L/an-archaeology-inspired-database.html&quot;&gt;&lt;em&gt;An Archaeology-Inspired Database&lt;/em&gt;&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Crystal&lt;/strong&gt;: &lt;a href=&quot;https://medium.com/@marceloboeira/why-you-should-build-your-own-nosql-database-9bbba42039f5&quot;&gt;&lt;em&gt;Why you should build your own NoSQL Database&lt;/em&gt;&lt;/a&gt; (&lt;a href=&quot;https://github.com/marceloboeira/bojack&quot;&gt;Source&lt;/a&gt;, Archived)&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Go&lt;/strong&gt;: &lt;a href=&quot;https://build-your-own.org/database/&quot;&gt;&lt;em&gt;Build Your Own Database from Scratch: Persistence, Indexing, Concurrency&lt;/em&gt;&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Go&lt;/strong&gt;: &lt;a href=&quot;https://www.build-redis-from-scratch.dev/&quot;&gt;&lt;em&gt;Build Your Own Redis from Scratch&lt;/em&gt;&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Go&lt;/strong&gt;: &lt;a href=&quot;https://github.com/krasun/gosqldb&quot;&gt;gosqldb&lt;/a&gt;: A key-value persistent database that supports SQL queries over B+ and LSM trees&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Java&lt;/strong&gt;: Electric&apos;s &lt;a href=&quot;http://megacz.com/software/btree.html&quot;&gt;B-Tree&lt;/a&gt; (Source JAR file)&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Java&lt;/strong&gt;: &lt;a href=&quot;https://github.com/jankotek/JDBM3&quot;&gt;&lt;em&gt;JDBM3&lt;/em&gt;&lt;/a&gt;: Work was paused and redirected to JDBM4-renamed-MapDB&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Java&lt;/strong&gt;: &lt;a href=&quot;https://mapdb.org/&quot;&gt;&lt;em&gt;MapDB&lt;/em&gt;&lt;/a&gt;: MapDB provides concurrent Maps, Sets and Queues backed by disk storage or off-heap-memory. It is a fast and easy to use embedded Java database engine. (&lt;a href=&quot;https://github.com/jankotek/mapdb/&quot;&gt;Source&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Java&lt;/strong&gt;: &lt;a href=&quot;http://cs.bc.edu/~sciore/simpledb/&quot;&gt;The SimpleDB Data System&lt;/a&gt;: &quot;... a multi-user transactional database server written in Java, which interacts with Java client programs via JDBC. The system is intended for pedagogical use only. The code is clean and compact. The APIs are straightforward. The learning curve is relatively small. Everything about it is geared towards improving the experience of a database system internals course. Consequently, the system is intentionally bare-bones. It implements only a small fraction of SQL and JDBC, and does little or no error checking. The SimpleDB code is an integral part of my textbook &lt;a href=&quot;https://www.amazon.com/dp/3030338355/&quot;&gt;Database Design and Implementation&lt;/a&gt;, published by Springer.&quot;&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;JavaScript&lt;/strong&gt;: &lt;a href=&quot;http://aosabook.org/en/500L/dagoba-an-in-memory-graph-database.html&quot;&gt;&lt;em&gt;Dagoba: an in-memory graph database&lt;/em&gt;&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Python&lt;/strong&gt;: &lt;a href=&quot;http://aosabook.org/en/500L/dbdb-dog-bed-database.html&quot;&gt;&lt;em&gt;DBDB: Dog Bed Database&lt;/em&gt;&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Python&lt;/strong&gt;: &lt;a href=&quot;http://charlesleifer.com/blog/building-a-simple-redis-server-with-python/&quot;&gt;&lt;em&gt;Write your own miniature Redis with Python&lt;/em&gt;&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Ruby&lt;/strong&gt;: &lt;a href=&quot;https://dineshgowda.com/posts/build-your-own-persistent-kv-store/&quot;&gt;&lt;em&gt;Build your own fast, persistent KV store in Ruby&lt;/em&gt;&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Rust&lt;/strong&gt;: &lt;a href=&quot;https://tokio.rs/tokio/tutorial/setup&quot;&gt;&lt;em&gt;Build your own Redis client and server&lt;/em&gt;&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Rust&lt;/strong&gt;: &lt;a href=&quot;https://github.com/yywe/yoursql&quot;&gt;YourSQL&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Rust&lt;/strong&gt;: &lt;a href=&quot;https://github.com/mzinsmeister/OxidSQL&quot;&gt;OxidSQL&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Rust&lt;/strong&gt;: &lt;a href=&quot;https://github.com/radogost/erdb&quot;&gt;erdb&lt;/a&gt;: An educational relational database&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Reading&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://news.ycombinator.com/item?id=18410692&quot;&gt;Ask HN: Books about database implementation&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://riak.com/assets/bitcask-intro.pdf&quot;&gt;Bitcask paper&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/B-tree&quot;&gt;Btree (Wikipedia)&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://benjamincongdon.me/blog/2021/08/17/B-Trees-More-Than-I-Thought-Id-Want-to-Know/&quot;&gt;B-trees: More than I thought I&apos;d want to know&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.programiz.com/dsa/b-tree&quot;&gt;B-tree&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://transactional.blog/blog/2024-data-replication-design-spectrum&quot;&gt;Data Replication Design Spectrum&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://webdam.inria.fr/Alice/&quot;&gt;Foundations of Databases&lt;/a&gt; (PDF available)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.lucavall.in/blog/how-databases-store-and-retrieve-data-with-b-trees&quot;&gt;How Databases Store and Retrieve Data with B-Trees&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.geeksforgeeks.org/introduction-of-b-tree-2/&quot;&gt;Introduction of B-tree&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Transactions&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://transactional.blog/blog/2025-decomposing-transactional-systems&quot;&gt;&quot;Decomposing Transactional Systems&quot;&lt;/a&gt;: &quot;Every transactional system does four things: 
  &lt;ul&gt; 
   &lt;li&gt;It &lt;em&gt;executes&lt;/em&gt; transactions.&lt;/li&gt; 
   &lt;li&gt;It &lt;em&gt;orders&lt;/em&gt; transactions.&lt;/li&gt; 
   &lt;li&gt;It &lt;em&gt;validates&lt;/em&gt; transactions.&lt;/li&gt; 
   &lt;li&gt;It &lt;em&gt;persists&lt;/em&gt; transactions.&lt;/li&gt; 
  &lt;/ul&gt; &lt;p&gt;&lt;em&gt;Executing&lt;/em&gt; a transaction means evaluating the body of the transaction to produce the intended reads and writes. There is still notable variety across systems as to how the body of a transaction is executed. Writes might be applied to storage during this phase, or they might be buffered locally and submitted as a batch at the end. A transaction might be executed more than once for different purposes.&lt;/p&gt; &lt;p&gt;&lt;em&gt;Ordering&lt;/em&gt; a transaction means assigning the transaction some notion of a time at which it occurred. This could be a version, a timestamp, a log sequence number, or a more complex description of transaction IDs it happened before or after. MVCC databases may assign two versions: an initial read version, and a final commit version. In this case, we’re mainly focused on the specific point at which the commit version is chosen — the time at which the database claims all reads and writes occurred atomically.&lt;/p&gt; &lt;p&gt;&lt;em&gt;Validating&lt;/em&gt; a transaction means enforcing concurrency control, or more rarely, domain-specific semantics. If a transaction is going to be rejected for a system defined reason, such as having serializability conflicts with existing transactions, it will happen here. When validation happens after ordering, it checks to see if the assigned order is valid. When validation happens before ordering, it provides a range of acceptable commit versions, and the ordering step chooses one of them.&lt;/p&gt; &lt;p&gt;&lt;em&gt;Persisting&lt;/em&gt; a transaction makes making it durable, generally to disk. Sometimes writes are incrementally made durable during transaction execution, but the key point in persistence is when all writes and the commit record marking the transaction as committed are durable. Often this is noting how the system performs replication and persists the outcome of its atomic commitment protocol. (And sometimes the lines between those two aren’t very clear.)&lt;/p&gt; &lt;p&gt;All four of these things must be done before the system may acknowledge a transaction’s result to a client. However, these steps can be done in any order. They can be done concurrently. Different systems achieve different tradeoffs by reordering these steps. ... A classic optimistic concurrency control database will execute a transaction, and record the read and write sets. Once execution finishes, a commit version is allocated, and concurrent transactions are checked for conflicts. If no conflicts were found, the transaction is made durable, and acknowledged as committed. ... A classic pessimistic concurrency control database executes a transaction and acquires locks as it runs to exclude conflicting transactions. When the transaction finishes, it acquires a commit version, and then is persisted to disk. Then it releases the locks.&lt;/p&gt; &lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>InnoDB</title>
      <link>https://tedneward.github.io/Research/storage/innodb/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/innodb/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/InnoDB&quot;&gt;Wikipedia&lt;/a&gt; | &lt;a href=&quot;https://mariadb.com/kb/en/innodb/&quot;&gt;Website&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>JsonDB</title>
      <link>https://tedneward.github.io/Research/storage/jsondb/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/jsondb/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://jsondb.io/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/Jsondb/jsondb-core&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Small memory footprint, runs embedded within your Java program,&lt;br&gt; Provides APIs that are very similar in names and semantics to those of Spring Data for MongoDB,&lt;br&gt; Supports encryption of data, XPath based search/find queries.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Kinto</title>
      <link>https://tedneward.github.io/Research/storage/kinto/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/kinto/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.kinto-storage.org/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://docs.kinto-storage.org/en/latest/overview.html&quot;&gt;Docs&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>libSQL</title>
      <link>https://tedneward.github.io/Research/storage/libsql/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/libsql/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://libsql.org/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/libsql/libsql&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Related: &lt;a href=&quot;https://github.com/libsql/sqld&quot;&gt;sqld&lt;/a&gt; - networked version of libsql&lt;/p&gt; 
&lt;h2&gt;Articles&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://blog.logrocket.com/libsql-next-gen-fork-sqlite/&quot;&gt;Get started with libSQL, a next-gen fork of SQLite&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>LowDB</title>
      <link>https://tedneward.github.io/Research/storage/lowdb/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/lowdb/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/typicode/lowdb&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Marten</title>
      <link>https://tedneward.github.io/Research/storage/martendb/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/martendb/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://martendb.io/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/jasperfx/marten&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Document Database: The Marten library provides .NET developers with the ability to easily use the proven PostgreSQL database engine and its fantastic JSON support as a fully fledged document database. The Marten team believes that a document database has far reaching benefits for developer productivity over relational databases with or without an ORM tool.&lt;/p&gt; 
&lt;p&gt;Event Store: Event Sourcing can be a powerful technique in applications that are workflow centric or have any need for historical queries. Marten utilizes the strong JSONB support to expose an ACID-compliant event store implementation over the PostgreSQL database. Even better yet, Marten takes advantage of PostgreSQL&apos;s embedded JavaScript support to enable effective user-defined projections against your event streams.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Actian</title>
      <link>https://tedneward.github.io/Research/storage/actian/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/actian/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.actian.com/data-management/nosql-object-database/&quot;&gt;Website&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>ArcticDB</title>
      <link>https://tedneward.github.io/Research/storage/arcticdb/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/arcticdb/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://arcticdb.io/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/man-group/ArcticDB&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;ArcticDB is a serverless DataFrame database engine designed for the Python Data Science ecosystem.&lt;/p&gt; 
&lt;p&gt;ArcticDB enables you to store, retrieve and process DataFrames at scale, backed by commodity object storage (S3-compatible storages and Azure Blob Storage).&lt;/p&gt; 
&lt;p&gt;ArcticDB requires zero additional infrastructure beyond a running Python environment and access to object storage and can be installed in seconds.&lt;/p&gt; 
&lt;p&gt;ArcticDB is:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt; &lt;p&gt;Fast&lt;/p&gt; 
  &lt;ul&gt; 
   &lt;li&gt;Process up to 100 million rows per second for a single consumer&lt;/li&gt; 
   &lt;li&gt;Process a billion rows per second across all consumers&lt;/li&gt; 
   &lt;li&gt;Quick and easy to install: pip install arcticdb&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Flexible&lt;/p&gt; 
  &lt;ul&gt; 
   &lt;li&gt;Data schemas are not required&lt;/li&gt; 
   &lt;li&gt;Supports streaming data ingestion&lt;/li&gt; 
   &lt;li&gt;Bitemporal - stores all previous versions of stored data&lt;/li&gt; 
   &lt;li&gt;Easy to setup both locally and on cloud&lt;/li&gt; 
   &lt;li&gt;Scales from dev/research to production environments&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Familiar&lt;/p&gt; 
  &lt;ul&gt; 
   &lt;li&gt;ArcticDB is the world&apos;s simplest shareable database&lt;/li&gt; 
   &lt;li&gt;Easy to learn for anyone with Python and Pandas experience&lt;/li&gt; 
   &lt;li&gt;Just you and your data - the cognitive overhead is very low.&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>BrightstarDB</title>
      <link>https://tedneward.github.io/Research/storage/brightstardb/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/brightstardb/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://brightstardb.com/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/BrightstarDB/BrightstarDB&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Cross Platform&lt;/strong&gt; BrightstarDB runs on Windows, Linux, OSX, Windows Phone, Android and iOS, with a single consistent data file format across all platforms. The core libraries have a small footprint and install with zero configuration for embedded applications.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Server or Embedded&lt;/strong&gt; Run BrightstarDB embedded inside your own application or connect to a BrightstarDB server using either the RESTful HTTP API or the strongly-typed .NET client API.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;RDF Flexibility&lt;/strong&gt; BrightstarDB is an RDF triplestore. It does not require the definition of a database schema, and with the RDF data model model you can easily add and integrate data of all shapes. We also implement the standard SPARQL query language, update language and protocol so you can use off-the-shelf client tools to connect to your data stores.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;LINQ Simplicity&lt;/strong&gt; BrightstarDB provides an ORM for RDF. A custom LINQ provider maps queries against your application domain model into SPARQL queries. This provides full CRUD and query capability for strongly-typed .NET applications.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Our Store or Yours&lt;/strong&gt; The ORM for RDF, LINQ to SPARQL and the .NET dynamic objects API all support connecting to any SPARQL endpoint that implements SPARQL 1.1 standards. So you can choose to store your triples in BrightstarDB or any other compliant triplestore and still make use of our advanced, developer-friendly APIs.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Open Source&lt;/strong&gt; BrightstarDB is developed in the open on GitHub. Our code is licensed under the permissive MIT license, allowing you to use BrightstarDB in commercial and non-commercial applications alike. Community support is available from our GitHub issue tracker. Commercial support is also available from NetworkedPlanet.&lt;/p&gt; &lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Citus</title>
      <link>https://tedneward.github.io/Research/storage/citus/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/citus/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.citusdata.com/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/citusdata/citus&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Citus is a PostgreSQL extension that transforms Postgres into a distributed database—so you can achieve high performance at any scale.&lt;/p&gt; 
&lt;p&gt;With Citus, you extend your PostgreSQL database with new superpowers:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Distributed tables are sharded across a cluster of PostgreSQL nodes to combine their CPU, memory, storage and I/O capacity.&lt;/li&gt; 
 &lt;li&gt;References tables are replicated to all nodes for joins and foreign keys from distributed tables and maximum read performance.&lt;/li&gt; 
 &lt;li&gt;Distributed query engine routes and parallelizes SELECT, DML, and other operations on distributed tables across the cluster.&lt;/li&gt; 
 &lt;li&gt;Columnar storage compresses data, speeds up scans, and supports fast projections, both on regular and distributed tables.&lt;/li&gt; 
 &lt;li&gt;Query from any node enables you to utilize the full capacity of your cluster for distributed queries&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;You can use these Citus superpowers to make your Postgres database scale-out ready on a single Citus node. Or you can build a large cluster capable of handling high transaction throughputs, especially in multi-tenant apps, run fast analytical queries, and process large amounts of time series or IoT data for real-time analytics. When your data size and volume grow, you can easily add more worker nodes to the cluster and rebalance the shards.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>CosmosDB</title>
      <link>https://tedneward.github.io/Research/storage/cosmosdb/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/cosmosdb/index.html</guid>
      	<description>
	&lt;p&gt;&quot;Azure Cosmos DB is a fully managed database service with turnkey global distribution and transparent multi-master replication. Get single-digit millisecond read and write latencies at the 99th percentile, automatic and elastic scaling of throughput and storage worldwide, 99.999-percent high availability, and five well-defined consistency choices—all backed by industry-leading comprehensive SLAs. Multi-model with wire protocol–compatible API endpoints for Cassandra, MongoDB, SQL, Gremlin, Etcd, and Table along with built-in support for Jupyter notebooks.&quot;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://azure.microsoft.com/en-us/services/cosmos-db/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://docs.microsoft.com/en-us/azure/cosmos-db/&quot;&gt;Documentation&lt;/a&gt;(&lt;a href=&quot;https://docs.microsoft.com/en-us/azure/opbuildpdf/cosmos-db/toc.pdf?branch=live&quot;&gt;Generated PDF&lt;/a&gt;) | &lt;a href=&quot;https://azure.microsoft.com/en-us/resources/developer-s-guide-to-getting-started-with-azure-cosmos-db/&quot;&gt;Book&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>db4o</title>
      <link>https://tedneward.github.io/Research/storage/db4o/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/db4o/index.html</guid>
      	<description>
	&lt;p&gt;Used to be product from db4objects, since liquidated.&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/iboxdb/db4o-gpl&quot;&gt;db4o-gpl&lt;/a&gt;: GPL&apos;ed db4o code, both Java and .NET&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/lytico/db4o&quot;&gt;db4o&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/pegurnee/db4o&quot;&gt;db4o&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>DGraph</title>
      <link>https://tedneward.github.io/Research/storage/dgraph/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/dgraph/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://dgraph.io/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/dgraph-io/dgraph&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Dgraph is a horizontally scalable and distributed GraphQL database with a graph backend. It provides ACID transactions, consistent replication, and linearizable reads. It&apos;s built from the ground up to perform for a rich set of queries. Being a native GraphQL database, it tightly controls how the data is arranged on disk to optimize for query performance and throughput, reducing disk seeks and network calls in a cluster.&lt;/p&gt; 
&lt;p&gt;Using the official Dgraph image: &lt;code&gt;docker pull dgraph/dgraph:latest&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;Run a Quick Standalone Cluster: &lt;code&gt;docker run -it -p 8080:8080 -p 9080:9080 -v ~/dgraph:/dgraph dgraph/standalone:latest&lt;/code&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Dolt</title>
      <link>https://tedneward.github.io/Research/storage/dolt/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/dolt/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/dolthub/dolt&quot;&gt;Source&lt;/a&gt; | &lt;a href=&quot;https://docs.dolthub.com/introduction/what-is-dolt&quot;&gt;Docs&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Dolt is a SQL database that you can fork, clone, branch, merge, push and pull just like a git repository. Connect to Dolt just like any MySQL database to run queries or update the data using SQL commands. Use the command line interface to import CSV files, commit your changes, push them to a remote, or merge your teammate&apos;s changes.&lt;/p&gt; 
&lt;p&gt;All the commands you know for Git work exactly the same for Dolt. Git versions files, Dolt versions tables. It&apos;s like Git and MySQL had a baby!&lt;/p&gt; 
&lt;p&gt;We also built &lt;a href=&quot;https://www.dolthub.com/&quot;&gt;DoltHub&lt;/a&gt;, a place to share Dolt databases. We host public data for free!&lt;/p&gt; 
&lt;p&gt;We built Dolt using the following axioms:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Git versions files. Dolt versions table schema and table data.&lt;/li&gt; 
 &lt;li&gt;Dolt will copy the Git command line exactly.&lt;/li&gt; 
 &lt;li&gt;Dolt will be MySQL compatible.&lt;/li&gt; 
 &lt;li&gt;Git features in SQL will extend MySQL SQL. Write operations will be procedures. Read operations will be system tables.&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Amazon Dynamo</title>
      <link>https://tedneward.github.io/Research/storage/dynamo/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/dynamo/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://docs.aws.amazon.com/dynamodb/index.html&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/index.html&quot;&gt;Developer Guide&lt;/a&gt; (&lt;a href=&quot;https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/dynamodb-dg.pdf&quot;&gt;PDF&lt;/a&gt;)&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Extensible-Storage-Engine (ESE, aka &quot;Jet&quot;)</title>
      <link>https://tedneward.github.io/Research/storage/ese/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/ese/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/microsoft/Extensible-Storage-Engine&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;From the source README:&lt;/p&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;ESE enables applications to store data to, and retrieve data from tables using indexed or sequential cursor navigation. It supports denormalized schemas including wide tables with numerous sparse columns, multi-valued columns, and sparse and rich indexes. ESE enables applications to enjoy a consistent data state using transacted data update and retrieval. A crash recovery mechanism is provided so that data consistency is maintained even in the event of a system crash. ESE provides ACID (Atomic Consistent Isolated Durable) transactions over data and schema by way of a write-ahead log and a snapshot isolation model.&lt;/p&gt; 
 &lt;ul&gt; 
  &lt;li&gt;A summary of features and the JET API documentation are up on &lt;a href=&quot;https://docs.microsoft.com/en-us/windows/win32/extensible-storage-engine/extensible-storage-engine&quot;&gt;Microsoft&apos;s official documentation site&lt;/a&gt;&lt;/li&gt; 
  &lt;li&gt;A more extensive list of ESE database features &lt;a href=&quot;https://en.wikipedia.org/wiki/Extensible_Storage_Engine&quot;&gt;are documented in our Wikipedia entry&lt;/a&gt;&lt;/li&gt; 
 &lt;/ul&gt; 
 &lt;p&gt;The library provides many other strongly layered and, thus, reusable sub-facilities as well:&lt;/p&gt; 
 &lt;ul&gt; 
  &lt;li&gt;A synchronization and locking library&lt;/li&gt; 
  &lt;li&gt;An STL-like data structures library&lt;/li&gt; 
  &lt;li&gt;An OS abstraction layer&lt;/li&gt; 
  &lt;li&gt;A Block / Cache Manager&lt;/li&gt; 
 &lt;/ul&gt; 
&lt;/blockquote&gt; 
&lt;p&gt;All this is in addition to the full-blown database engine itself.&lt;/p&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;Most people do not know that JET was an acronym for an API set, not a specific database format or engine. Just as there is no such thing as &quot;the SQL engine&quot;, as there are many implementations of the protocol, there is no &quot;JET engine&quot; or &quot;JET database&quot;. It is in the acronym, &quot;Joint Engine Technology&quot;. And as such, there are two separate implementations of the JET API. This is the JET Blue engine implementation, see &lt;a href=&quot;https://docs.microsoft.com/en-us/windows/win32/extensible-storage-engine/extensible-storage-engine&quot;&gt;Notes in here&lt;/a&gt;. The origin of the &lt;a href=&quot;https://en.wikipedia.org/wiki/Extensible_Storage_Engine#History&quot;&gt;colors have an an amusing source&lt;/a&gt; by the way. Most people think of the &quot;JET engine&quot; as JET Red, that shipped under Microsoft Access. This is not that &quot;JET engine&quot;. We renamed to ESE to try to avoid this confusion, but it seems that the confusion continues to this day.&lt;/p&gt; 
&lt;/blockquote&gt;
	</description>
    </item>
    <item>
      <title>FactDB</title>
      <link>https://tedneward.github.io/Research/storage/factdb/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/factdb/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/MadBomber/fact_db&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;FactDb implements the Event Clock concept - capturing organizational knowledge through temporal facts with validity periods (valid_at/invalid_at), entity resolution, and audit trails back to source content.&lt;/p&gt; 
&lt;p&gt;Key Features&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Temporal Facts - Track facts with validity periods&lt;/li&gt; 
 &lt;li&gt;Entity Resolution - Resolve mentions to canonical entities&lt;/li&gt; 
 &lt;li&gt;Audit Trails - Every fact links back to source content&lt;/li&gt; 
 &lt;li&gt;Multiple Extractors - Extract facts manually, via LLM, or rule-based&lt;/li&gt; 
 &lt;li&gt;Semantic Search - PostgreSQL with pgvector&lt;/li&gt; 
 &lt;li&gt;Concurrent Processing - Batch process with parallel pipelines&lt;/li&gt; 
 &lt;li&gt;Output Formats - JSON, triples, Cypher, or text for LLM consumption&lt;/li&gt; 
 &lt;li&gt;Temporal Queries - Fluent API for point-in-time queries and diffs&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Firebird</title>
      <link>https://tedneward.github.io/Research/storage/firebirdsql/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/firebirdsql/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.firebirdsql.org&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/FirebirdSQL/&quot;&gt;Source&lt;/a&gt; | &lt;a href=&quot;https://www.firebirdsql.org/en/firebird-rdbms/&quot;&gt;Docs&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>GraphDB(Lite)</title>
      <link>https://tedneward.github.io/Research/storage/graphdb/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/graphdb/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.ontotext.com/products/graphdb/&quot;&gt;Website&lt;/a&gt; | Commercial/closed-source&lt;/p&gt; 
&lt;p&gt;Run GraphDB in Docker: &lt;code&gt;docker run -d -p 7200:7200 ontotext/graphdb:10.0.0&lt;/code&gt; (Source: &lt;a href=&quot;https://github.com/Ontotext-AD/graphdb-docker&quot;&gt;https://github.com/Ontotext-AD/graphdb-docker&lt;/a&gt;)&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>HyperSQL</title>
      <link>https://tedneward.github.io/Research/storage/hsqldb/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/hsqldb/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;http://hsqldb.org/&quot;&gt;Website&lt;/a&gt; &lt;a href=&quot;https://sourceforge.net/projects/hsqldb/&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>IndexedDB</title>
      <link>https://tedneward.github.io/Research/storage/indexeddb/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/indexeddb/index.html</guid>
      	<description>
	&lt;p&gt;&quot;IndexedDB is a transactional database system, like an SQL-based RDBMS. However, unlike SQL-based RDBMSes, which use fixed-column tables, IndexedDB is a JavaScript-based object-oriented database. IndexedDB lets you store and retrieve objects that are indexed with a key; any objects supported by the structured clone algorithm can be stored. You need to specify the database schema, open a connection to your database, and then retrieve and update data within a series of transactions.&quot;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://w3c.github.io/IndexedDB/&quot;&gt;Specification&lt;/a&gt; | &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API&quot;&gt;Reference&lt;/a&gt;&lt;/p&gt; 
&lt;h2&gt;Using&lt;/h2&gt; 
&lt;h3&gt;Open the database&lt;/h3&gt; 
&lt;pre&gt;&lt;code&gt;// Let us open our database
const request = window.indexedDB.open(&quot;MyTestDatabase&quot;, 3);
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;The open request doesn&apos;t open the database or start the transaction right away. The call to the open() function returns an IDBOpenDBRequest object with a result (success) or error value that you handle as an event. Most other asynchronous functions in IndexedDB do the same thing - return an IDBRequest object with the result or error. The result for the open function is an instance of an IDBDatabase.&lt;/p&gt; 
&lt;p&gt;The second parameter to the open method is the version of the database. The version of the database determines the database schema — the object stores in the database and their structure. If the database doesn&apos;t already exist, it is created by the open operation, then an &lt;code&gt;onupgradeneeded&lt;/code&gt; event is triggered and you create the database schema in the handler for this event. If the database does exist but you are specifying an upgraded version number, an &lt;code&gt;onupgradeneeded&lt;/code&gt; event is triggered straight away, allowing you to provide an updated schema in its handler. More on this later in &quot;Creating or updating the version of the database&quot; below, and the &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/IDBFactory/open&quot;&gt;&lt;code&gt;IDBFactory.open&lt;/code&gt;&lt;/a&gt; page.&lt;/p&gt; 
&lt;p&gt;Warning: The version number is an &lt;code&gt;unsigned long long&lt;/code&gt; number, which means that it can be a very big integer. It also means that you can&apos;t use a float, otherwise it will be converted to the closest lower integer and the transaction may not start, nor the upgradeneeded event trigger. So for example, don&apos;t use 2.4 as a version number: &lt;code&gt;const request = indexedDB.open(&quot;MyTestDatabase&quot;, 2.4); // don&apos;t do this, as the version will be rounded to 2&lt;/code&gt;&lt;/p&gt; 
&lt;h4&gt;Generating handlers&lt;/h4&gt; 
&lt;pre&gt;&lt;code&gt;request.onerror = (event) =&amp;gt; {
  // Do something with request.error!
};
request.onsuccess = (event) =&amp;gt; {
  // Do something with request.result!
};
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;If the request succeeds, the success event is fired, and the function assigned to onsuccess is called. If the request fails, the error event is fired, and the function assigned to onerror is called.&lt;/p&gt; 
&lt;p&gt;The IndexedDB API is designed to minimize the need for error handling, so you&apos;re not likely to see many error events (at least, not once you&apos;re used to the API!). In the case of opening a database, however, there are some common conditions that generate error events. The most likely problem is that the user decided not to give your web app permission to create a database. One of the main design goals of IndexedDB is to allow large amounts of data to be stored for offline use. (To learn more about how much storage you can have for each browser, see How much data can be stored? on the Browser storage quotas and eviction criteria page.)&lt;/p&gt; 
&lt;p&gt;Obviously, browsers do not want to allow some advertising network or malicious website to pollute your computer, so browsers used to prompt the user the first time any given web app attempts to open an IndexedDB for storage. The user could choose to allow or deny access. Also, IndexedDB storage in browsers&apos; privacy modes only lasts in-memory until the incognito session is closed.&lt;/p&gt; 
&lt;p&gt;Now, assuming that the user allowed your request to create a database, and you&apos;ve received a success event to trigger the success callback; What&apos;s next? The request here was generated with a call to indexedDB.open(), so request.result is an instance of IDBDatabase, and you definitely want to save that for later.&lt;/p&gt; 
&lt;h4&gt;Handling errors&lt;/h4&gt; 
&lt;p&gt;As mentioned above, error events bubble. Error events are targeted at the request that generated the error, then the event bubbles to the transaction, and then finally to the database object. If you want to avoid adding error handlers to every request, you can instead add a single error handler on the database object, like so:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;db.onerror = (event) =&amp;gt; {
  // Generic error handler for all errors targeted at this database&apos;s
  // requests!
  console.error(`Database error: ${event.target.error?.message}`);
};
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;One of the common possible errors when opening a database is VER_ERR. It indicates that the version of the database stored on the disk is greater than the version that you are trying to open. This is an error case that must always be handled by the error handler.&lt;/p&gt; 
&lt;h4&gt;Creating or updating the version of the database&lt;/h4&gt; 
&lt;p&gt;When you create a new database or increase the version number of an existing database (by specifying a higher version number than you did previously, when Opening a database), the onupgradeneeded event will be triggered and an IDBVersionChangeEvent object will be passed to any onversionchange event handler set up on request.result (i.e., db in the example). In the handler for the upgradeneeded event, you should create the object stores needed for this version of the database:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;// This event is only implemented in recent browsers
request.onupgradeneeded = (event) =&amp;gt; {
  // Save the IDBDatabase interface
  const db = event.target.result;

  // Create an objectStore for this database
  const objectStore = db.createObjectStore(&quot;name&quot;, { keyPath: &quot;myKey&quot; });
};
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;In this case, the database will already have the object stores from the previous version of the database, so you do not have to create these object stores again. You only need to create any new object stores, or delete object stores from the previous version that are no longer needed. If you need to change an existing object store (e.g., to change the keyPath), then you must delete the old object store and create it again with the new options. (Note that this will delete the information in the object store! If you need to save that information, you should read it out and save it somewhere else before upgrading the database.)&lt;/p&gt; 
&lt;p&gt;Trying to create an object store with a name that already exists (or trying to delete an object store with a name that does not already exist) will throw an error.&lt;/p&gt; 
&lt;p&gt;If the onupgradeneeded event exits successfully, the onsuccess handler of the open database request will then be triggered.&lt;/p&gt; 
&lt;h4&gt;Structuring the database&lt;/h4&gt; 
&lt;p&gt;Now to structure the database. IndexedDB uses object stores rather than tables, and a single database can contain any number of object stores. Whenever a value is stored in an object store, it is associated with a key. There are several different ways that a key can be supplied depending on whether the object store uses a key path or a key generator.&lt;/p&gt; 
&lt;p&gt;The following table shows the different ways the keys are supplied:&lt;/p&gt; 
&lt;table&gt; 
 &lt;thead&gt; 
  &lt;tr&gt;
   &lt;th&gt;Key Path (keyPath) &lt;/th&gt;
   &lt;th&gt; Key Generator (autoIncrement) &lt;/th&gt;
   &lt;th&gt; Description&lt;/th&gt;
  &lt;/tr&gt; 
 &lt;/thead&gt; 
 &lt;tbody&gt; 
  &lt;tr&gt;
   &lt;td&gt;No &lt;/td&gt;
   &lt;td&gt; No &lt;/td&gt;
   &lt;td&gt; This object store can hold any kind of value, even primitive values like numbers and strings. You must supply a separate key argument whenever you want to add a new value.&lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt;Yes &lt;/td&gt;
   &lt;td&gt; No &lt;/td&gt;
   &lt;td&gt; This object store can only hold JavaScript objects. The objects must have a property with the same name as the key path.&lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt;No &lt;/td&gt;
   &lt;td&gt; Yes &lt;/td&gt;
   &lt;td&gt; This object store can hold any kind of value. The key is generated for you automatically, or you can supply a separate key argument if you want to use a specific key.&lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt;Yes &lt;/td&gt;
   &lt;td&gt; Yes &lt;/td&gt;
   &lt;td&gt; This object store can only hold JavaScript objects. Usually a key is generated and the value of the generated key is stored in the object in a property with the same name as the key path. However, if such a property already exists, the value of that property is used as key rather than generating a new key.&lt;/td&gt;
  &lt;/tr&gt; 
 &lt;/tbody&gt; 
&lt;/table&gt; 
&lt;p&gt;You can also create indices on any object store, provided the object store holds objects, not primitives. An index lets you look up the values stored in an object store using the value of a property of the stored object, rather than the object&apos;s key.&lt;/p&gt; 
&lt;p&gt;Additionally, indexes have the ability to enforce simple constraints on the stored data. By setting the unique flag when creating the index, the index ensures that no two objects are stored with both having the same value for the index&apos;s key path. So, for example, if you have an object store which holds a set of people, and you want to ensure that no two people have the same email address, you can use an index with the unique flag set to enforce this.&lt;/p&gt; 
&lt;p&gt;That may sound confusing, but this simple example should illustrate the concepts. First, we&apos;ll define some customer data to use in our example:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;// This is what our customer data looks like.
const customerData = [
  { ssn: &quot;444-44-4444&quot;, name: &quot;Bill&quot;, age: 35, email: &quot;bill@company.com&quot; },
  { ssn: &quot;555-55-5555&quot;, name: &quot;Donna&quot;, age: 32, email: &quot;donna@home.org&quot; },
];
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Of course, you wouldn&apos;t use someone&apos;s social security number as the primary key to a customer table because not everyone has a social security number, and you would store their birth date instead of their age, but let&apos;s ignore those unfortunate choices for the sake of convenience and move along.&lt;/p&gt; 
&lt;p&gt;Now let&apos;s look at creating an IndexedDB to store our data:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;const dbName = &quot;the_name&quot;;

const request = indexedDB.open(dbName, 2);

request.onerror = (event) =&amp;gt; {
  // Handle errors.
};
request.onupgradeneeded = (event) =&amp;gt; {
  const db = event.target.result;

  // Create an objectStore to hold information about our customers. We&apos;re
  // going to use &quot;ssn&quot; as our key path because it&apos;s guaranteed to be
  // unique - or at least that&apos;s what I was told during the kickoff meeting.
  const objectStore = db.createObjectStore(&quot;customers&quot;, { keyPath: &quot;ssn&quot; });

  // Create an index to search customers by name. We may have duplicates
  // so we can&apos;t use a unique index.
  objectStore.createIndex(&quot;name&quot;, &quot;name&quot;, { unique: false });

  // Create an index to search customers by email. We want to ensure that
  // no two customers have the same email, so use a unique index.
  objectStore.createIndex(&quot;email&quot;, &quot;email&quot;, { unique: true });

  // Use transaction oncomplete to make sure the objectStore creation is
  // finished before adding data into it.
  objectStore.transaction.oncomplete = (event) =&amp;gt; {
    // Store values in the newly created objectStore.
    const customerObjectStore = db
      .transaction(&quot;customers&quot;, &quot;readwrite&quot;)
      .objectStore(&quot;customers&quot;);
    customerData.forEach((customer) =&amp;gt; {
      customerObjectStore.add(customer);
    });
  };
};
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;As indicated previously, onupgradeneeded is the only place where you can alter the structure of the database. In it, you can create and delete object stores and build and remove indices.&lt;/p&gt; 
&lt;p&gt;Object stores are created with a single call to createObjectStore(). The method takes a name of the store, and a parameter object. Even though the parameter object is optional, it is very important, because it lets you define important optional properties and refine the type of object store you want to create. In our case, we&apos;ve asked for an object store named &quot;customers&quot; and defined a keyPath, which is the property that makes an individual object in the store unique. That property in this example is &quot;ssn&quot; since a social security number is guaranteed to be unique. &quot;ssn&quot; must be present on every object that is stored in the objectStore.&lt;/p&gt; 
&lt;p&gt;We&apos;ve also asked for an index named &quot;name&quot; that looks at the name property of the stored objects. As with createObjectStore(), createIndex() takes an optional options object that refines the type of index that you want to create. Adding objects that don&apos;t have a name property still succeeds, but the objects won&apos;t appear in the &quot;name&quot; index.&lt;/p&gt; 
&lt;p&gt;We can now retrieve the stored customer objects using their ssn from the object store directly, or using their name by using the index. To learn how this is done, see the section on using an index.&lt;/p&gt; 
&lt;h4&gt;Using a key generator&lt;/h4&gt; 
&lt;p&gt;Setting up an autoIncrement flag when creating the object store would enable the key generator for that object store. By default this flag is not set.&lt;/p&gt; 
&lt;p&gt;With the key generator, the key would be generated automatically as you add the value to the object store. The current number of a key generator is always set to 1 when the object store for that key generator is first created. Basically the newly auto-generated key is increased by 1 based on the previous key. The current number for a key generator never decreases, other than as a result of database operations being reverted, for example, the database transaction is aborted. Therefore deleting a record or even clearing all records from an object store never affects the object store&apos;s key generator.&lt;/p&gt; 
&lt;p&gt;We can create another object store with the key generator as below:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;// Open the indexedDB.
const request = indexedDB.open(dbName, 3);

request.onupgradeneeded = (event) =&amp;gt; {
  const db = event.target.result;

  // Create another object store called &quot;names&quot; with the autoIncrement flag set as true.
  const objStore = db.createObjectStore(&quot;names&quot;, { autoIncrement: true });

  // Because the &quot;names&quot; object store has the key generator, the key for the name value is generated automatically.
  // The added records would be like:
  // key : 1 =&amp;gt; value : &quot;Bill&quot;
  // key : 2 =&amp;gt; value : &quot;Donna&quot;
  customerData.forEach((customer) =&amp;gt; {
    objStore.add(customer.name);
  });
};
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;For more details about the key generator, see Key generators in the spec.&lt;/p&gt; 
&lt;h3&gt;Adding, retrieving, and removing data&lt;/h3&gt; 
&lt;p&gt;Before you can do anything with your new database, you need to start a transaction. Transactions come from the database object, and you have to specify which object stores you want the transaction to span. Once you are inside the transaction, you can access the object stores that hold your data and make your requests. Next, you need to decide if you&apos;re going to make changes to the database or if you just need to read from it. Transactions have three available modes: readonly, readwrite, and versionchange.&lt;/p&gt; 
&lt;p&gt;To change the &quot;schema&quot; or structure of the database—which involves creating or deleting object stores or indexes—the transaction must be in versionchange mode. This transaction is opened by calling the IDBFactory.open method with a version specified.&lt;/p&gt; 
&lt;p&gt;To read the records of an existing object store, the transaction can either be in readonly or readwrite mode. To make changes to an existing object store, the transaction must be in readwrite mode. You open such transactions with IDBDatabase.transaction. The method accepts two parameters: the storeNames (the scope, defined as an array of object stores that you want to access) and the mode (readonly or readwrite) for the transaction. The method returns a transaction object containing the IDBIndex.objectStore method, which you can use to access your object store. By default, where no mode is specified, transactions open in readonly mode.&lt;/p&gt; 
&lt;p&gt;You can speed up data access by using the right scope and mode in the transaction. Here are a couple of tips:&lt;/p&gt; 
&lt;p&gt;When defining the scope, specify only the object stores you need. This way, you can run multiple transactions with non-overlapping scopes concurrently.&lt;br&gt; Only specify a readwrite transaction mode when necessary. You can concurrently run multiple readonly transactions with overlapping scopes, but you can have only one readwrite transaction for an object store. To learn more, see the definition for transaction in the IndexedDB key characteristics and basic terminology article.&lt;/p&gt; 
&lt;h4&gt;Adding data to the database&lt;/h4&gt; 
&lt;p&gt;If you&apos;ve just created a database, then you probably want to write to it. Here&apos;s what that looks like:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;const transaction = db.transaction([&quot;customers&quot;], &quot;readwrite&quot;);
// Note: Older experimental implementations use the deprecated constant IDBTransaction.READ_WRITE instead of &quot;readwrite&quot;.
// In case you want to support such an implementation, you can write:
// const transaction = db.transaction([&quot;customers&quot;], IDBTransaction.READ_WRITE);
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;The transaction() function takes two arguments (though one is optional) and returns a transaction object. The first argument is a list of object stores that the transaction will span. You can pass an empty array if you want the transaction to span all object stores, but don&apos;t do it because the spec says an empty array should generate an InvalidAccessError. If you don&apos;t specify anything for the second argument, you get a read-only transaction. Since you want to write to it here you need to pass the &quot;readwrite&quot; flag.&lt;/p&gt; 
&lt;p&gt;Now that you have a transaction you need to understand its lifetime. Transactions are tied very closely to the event loop. If you make a transaction and return to the event loop without using it then the transaction will become inactive. The only way to keep the transaction active is to make a request on it. When the request is finished you&apos;ll get a DOM event and, assuming that the request succeeded, you&apos;ll have another opportunity to extend the transaction during that callback. If you return to the event loop without extending the transaction then it will become inactive, and so on. As long as there are pending requests the transaction remains active. Transaction lifetimes are really very simple but it might take a little time to get used to. A few more examples will help, too. If you start seeing TRANSACTION_INACTIVE_ERR error codes then you&apos;ve messed something up.&lt;/p&gt; 
&lt;p&gt;Transactions can receive DOM events of three different types: error, abort, and complete. We&apos;ve talked about the way that error events bubble, so a transaction receives error events from any requests that are generated from it. A more subtle point here is that the default behavior of an error is to abort the transaction in which it occurred. Unless you handle the error by first calling stopPropagation() on the error event then doing something else, the entire transaction is rolled back. This design forces you to think about and handle errors, but you can always add a catchall error handler to the database if fine-grained error handling is too cumbersome. If you don&apos;t handle an error event or if you call abort() on the transaction, then the transaction is rolled back and an abort event is fired on the transaction. Otherwise, after all pending requests have completed, you&apos;ll get a complete event. If you&apos;re doing lots of database operations, then tracking the transaction rather than individual requests can certainly aid your sanity.&lt;/p&gt; 
&lt;p&gt;Now that you have a transaction, you&apos;ll need to get the object store from it. Transactions only let you have an object store that you specified when creating the transaction. Then you can add all the data you need.&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;// Do something when all the data is added to the database.
transaction.oncomplete = (event) =&amp;gt; {
  console.log(&quot;All done!&quot;);
};

transaction.onerror = (event) =&amp;gt; {
  // Don&apos;t forget to handle errors!
};

const objectStore = transaction.objectStore(&quot;customers&quot;);
customerData.forEach((customer) =&amp;gt; {
  const request = objectStore.add(customer);
  request.onsuccess = (event) =&amp;gt; {
    // event.target.result === customer.ssn;
  };
});
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;The result of a request generated from a call to add() is the key of the value that was added. So in this case, it should equal the ssn property of the object that was added, since the object store uses the ssn property for the key path. Note that the add() function requires that no object already be in the database with the same key. If you&apos;re trying to modify an existing entry, or you don&apos;t care if one exists already, you can use the put() function, as shown below in the Updating an entry in the database section.&lt;/p&gt; 
&lt;h3&gt;Removing data from the database&lt;/h3&gt; 
&lt;p&gt;Removing data is very similar:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;const request = db
  .transaction([&quot;customers&quot;], &quot;readwrite&quot;)
  .objectStore(&quot;customers&quot;)
  .delete(&quot;444-44-4444&quot;);
request.onsuccess = (event) =&amp;gt; {
  // It&apos;s gone!
};
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;Getting data from the database&lt;/h3&gt; 
&lt;p&gt;Now that the database has some info in it, you can retrieve it in several ways. First, the simple get(). You need to provide the key to retrieve the value, like so:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;const transaction = db.transaction([&quot;customers&quot;]);
const objectStore = transaction.objectStore(&quot;customers&quot;);
const request = objectStore.get(&quot;444-44-4444&quot;);
request.onerror = (event) =&amp;gt; {
  // Handle errors!
};
request.onsuccess = (event) =&amp;gt; {
  // Do something with the request.result!
  console.log(`Name for SSN 444-44-4444 is ${request.result.name}`);
};
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;That&apos;s a lot of code for a &quot;simple&quot; retrieval. Here&apos;s how you can shorten it up a bit, assuming that you handle errors at the database level:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;db
  .transaction(&quot;customers&quot;)
  .objectStore(&quot;customers&quot;)
  .get(&quot;444-44-4444&quot;).onsuccess = (event) =&amp;gt; {
  console.log(`Name for SSN 444-44-4444 is ${event.target.result.name}`);
};
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;See how this works? Since there&apos;s only one object store, you can avoid passing a list of object stores you need in your transaction and just pass the name as a string. Also, you&apos;re only reading from the database, so you don&apos;t need a &quot;readwrite&quot; transaction. Calling transaction() with no mode specified gives you a &quot;readonly&quot; transaction. Another subtlety here is that you don&apos;t actually save the request object to a variable. Since the DOM event has the request as its target you can use the event to get to the result property.&lt;/p&gt; 
&lt;p&gt;Updating an entry in the database&lt;br&gt; Now we&apos;ve retrieved some data, updating it and inserting it back into the IndexedDB is pretty simple. Let&apos;s update the previous example somewhat:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;const objectStore = db
  .transaction([&quot;customers&quot;], &quot;readwrite&quot;)
  .objectStore(&quot;customers&quot;);
const request = objectStore.get(&quot;444-44-4444&quot;);
request.onerror = (event) =&amp;gt; {
  // Handle errors!
};
request.onsuccess = (event) =&amp;gt; {
  // Get the old value that we want to update
  const data = event.target.result;

  // update the value(s) in the object that you want to change
  data.age = 42;

  // Put this updated object back into the database.
  const requestUpdate = objectStore.put(data);
  requestUpdate.onerror = (event) =&amp;gt; {
    // Do something with the error
  };
  requestUpdate.onsuccess = (event) =&amp;gt; {
    // Success - the data is updated!
  };
};
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;So here we&apos;re creating an objectStore and requesting a customer record out of it, identified by its ssn value (444-44-4444). We then put the result of that request in a variable (data), update the age property of this object, then create a second request (requestUpdate) to put the customer record back into the objectStore, overwriting the previous value.&lt;/p&gt; 
&lt;p&gt;Note: In this case we&apos;ve had to specify a readwrite transaction because we want to write to the database, not just read from it.&lt;/p&gt; 
&lt;p&gt;Using a cursor&lt;br&gt; Using get() requires that you know which key you want to retrieve. If you want to step through all the values in your object store, then you can use a cursor. Here&apos;s what it looks like:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;const objectStore = db.transaction(&quot;customers&quot;).objectStore(&quot;customers&quot;);

objectStore.openCursor().onsuccess = (event) =&amp;gt; {
  const cursor = event.target.result;
  if (cursor) {
    console.log(`Name for SSN ${cursor.key} is ${cursor.value.name}`);
    cursor.continue();
  } else {
    console.log(&quot;No more entries!&quot;);
  }
};
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;The openCursor() function takes several arguments. First, you can limit the range of items that are retrieved by using a key range object that we&apos;ll get to in a minute. Second, you can specify the direction that you want to iterate. In the above example, we&apos;re iterating over all objects in ascending order. The success callback for cursors is a little special. The cursor object itself is the result of the request (above we&apos;re using the shorthand, so it&apos;s event.target.result). Then the actual key and value can be found on the key and value properties of the cursor object. If you want to keep going, then you have to call continue() on the cursor. When you&apos;ve reached the end of the data (or if there were no entries that matched your openCursor() request) you still get a success callback, but the result property is undefined.&lt;/p&gt; 
&lt;p&gt;One common pattern with cursors is to retrieve all objects in an object store and add them to an array, like this:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;const customers = [];

objectStore.openCursor().onsuccess = (event) =&amp;gt; {
  const cursor = event.target.result;
  if (cursor) {
    customers.push(cursor.value);
    cursor.continue();
  } else {
    console.log(`Got all customers: ${customers}`);
  }
};
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Note: Alternatively, you can use getAll() to handle this case (and getAllKeys()). The following code does precisely the same thing as above:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;objectStore.getAll().onsuccess = (event) =&amp;gt; {
  console.log(`Got all customers: ${event.target.result}`);
};
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;There is a performance cost associated with looking at the value property of a cursor, because the object is created lazily. When you use getAll() for example, the browser must create all the objects at once. If you&apos;re just interested in looking at each of the keys, for instance, it is much more efficient to use a cursor than to use getAll(). If you&apos;re trying to get an array of all the objects in an object store, though, use getAll().&lt;/p&gt; 
&lt;h3&gt;Using an index&lt;/h3&gt; 
&lt;p&gt;Storing customer data using the SSN as a key is logical since the SSN uniquely identifies an individual. (Whether this is a good idea for privacy is a different question, and outside the scope of this article.) If you need to look up a customer by name, however, you&apos;ll need to iterate over every SSN in the database until you find the right one. Searching in this fashion would be very slow, so instead you can use an index.&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;// First, make sure you created index in request.onupgradeneeded:
// objectStore.createIndex(&quot;name&quot;, &quot;name&quot;);
// Otherwise you will get DOMException.

const index = objectStore.index(&quot;name&quot;);

index.get(&quot;Donna&quot;).onsuccess = (event) =&amp;gt; {
  console.log(`Donna&apos;s SSN is ${event.target.result.ssn}`);
};
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;The &quot;name&quot; index isn&apos;t unique, so there could be more than one entry with the name set to &quot;Donna&quot;. In that case you always get the one with the lowest key value.&lt;/p&gt; 
&lt;p&gt;If you need to access all the entries with a given name you can use a cursor. You can open two different types of cursors on indexes. A normal cursor maps the index property to the object in the object store. A key cursor maps the index property to the key used to store the object in the object store. The differences are illustrated here:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;// Using a normal cursor to grab whole customer record objects
index.openCursor().onsuccess = (event) =&amp;gt; {
  const cursor = event.target.result;
  if (cursor) {
    // cursor.key is a name, like &quot;Bill&quot;, and cursor.value is the whole object.
    console.log(
      `Name: ${cursor.key}, SSN: ${cursor.value.ssn}, email: ${cursor.value.email}`,
    );
    cursor.continue();
  }
};

// Using a key cursor to grab customer record object keys
index.openKeyCursor().onsuccess = (event) =&amp;gt; {
  const cursor = event.target.result;
  if (cursor) {
    // cursor.key is a name, like &quot;Bill&quot;, and cursor.primaryKey is the SSN.
    // No way to directly get the rest of the stored object.
    console.log(`Name: ${cursor.key}, SSN: ${cursor.primaryKey}`);
    cursor.continue();
  }
};
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;Specifying the range and direction of cursors&lt;/h3&gt; 
&lt;p&gt;If you would like to limit the range of values you see in a cursor, you can use an IDBKeyRange object and pass it as the first argument to openCursor() or openKeyCursor(). You can make a key range that only allows a single key, or one that has a lower or upper bound, or one that has both a lower and upper bound. The bound may be &quot;closed&quot; (i.e., the key range includes the given value(s)) or &quot;open&quot; (i.e., the key range does not include the given value(s)). Here&apos;s how it works:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;// Only match &quot;Donna&quot;
const singleKeyRange = IDBKeyRange.only(&quot;Donna&quot;);

// Match anything past &quot;Bill&quot;, including &quot;Bill&quot;
const lowerBoundKeyRange = IDBKeyRange.lowerBound(&quot;Bill&quot;);

// Match anything past &quot;Bill&quot;, but don&apos;t include &quot;Bill&quot;
const lowerBoundOpenKeyRange = IDBKeyRange.lowerBound(&quot;Bill&quot;, true);

// Match anything up to, but not including, &quot;Donna&quot;
const upperBoundOpenKeyRange = IDBKeyRange.upperBound(&quot;Donna&quot;, true);

// Match anything between &quot;Bill&quot; and &quot;Donna&quot;, but not including &quot;Donna&quot;
const boundKeyRange = IDBKeyRange.bound(&quot;Bill&quot;, &quot;Donna&quot;, false, true);

// To use one of the key ranges, pass it in as the first argument of openCursor()/openKeyCursor()
index.openCursor(boundKeyRange).onsuccess = (event) =&amp;gt; {
  const cursor = event.target.result;
  if (cursor) {
    // Do something with the matches.
    cursor.continue();
  }
};
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Sometimes you may want to iterate in descending order rather than in ascending order (the default direction for all cursors). Switching direction is accomplished by passing prev to the openCursor() function as the second argument:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;objectStore.openCursor(boundKeyRange, &quot;prev&quot;).onsuccess = (event) =&amp;gt; {
  const cursor = event.target.result;
  if (cursor) {
    // Do something with the entries.
    cursor.continue();
  }
};
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;If you just want to specify a change of direction but not constrain the results shown, you can just pass in null as the first argument:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;objectStore.openCursor(null, &quot;prev&quot;).onsuccess = (event) =&amp;gt; {
  const cursor = event.target.result;
  if (cursor) {
    // Do something with the entries.
    cursor.continue();
  }
};
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Since the &quot;name&quot; index isn&apos;t unique, there might be multiple entries where name is the same. Note that such a situation cannot occur with object stores since the key must always be unique. If you wish to filter out duplicates during cursor iteration over indexes, you can pass nextunique (or prevunique if you&apos;re going backwards) as the direction parameter. When nextunique or prevunique is used, the entry with the lowest key is always the one returned.&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;index.openKeyCursor(null, &quot;nextunique&quot;).onsuccess = (event) =&amp;gt; {
  const cursor = event.target.result;
  if (cursor) {
    // Do something with the entries.
    cursor.continue();
  }
};
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Please see &quot;IDBCursor Constants&quot; for the valid direction arguments.&lt;/p&gt; 
&lt;h3&gt;Version changes while a web app is open in another tab&lt;/h3&gt; 
&lt;p&gt;When your web app changes in such a way that a version change is required for your database, you need to consider what happens if the user has the old version of your app open in one tab and then loads the new version of your app in another. When you call open() with a greater version than the actual version of the database, all other open databases must explicitly acknowledge the request before you can start making changes to the database (an onblocked event is fired until they are closed or reloaded). Here&apos;s how it works:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;const openReq = mozIndexedDB.open(&quot;MyTestDatabase&quot;, 2);

openReq.onblocked = (event) =&amp;gt; {
  // If some other tab is loaded with the database, then it needs to be closed
  // before we can proceed.
  console.log(&quot;Please close all other tabs with this site open!&quot;);
};

openReq.onupgradeneeded = (event) =&amp;gt; {
  // All other databases have been closed. Set everything up.
  db.createObjectStore(/* … */);
  useDatabase(db);
};

openReq.onsuccess = (event) =&amp;gt; {
  const db = event.target.result;
  useDatabase(db);
};

function useDatabase(db) {
  // Make sure to add a handler to be notified if another page requests a version
  // change. We must close the database. This allows the other page to upgrade the database.
  // If you don&apos;t do this then the upgrade won&apos;t happen until the user closes the tab.
  db.onversionchange = (event) =&amp;gt; {
    db.close();
    console.log(
      &quot;A new version of this page is ready. Please reload or close this tab!&quot;,
    );
  };

  // Do stuff with the database.
}
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;You should also listen for VersionError errors to handle the situation where already opened apps may initiate code leading to a new attempt to open the database, but using an outdated version.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>JanusGraph</title>
      <link>https://tedneward.github.io/Research/storage/janusgraph/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/janusgraph/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://janusgraph.org/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/janusgraph/janusgraph&quot;&gt;Website&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>JunoDB</title>
      <link>https://tedneward.github.io/Research/storage/junodb/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/junodb/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/paypal/junodb&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>kvass</title>
      <link>https://tedneward.github.io/Research/storage/kvass/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/kvass/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/maxmunzel/kvass&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;As in, run it from the CLI to store any binaries of desire.&lt;/p&gt; 
&lt;h2&gt;Simple usage&lt;/h2&gt; 
&lt;pre&gt;&lt;code&gt;$ kvass set hello world
$ kvass get hello
world

# enumerate keys
$ kvass ls
hello

# store arbitrary files
$ kvass set logo &amp;lt; kvass.jpg
$ kvass get logo &amp;gt; kvass.jpg


# Its trivial to set up and operate kvass across multiple devices
$ ssh you@yourserver.com kvass config show

Encryption Key:  	5abf59f5f1a2f3c998a4f592ce081a23e14a68fd8a792259c6ec0fc1e8fb1246  # &amp;lt;- copy this for the next step
ProcessID:       	752176921
Remote:          	(None)

$ kvass config key 5abf59f5f1a2f3c998a4f592ce081a23e14a68fd8a792259c6ec0fc1e8fb1246 # set the same key for all your devices
$ kvass config remote yourserver.com:8000 # tell kvass where to find the server instance

# Run &quot;kvass serve&quot; on your server using systemd, screen or the init system of your choice (runit, anyone?). You can specify the interface and port to host at with [--bind].

$ kvass serve --bind=&quot;0.0.0.0:80&quot; # host on the default HTTP port (which means you can generate cleaner URLs - just set your remote no port)

# every set will now be broadcasted to the server
$ kvass set &quot;hello from the other side&quot; hello
$ ssh you@yourserver kvass get &quot;hello from the other side&quot;
hello

# and every get will check the server for updates
$ ssh you@yourserver kvass set hello 👋
$ kvass get hello
👋

# Good to know: All communication between the client and server is authenticated and encrypted using AES-256 GCM.

# remember the file we stored earlier? Let&apos;s get a shareable url for it!
$ kvass url logo
http://demo.maxnagy.com:8000/get?q=OQMwTQmFCz6xiWxFxt4Mkw

# you can also print the corresponding qr code directly to your terminal
kvass qr logo
&lt;/code&gt;&lt;/pre&gt;
	</description>
    </item>
    <item>
      <title>Limbo</title>
      <link>https://tedneward.github.io/Research/storage/limbo/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/limbo/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/tursodatabase/limbo&quot;&gt;Source&lt;/a&gt; | &lt;a href=&quot;https://avi.im/blag/2024/faster-sqlite/&quot;&gt;Paper: “Serverless Runtime / Database Co-Design With Asynchronous I/O”&lt;/a&gt;&lt;/p&gt; 
&lt;h2&gt;Articles/Blog Posts&lt;/h2&gt; 
&lt;p&gt;&lt;a href=&quot;https://avi.im/blag/2024/faster-sqlite/&quot;&gt;&quot;In search of a faster SQLite&quot;&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>MapDB</title>
      <link>https://tedneward.github.io/Research/storage/mapdb/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/mapdb/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://mapdb.org/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/jankotek/mapdb/&quot;&gt;Source&lt;/a&gt; | &lt;a href=&quot;https://jankotek.gitbooks.io/mapdb/content/&quot;&gt;Docs&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Hello world:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;//import org.mapdb.*
DB db = DBMaker.memoryDB().make();
ConcurrentMap map = db.hashMap(&quot;map&quot;).make();
map.put(&quot;something&quot;, &quot;here&quot;);
&lt;/code&gt;&lt;/pre&gt;
	</description>
    </item>
    <item>
      <title>Memgraph</title>
      <link>https://tedneward.github.io/Research/storage/memgraph/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/memgraph/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://memgraph.com/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/memgraph/memgraph&quot;&gt;Source&lt;/a&gt; | &lt;a href=&quot;https://memgraph.com/docs&quot;&gt;Docs&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Docker run instructions:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;docker run -it -p 7687:7687 -p 3000:3000 memgraph/memgraph-platform
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;&lt;a href=&quot;https://memgraph.com/docs/memgraph/getting-started&quot;&gt;Getting Started&lt;/a&gt; instructions. Seems relatively standard.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Speaking.io</title>
      <link>https://tedneward.github.io/Research/speaking/speakingio/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">speaking/speakingio/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://speaking.io/&quot;&gt;Website&lt;/a&gt;&lt;/p&gt; 
&lt;h3&gt;Outline&lt;/h3&gt; 
&lt;ol&gt; 
 &lt;li&gt; &lt;p&gt;First: plan out your talk.&lt;/p&gt; 
  &lt;ol&gt; 
   &lt;li&gt;&lt;a href=&quot;https://speaking.io/plan/writing-a-cfp/&quot;&gt;Writing the CFP&lt;/a&gt;: The conference will have a Call For Papers. You&apos;ll need to write one.&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://speaking.io/plan/repetition/&quot;&gt;Repetition&lt;/a&gt;: Here&apos;s a trick of the trade: repetition. Repetition is a trick of the trade.&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://speaking.io/plan/number-of-slides/&quot;&gt;The Number of Slides&lt;/a&gt;: How many slides should you plan for?&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://speaking.io/plan/an-outline/&quot;&gt;Outlining&lt;/a&gt;: How do I get started on my talk?&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://speaking.io/plan/an-idea/&quot;&gt;The Idea&lt;/a&gt;: What should you talk about? What&apos;s a good topic for you?&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://speaking.io/plan/finding-a-talk/&quot;&gt;Finding Where to Talk&lt;/a&gt;: How do you even get started, anyway? Where can I give a talk?&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://speaking.io/plan/talks-are-entertainment/&quot;&gt;Talks are Entertainment&lt;/a&gt;: Public speaking&apos;s dirty little secret.&lt;/li&gt; 
  &lt;/ol&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Design and build your slides.&lt;/p&gt; 
  &lt;ol&gt; 
   &lt;li&gt;&lt;a href=&quot;https://speaking.io/design/typography/&quot;&gt;Typography&lt;/a&gt;: What do the words on your slides look like? Hint: they&apos;re probably a disaster.&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://speaking.io/design/transitions/&quot;&gt;Slide Transitions and Animations&lt;/a&gt;: What should your animations look like?&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://speaking.io/design/software/&quot;&gt;Software&lt;/a&gt;: What software should I build my slide deck with?&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://speaking.io/design/dimensions/&quot;&gt;Dimensions&lt;/a&gt;: Should your slides be 4:3 or widescreen?&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://speaking.io/design/color/&quot;&gt;Color&lt;/a&gt;: How do I choose a color scheme?&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://speaking.io/design/using-images/&quot;&gt;Using Images&lt;/a&gt;: Photos and clip art and images, oh my.&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://speaking.io/design/duplicating-objects/&quot;&gt;Duplicating Objects&lt;/a&gt;: Learn this one weird trick to build your slides quickly.&lt;/li&gt; 
  &lt;/ol&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Prep for the big day.&lt;/p&gt; 
  &lt;ol&gt; 
   &lt;li&gt;&lt;a href=&quot;https://speaking.io/prep/scoping-out-the-room/&quot;&gt;Scoping out the Room&lt;/a&gt;: You&apos;re just about to go up on stage. Scope the room out.&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://speaking.io/prep/recording-your-talk/&quot;&gt;Recording Your Talk&lt;/a&gt;: Think about recording your talk as practice, and for others.&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://speaking.io/prep/practicing-it/&quot;&gt;Practicing It&lt;/a&gt;: At some point you should practice. Quit putting it off, you know I&apos;m right.&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://speaking.io/prep/live-demos/&quot;&gt;Live Tech Demos&lt;/a&gt;: What&apos;s the best way to prepare a live demo in front of an audience?&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://speaking.io/prep/presenter-remotes/&quot;&gt;The Best Presenter Remotes&lt;/a&gt;: Thinking about controlling your slides with a remote?&lt;/li&gt; 
  &lt;/ol&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Deliver and do your thing.&lt;/p&gt; 
  &lt;ol&gt; 
   &lt;li&gt;&lt;a href=&quot;https://speaking.io/deliver/your-voice/&quot;&gt;Your Voice&lt;/a&gt;: How fast should you talk? How slow? How can you command your voice?&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://speaking.io/deliver/what-they-dont-tell-you-about-public-speaking/&quot;&gt;What They Don&apos;t Tell You&lt;/a&gt;: What are the things to think about that you won&apos;t think about?&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://speaking.io/deliver/remotes/&quot;&gt;Remotes&lt;/a&gt;: A quick little guide on navigating your deck with a remote.&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://speaking.io/deliver/nervousness/&quot;&gt;Dealing with Nervousness&lt;/a&gt;: Everyone gets nervous.&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://speaking.io/deliver/fucking-up/&quot;&gt;Fucking up&lt;/a&gt;: All the preparation in the world won&apos;t save you from a brainfart.&lt;/li&gt; 
  &lt;/ol&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;React and reflect on what just happened.&lt;/p&gt; 
  &lt;ol&gt; 
   &lt;li&gt;&lt;a href=&quot;https://speaking.io/react/sharing-your-talk-online/&quot;&gt;Sharing Your Talk Online&lt;/a&gt;: Turns out your biggest audience wasn&apos;t even in the room with you.&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://speaking.io/react/improving/&quot;&gt;Improving a Talk&lt;/a&gt;: C&apos;mon, you&apos;re not perfect. You probably messed something up.&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://speaking.io/react/handling-questions/&quot;&gt;Handling Questions&lt;/a&gt;: What&apos;s the trick behind Q&amp;amp;A after a talk?&lt;/li&gt; 
  &lt;/ol&gt; &lt;/li&gt; 
&lt;/ol&gt;
	</description>
    </item>
    <item>
      <title>The Kick Ass College Guide to Presentations</title>
      <link>https://tedneward.github.io/Research/speaking/kick-ass-guide-to-presentations/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">speaking/kick-ass-guide-to-presentations/index.html</guid>
      	<description>
	&lt;p&gt;&lt;em&gt;(by Brian Stampfl)&lt;/em&gt;&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Kick Ass Key Factor #1:&lt;/strong&gt; Know Your Stuff&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Kick Ass Key Factor #2:&lt;/strong&gt; Build Your Presentation So You Can&apos;t Forget Your Stuff&lt;/p&gt; 
&lt;h1&gt;Chapter 1: Becoming Bulletproof&lt;/h1&gt; 
&lt;p&gt;The difference between a good presentation and an awesome one is a small amount of extra work, attention to detail, and a willingness to take a chance.&lt;/p&gt; 
&lt;h1&gt;Chapter 2: Overcoming Fear&lt;/h1&gt; 
&lt;p&gt;Some basic generalizations of things that scare us when we set foot in front of a live audience:&lt;br&gt; 1. Participation is not an option; you&apos;re mandated to speak.&lt;br&gt; 2. Screwing up is equal to death. Embarrassment is a uniquely human emotion.&lt;br&gt; 3. Forgetting your own name.&lt;br&gt; 4. Stinking at presentations. This is a self-fulfilling prophecy.&lt;br&gt; 5. Generally unidentifiable fear.&lt;/p&gt; 
&lt;p&gt;Fear is a clue we need to prepare better.&lt;/p&gt; 
&lt;p&gt;Realizations:&lt;br&gt; * We&apos;re all friends here. Your classmates are your friends; everyone wants you to succeed; nobody cares if you make a mistake; they are worried about their own presentations, not you.&lt;br&gt; * Yeah, but I don&apos;t know these people. Strangers in the audience are one handshake from being your friend; the audience wants you to succeed; they don&apos;t care if you make a mistake; any audience wants to learn, be entertained, and be supportive.&lt;br&gt; * But I&apos;m worried what people will think.&lt;/p&gt; 
&lt;h1&gt;Chapter 3: Entertaining a Room Full of Lawyers&lt;/h1&gt; 
&lt;p&gt;The best presentations are actually performances.&lt;/p&gt; 
&lt;h1&gt;Chapter 4: Studying the Greats -- Develop Your Style&lt;/h1&gt; 
&lt;p&gt;Watch the pros, figure out what they&apos;re doing right. When you see something that grabs your attention, figure out a way to take that thing with you.&lt;/p&gt; 
&lt;h1&gt;Chapter 5: Where do I start?&lt;/h1&gt; 
&lt;p&gt;Answer three critical questions:&lt;br&gt; 1. How much time are you given for your presentation?&lt;br&gt; 2. What is your method of delivery? Flash cards; reading from something written; memorization; PowerPoint; group presentation&lt;br&gt; 3. What is your topic?&lt;/p&gt; 
&lt;h1&gt;Chapter 6: Brainstorming 101&lt;/h1&gt; 
&lt;p&gt;Brainstorming steps:&lt;br&gt; * Have pen and paper or whiteboard at the ready&lt;br&gt; * Agree that there are no dumb ideas; if an idea pops into your head, write it down&lt;br&gt; * As quickly as you can write, ark out ideas related to the general subject&lt;br&gt; * Use abbreviations if possible&lt;br&gt; * Write ideas down for at least ten minutes straight&lt;br&gt; * At the end of the brainstorm (ten minutes or end of the brain dump), pick out five topics that most closely fit what you need to speak about&lt;/p&gt; 
&lt;p&gt;Now split the topic down into smaller chunks. Narrowing will make it feel less daunting and more interesting.&lt;/p&gt; 
&lt;h1&gt;Chapter 7: Technically Speaking&lt;/h1&gt; 
&lt;p&gt;(Technical discussion of using PowerPoint for PC, Mac, etc)&lt;/p&gt; 
&lt;h1&gt;Chapter 8: The PowerPoint Build Begins&lt;/h1&gt; 
&lt;p&gt;Your PowerPoint is not the presentation&lt;/p&gt; 
&lt;p&gt;You&apos;ll never improve a poorly thought-out presentation by projecting garbage onto the screen.&lt;/p&gt; 
&lt;h1&gt;Chapter 9: The Rule of Three&lt;/h1&gt; 
&lt;p&gt;Expand each segment of your outline into three parts.&lt;/p&gt; 
&lt;p&gt;Example:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Beginning 
  &lt;ul&gt; 
   &lt;li&gt;Introduction: Yourself and the Topic 
    &lt;ul&gt; 
     &lt;li&gt;Name&lt;/li&gt; 
     &lt;li&gt;Short Bio&lt;/li&gt; 
     &lt;li&gt;Topic Name&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;Preview: Tell the Audience What to Expect 
    &lt;ul&gt; 
     &lt;li&gt;Describe the Problem&lt;/li&gt; 
     &lt;li&gt;Explain Popular Opinions&lt;/li&gt; 
     &lt;li&gt;Why to Think My Way&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;Historical Background: Ensures Everybody Knows the Backstory 
    &lt;ul&gt; 
     &lt;li&gt;In 1945, Thing Occurred&lt;/li&gt; 
     &lt;li&gt;Company &quot;X&quot; Responded This Way&lt;/li&gt; 
     &lt;li&gt;Today, the Problem is This&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Middle 
  &lt;ul&gt; 
   &lt;li&gt;Description of What is Happening in the World 
    &lt;ul&gt; 
     &lt;li&gt;This Thing is Occurring&lt;/li&gt; 
     &lt;li&gt;This is the Result&lt;/li&gt; 
     &lt;li&gt;Long-Term Ramifications&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;The Three Types of Learners: Auditory, Visual, Hands-On&lt;/p&gt; 
&lt;p&gt;The Three Types of Delivery: Bullet Points, Stories, Combination&lt;/p&gt; 
&lt;h1&gt;Chapter 10: How to Create Kick Ass Content&lt;/h1&gt; 
&lt;p&gt;Start with an Explosion: Grab attention right away. The Question; The Promise; The Unfinished Story; the Fascinating Facts.&lt;/p&gt; 
&lt;h1&gt;Chapter 11: How Many Slides Should I Create?&lt;/h1&gt; 
&lt;p&gt;You shouldn&apos;t be asking how many slides you should create, but rather how long will it take to go through the slides you&apos;ve created.&lt;/p&gt; 
&lt;p&gt;As a guideline, one slide for each minute you have to speak.&lt;/p&gt; 
&lt;p&gt;Building slides takes much longer than most people think. Be prepared to put in the time.&lt;/p&gt; 
&lt;h1&gt;Chapter 12: Building the Framework&lt;/h1&gt; 
&lt;p&gt;Ge the framework of your presentation built:&lt;br&gt; 1. Create a folder on your computer that contains all the pictures, logos, videos, and a copy of your outline. Importing all the information from one place makes things easier.&lt;br&gt; 2. Create as many blank slides as you need. Don&apos;t worry about making too many or not enough.&lt;br&gt; 3. Import all your photos. Don&apos;t worry about the order in which you bring them in, and don&apos;t worry about sizing or fine-tuning. Just get them into the slides.&lt;br&gt; 4. Import your video. Make sure that the original video is stored and remains in the same folder as Step 1.&lt;br&gt; 5. Copy and paste the lines of text from the outline into each slide.&lt;br&gt; 6. Arrange the slides.&lt;/p&gt; 
&lt;h1&gt;Chapter 13: Text&lt;/h1&gt; 
&lt;p&gt;DO NOT paste large blocks of text into your presentation. No audience wants to read a book projected onto a screen.&lt;/p&gt; 
&lt;p&gt;Text is not a way of conveying information to your audience, but visual cues and reminders of the information you&apos;re sharing with them.&lt;/p&gt; 
&lt;p&gt;PowerPoint is designed to support you, not carry you&lt;/p&gt; 
&lt;p&gt;Font Color: easiest color combo is black text on white background; most dark colored fonts should work well on a white background. Second best combo is white text on a black background--there isn&apos;t as much reflection from the screen.&lt;/p&gt; 
&lt;h1&gt;Chapter 14: Photograph File Size and Resolution&lt;/h1&gt; 
&lt;p&gt;Best bet is to adjust the images resolution so that the longest dimension is around 1k pixels. Use high quality photos in your presentation. Brighten up photos; projectors never project the same level of brightness as an LCD screen. Highlight details on a picture; insert objects such as circles or arrows into your slides to highlight the detail you want your audience to focus on.&lt;/p&gt; 
&lt;h1&gt;Chapter 15: Video&lt;/h1&gt; 
&lt;p&gt;Top four ways video can kill your presentation:&lt;br&gt; 1. Poor quality&lt;br&gt; 2. Lost in transfer&lt;br&gt; 3. Linking problems&lt;br&gt; 4. Not embedding videos&lt;/p&gt; 
&lt;h1&gt;Chapter 16: Transitions and Animations&lt;/h1&gt; 
&lt;p&gt;No amount of smoke and mirrors can make up for bad content. Avoid them.&lt;/p&gt; 
&lt;h1&gt;Chapter 17: Object Alignment&lt;/h1&gt; 
&lt;p&gt;It&apos;s important that the text on the slide aligns vertically into the same place as the text on the slide previous to it. Otherwise the text (or logo or whatever) will appear to be &quot;jumping&quot; from one slide to the next.&lt;/p&gt; 
&lt;p&gt;Visual balance: fill the frame. Think of composing the slide the same way we compose a photo.&lt;/p&gt; 
&lt;h1&gt;Chapter 18: Relevancy&lt;/h1&gt; 
&lt;p&gt;It may be time to remove some non-vital content. The reason presenters include irrelevant (crowd-pleasing) content is because the presenter is worried what they have to say is not interesting and they&apos;re afraid they might not please the crowd. Revisit your delivery. Are you presenting to the audience, or merely talking at them? Often the topic may not be particularly interesting in and of itself, but the passion, knowledge of the material, and delivery that makes it worth listening to.&lt;/p&gt; 
&lt;h1&gt;Chapter 19: Props&lt;/h1&gt; 
&lt;p&gt;Performance props: yet another means of relaying your message. It will remain in your control the entire time. While you may draw attention to the item you&apos;re using, you should not have to describe what the item is. The performance prop is a tool, and it becomes an extension of your story. No matter what your performance prop is, knowing ahead of time how you will hold the item, move with it, how you&apos;ll introduce it, and even when you might set the item down should all be thought out ahead of time. At a minimum, practice with your performance prop at least once or twice.&lt;/p&gt; 
&lt;p&gt;Show and Tell props: those items relevant to your topic that you will hold up to the audience and actually describe. The benefit of show-and-tell props is that you can present items to the audience that might otherwise be difficult to describe. Or the item might be so unique or personal that your mere possession of the item makes it special. You&apos;ll want to know ahead of time how you&apos;ll actually handle the item while you&apos;re speaking.&lt;/p&gt; 
&lt;h1&gt;Chapter 20: All the Gadgets&lt;/h1&gt; 
&lt;p&gt;Slide advancement: remote control or keyboard?&lt;/p&gt; 
&lt;p&gt;Microphones and podiums.&lt;/p&gt; 
&lt;p&gt;Laser pointers. Don&apos;t use them.&lt;/p&gt; 
&lt;h1&gt;Chapter 21: Room Configuration&lt;/h1&gt; 
&lt;p&gt;If you have any control where your audience will sit, you&apos;ll want them as far forward and close together as possible. By doing so, you&apos;ll improve the odds of a group dynamic occurring; for example, we know that laughter is contagious. What you want with your audience is connection: laughter is just one benefit of connection. Obtaining that connection with your audience is a major key to success.&lt;/p&gt; 
&lt;p&gt;Lights on or off? Ensure the screen image is not washed out. Keep a few lights on so that those taking notes can see.&lt;/p&gt; 
&lt;p&gt;Handouts. Pass them out early, keep them physically linked (stapled, bound, etc).&lt;/p&gt; 
&lt;h1&gt;Chapter 22: What Comes Out of Your Mouth&lt;/h1&gt; 
&lt;p&gt;Command Presence. Knowledge of Material, Solid Delivery, Passion. Command Presence is not a loud voice mowing over your audience. It&apos;s an attitude.&lt;/p&gt; 
&lt;p&gt;Know Your Stuff--But Don&apos;t Memorize Your Stuff. Memorizing your presentation is the equivalent of turning your presentation into a school play. Anyone who memorizes their script tends to sound as if they have memorized a script; it&apos;s very easy to detect and a turn-off for listeners. There is no built-in emotion, inflection, or motivation that would drive the characters; despite the speakers&apos; best efforts, the result is a monotone delivery. Those who memorize their material will often show signs of trying to recall the information. This usually presents itself in the form of the speaker looking up and to the left in an attempt to recall their next line. This will generally override any attempt to connect with your audience.&lt;/p&gt; 
&lt;h1&gt;Chapter 23: The Screen Is Not Your Audience&lt;/h1&gt; 
&lt;p&gt;While looking up/back at the screen, speakers will sometimes become mesmerized by their own images, or are simply too dependent on the notes they&apos;ve created for themselves. The speaker becomes drawn to the screen and forgets to turn back around and address their audience. The audience then has to look at the presenter&apos;s backside for the entire presentation. Glancing up to the screen for a few moments, and even directing your audience&apos;s attention to specific details is completely acceptable. But don&apos;t forget where your audience is sitting and be sure to speak to them.&lt;/p&gt; 
&lt;h1&gt;Never Read To Your Audience.&lt;/h1&gt; 
&lt;ul&gt; 
 &lt;li&gt;The Audience Knows How to Read; if you must put large amounts of text on the screen, let the audience read it themselves--direct their attention to the text, then give them time to do so.&lt;/li&gt; 
 &lt;li&gt;Most People Stink at Reading Out Loud.&lt;/li&gt; 
 &lt;li&gt;Large Amounts of Text Screams Laziness&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;Crutch words (ah, um, you know, etc)&lt;/p&gt; 
&lt;h1&gt;Chapter 24: Practice for Time&lt;/h1&gt; 
&lt;p&gt;Speed Kills: most people tend to speak faster than they realize when they&apos;re first learning the craft of public speaking.&lt;/p&gt; 
&lt;p&gt;Efficiency of Words: What you plan to say to your audience and what you actually say may turn out to be two different things. Your brain starts streamlining your message and speaking in your natural voice, abandoning all the extra words that you don&apos;t use in normal speech.&lt;/p&gt; 
&lt;p&gt;One More Question: Q&amp;amp;A can be the best parts of your presentation, but unless you are experienced with adjust your presentation time on the fly, hold off on all questions until the end.&lt;/p&gt; 
&lt;h1&gt;Chapter 25: Humor&lt;/h1&gt; 
&lt;p&gt;Humor comes with great risk!&lt;/p&gt; 
&lt;p&gt;Humor either works or it doesn&apos;t.&lt;/p&gt; 
&lt;p&gt;Know your audience&lt;/p&gt; 
&lt;p&gt;Stop the bleeding&lt;/p&gt; 
&lt;h1&gt;Chapter 26: Body Talk&lt;/h1&gt; 
&lt;p&gt;Your body needs to deliver your message as well as your words. The best way to counteract what your body might be saying outside your awareness is to take control of what your body is doing.&lt;/p&gt; 
&lt;p&gt;If public speaking scares us, our bodies are likely doing a fight-or-flight response.&lt;/p&gt; 
&lt;p&gt;The Distance to Here. Where you stand in relation to your audience will reflect your level of comfort and confidence. Closing the gap between the audience and ourselves is the opposite of what fear would have us do; the nervous person may find themselves creating distance from the audience as they search for some unidentified comfort zone. Luckily for us, most speaking environments limit the speaker&apos;s ability to step too far away.&lt;/p&gt; 
&lt;p&gt;Building Barriers. Placing an object between yourself and the audience is a primal response designed to protect us from a perceived threat. Shielding can be accomplished by standing behind the podium, a microphone stand, a table, or any object available to the speaker. Less obvious methods of shielding involve the speaker putting their hands into their pockets, the fig leaf pose, or folding their arms across their chest.&lt;/p&gt; 
&lt;p&gt;What Do I Do With My Hands? For Men: avoid standing with your hands folded over one another in front of your crotch--the fig leaf look is generally reserved for wedding photos; avoid contact with your body that could be described by the words picking or digging; refrain from any attempt to adjust your underwear; keep your hands away from your nose. For Women: women tend to overuse their hands and body to communicate--while the movements are generally natural, the line between conveying thought and aerobic workout is not always clear.&lt;/p&gt; 
&lt;p&gt;So what should you do with your hands? Let them move freely as you speak. Gestures will allow you to put emphasis on points, relay emotions, and even create imagery for your audience. Forcing your hands to remain at your sides or some other place will feel and look unnatural; once you allow yourself the freedom of movement, while avoiding the previously labeled pitfalls, you&apos;ll find that your audience will see you as being comfortable, and you&apos;ll feel more relaxed yourself.&lt;/p&gt; 
&lt;p&gt;Focus on Your Eyes. Scan Wide, Scan Deep; see the full width and depth of the crowd, so visualize the entire seating area divided into sections, and focus your attention on one section at a time, then move to the next. What Should I See? Pick out people that are looking directly at you; make eye contact with them, hold it for a few moments, then move on to the next person. Once that momentary contact is made, you&apos;ll know instinctively what impact you are having on that person.&lt;/p&gt; 
&lt;p&gt;Control Your Body. Be careful that walking around doesn&apos;t transition into pacing. Adjust your environment if necessary (within reason).&lt;/p&gt; 
&lt;h1&gt;Chapter 27: What Not To Wear&lt;/h1&gt; 
&lt;p&gt;Old People and Teachers Want You to Dress Nice. Look Like You Know What You&apos;re Talking About.&lt;/p&gt; 
&lt;h1&gt;Chapter 28: The Art of Audience Engagement&lt;/h1&gt; 
&lt;p&gt;Three Types of Crowds&lt;br&gt; * &lt;em&gt;The Hot Crowd:&lt;/em&gt; these are the fun ones, and require little or no work on your part to get them to participate.&lt;br&gt; * &lt;em&gt;The Warm Crowd:&lt;/em&gt; just good folks who are interested in hearing what you have to say, but didn&apos;t necessarily plan on being part of the presentation. You&apos;ll need to establish a rapport with these people before you can have a running dialogue with them.&lt;br&gt; * &lt;em&gt;The Cold Corpse Crowd:&lt;/em&gt; this is the type of audience that exists when attendance is mandated and the topics are of little interest to them. When asking a question of the crowd, be prepared that you may not get any responses. When this happens, simply be patient, stand quietly, and wait for a response. Scan the room and make eye contact with as many people as you can and wait. The waiting will serve three purposes: first, it will serve as a message to your audience that you will be posing questions to them and that you&apos;ll be standing by for answers; second, your pause will create an awkward tension in the room, and someone may say something just to break the tension; third, the pause will allow you to take advantage of the human brain&apos;s inability to not answer questions (the brain simply can&apos;t NOT answer a question if it&apos;s able to). Your job is to give the audience permission to say what they&apos;re thinking. Waiting for their answer is that permission.&lt;br&gt; * &lt;em&gt;Help! I can&apos;t crack this nut!&lt;/em&gt; If the audience refuses to interact with you, you&apos;ll simply need to interact with yourself.&lt;br&gt; Taming a Wild Audience. There&apos;s always a chance you&apos;ll encounter that one person who is dying to participate. Others are awkwardly inquisitive, some can&apos;t sit quietly for ten minutes, a few are obnoxious, and once in a while, the audience simply takes on a life of its own.&lt;br&gt; * &lt;em&gt;The Green Gorilla Guy.&lt;/em&gt; This is the person that asks the impossible hypothetical questions about your topic. (The term refers to the absurdity of the question itself.) Resolution: Keep in mind that although the question might sound goofy to you, the person may be sincere in asking. Not all things obvious to you are obvious to others. Sensitivity is key.&lt;br&gt; * &lt;em&gt;The Private Conversation Guy.&lt;/em&gt; This person will raise their hand not to ask questions about your topic, but rather to ask questions that are of personal interest to themselves only. Resolution: This one is easy since the person appears to have some interest in your expertise. Simply give a short, quick answer to their question and then invite them to speak with you at the end of the presentation.&lt;br&gt; * &lt;em&gt;I Have a Question, and a Better Answer Guy.&lt;/em&gt; Asking a question designed to offer an opportunity to show off the questioners&apos; own esoteric knowledge. Resolution: Some people are just dying for attention. The best approach to this problem is to publicly acknowledge the questioner&apos;s knowledge and redirect back to the presentation.&lt;br&gt; * &lt;em&gt;The Rowdy Crowd Takeover.&lt;/em&gt; Once in a while you&apos;ll come across a group that gets caught up in their own self-generated entertainment, cracking jokes back and forth. Resolution: Luckily, this silliness usually lasts for less than a minute. Have fun with it. Let it play out until the laughter dies down. Then break back in and continue on. If you experience repeat offenses to the point of disruption, let the audience know you have a limited amount of time and need to continue on.&lt;br&gt; * &lt;em&gt;The Non-Stop Question Guy.&lt;/em&gt; Resolution: Once you see the pattern, redirect that person&apos;s questions to the end of the presentation.&lt;br&gt; * &lt;em&gt;The Confronter.&lt;/em&gt; This person takes advantage of having the attention of a large group of people to address their personal needs or complaints. Resolution: acknowledge the confronter&apos;s concerns as legitimate, bring it back around to the larger topic in general (leaving open room for discussion or dissent), and invite the confronter to discuss the issue privately following the event.&lt;/p&gt; 
&lt;h1&gt;Chapter 29: Crash and Burn--When Things Go Wrong&lt;/h1&gt; 
&lt;p&gt;What the crowd don&apos;t know, the crowd don&apos;t know. Fix or dismiss the problem. Move on. The audience doesn&apos;t care if you make a mistake. They want you to succeed.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>The Ultimate Public Speaking Survival Guide</title>
      <link>https://tedneward.github.io/Research/speaking/ultimate-public-speaking-survival-guide/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">speaking/ultimate-public-speaking-survival-guide/index.html</guid>
      	<description>
	&lt;p&gt;&lt;em&gt;(by Ramakrishna Reddy)&lt;/em&gt;&lt;/p&gt; 
&lt;h1&gt;Chapter 1: Psychological Barriers&lt;/h1&gt; 
&lt;p&gt;Public speaking is overwhelming; how can I understand it in simple terms? Did you know how the drive the first time you drove a car? You start off learning primary activities such as acceleration, braking, changing gears, and so on; in speaking, you learn primary activities such as content creation, eye contact, voice modulation, hand gestures, facial expressions, stance and so on. In order to make the drive interesting and enjoyable, you can equip your vehicle with stereo system, adjustable seats, etc; in speaking, you can tell stories, create humor and use visual aids. When driving, unless you know where you are going, you waste yours and your passengers&apos; time; if you do not have a purpose in mind when you speak, you do the same.&lt;/p&gt; 
&lt;p&gt;Fear strikes me whenever I want to give a presentation; what should I do? Fear strikes everyone. You must start by accepting that the fear of public speaking is the fear of the unknown and fear of ridicule. Write down your questions/fears and examine them.&lt;/p&gt; 
&lt;p&gt;What will other people think if I make a mistake during my presentation? People respect you when you speak in front of an audience. People only think about you as much as you think they think of you. Two secrets: Speak as often as possible and at every given opportunity; take the time to reflect on every experience by asking what went right, what went wrong, and for suggestions on how to do it better next time.&lt;/p&gt; 
&lt;p&gt;Can I really sizzle on stage even though I don&apos;t have an eye-catching look? Yes.&lt;/p&gt; 
&lt;p&gt;Even though speaking comes naturally to me, do I still need to prepare my presentation? Yes. Do not assume that you need not prepare because you have notes; you have to be comfortable with your content. Your words must roll smoothly off your tongue.&lt;/p&gt; 
&lt;p&gt;Can I still give an effective presentation without a strong vocabulary? Using simple words that we speak in day-to-day conversations is the secret to a well-received presentation. Your audience will judge you based on the value of what you say, rather than the glamor of your words.&lt;/p&gt; 
&lt;h1&gt;Chapter 2: Speech Creation&lt;/h1&gt; 
&lt;p&gt;I know my topic but I feel stuck; what am I missing? Feeling stuck will stop you from taking action. What is the purpose of the presentation (general-purpose (inform, entertain, persuade or inspire), and specific)? A specific purpose should be clear, short and add value to your audience. It is very important to determine your specific purpose. A simple way to formulate your specific purpose is by knowing what you want your audience to feel, think or do after your presentation.&lt;/p&gt; 
&lt;p&gt;How do I start creating content for my presentation? Basic skeletal structure: an opening, context setting, key points, support points, application, summary, and conclusion.&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Opening is what you say in the first 30/60 seconds.&lt;/li&gt; 
 &lt;li&gt;Context setting is explaining what you are going to tell them. Sometimes this part gets merged into your opening.&lt;/li&gt; 
 &lt;li&gt;Key points help to reinforce the specific purpose of your talk. 3-4 key points per talk.&lt;/li&gt; 
 &lt;li&gt;Supporting points substantiate or prove a key point. Use stories, statistics, illustrations, or facts for support.&lt;/li&gt; 
 &lt;li&gt;Application tells the audience how to apply the key point.&lt;/li&gt; 
 &lt;li&gt;Summary drives home what you have told them and recaps your presentation.&lt;/li&gt; 
 &lt;li&gt;Conclusion is the showstopper for your presentation. Final 30/60 seconds of your talk.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;How do I create a killer opening for my talk? The first 30/60 seconds of your presentation determines how well the rest of the presentation will go. Four keys for a killer opening:&lt;/p&gt; 
&lt;ol&gt; 
 &lt;li&gt;Start with a current observation about your surroundings and the occasion for which you are speaking.&lt;/li&gt; 
 &lt;li&gt;Start with a question.&lt;/li&gt; 
 &lt;li&gt;Start with a startling statistic.&lt;/li&gt; 
 &lt;li&gt;Start with a personal story or experience.&lt;/li&gt; 
&lt;/ol&gt; 
&lt;p&gt;Some specific strategies: take a few seconds to scan your audience before uttering the opening words; do not start with fillers like &quot;the weather is good&quot; or &quot;what a sunny day&quot;; build trust, be open to your audience, by using open palms and a gentle voice to open up and start building trust; listen to your audience and acknowledge any response; be relaxed and comfortable; make them like you by not showing a know-it-all attitude; tone down the entertainment factor for a business presentation.&lt;/p&gt; 
&lt;p&gt;What is a context setting and how do I create one? Telling your audience what you are going to tell them; a promise you will eventually fulfill or a problem that you can solve during your speech. Specific steps:&lt;/p&gt; 
&lt;ol&gt; 
 &lt;li&gt;Context should be audience-focused; the audience should feel it is about them.&lt;/li&gt; 
 &lt;li&gt;Context should be clear and specific; the audience should be able to clearly understand your agenda.&lt;/li&gt; 
 &lt;li&gt;Go even further and add a specificity factor.&lt;/li&gt; 
&lt;/ol&gt; 
&lt;p&gt;How do I select the key points for my presentation? Interview and audience analysis.&lt;/p&gt; 
&lt;p&gt;How do I support the key points of my presentation? Aristotle says that an effective speech has three key elements: ethos (the credibility of the speaker), logos (the reasoning behind the point), and pathos (the emotional attachment between the speaker and the audience). Use stories, statistics, facts, illustration (PowerPoint, Props, Writing board, Questions and facts).&lt;/p&gt; 
&lt;p&gt;How to create a compelling story? Stories have the ability to transfer emotions. Elements to a powerful story:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt; &lt;p&gt;Must-have elements&lt;/p&gt; 
  &lt;ul&gt; 
   &lt;li&gt;Conflict&lt;/li&gt; 
   &lt;li&gt;A character with a desire (hero/heroine)&lt;/li&gt; 
   &lt;li&gt;Obstacles in that path&lt;/li&gt; 
   &lt;li&gt;Overcoming obstacles&lt;/li&gt; 
   &lt;li&gt;The point&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Good-to-have elements&lt;/p&gt; 
  &lt;ul&gt; 
   &lt;li&gt;Event setting -- the time and place&lt;/li&gt; 
   &lt;li&gt;Character building -- what the characters look like, their vulnerabilities, etc&lt;/li&gt; 
   &lt;li&gt;Dialogue -- what the characters say to each other&lt;/li&gt; 
   &lt;li&gt;Humor -- optional, but humor makes a story more compelling&lt;/li&gt; 
   &lt;li&gt;Emotion -- knowing what the characters are feeling can make the difference between a good story and a great story&lt;/li&gt; 
   &lt;li&gt;Sensory words -- words that evoke the senses of touch, sound, smell, vision, taste&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;How do I best use transitions in my speech? Transitions maintain a smooth and clear flow between points in the speech. If the speech is a journey, transitions are the signboards. Transitions can be verbal, non-verbal (movement, pause, prompted gestures), or a combination of the two.&lt;/p&gt; 
&lt;p&gt;How can I have an effective summary? Do&apos;s and Don&apos;ts for effective Q&amp;amp;A:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Do take a pause and answer straight to the point.&lt;/li&gt; 
 &lt;li&gt;Do clarify any question which isn&apos;t clear. Reiterate the question to the audience.&lt;/li&gt; 
 &lt;li&gt;Do confirm your answer to all questions by saying, &quot;Does that make sense?&quot; or &quot;Does that answer your question?&quot;&lt;/li&gt; 
 &lt;li&gt;Do act confident. You might not know all the answers but you can get the answers.&lt;/li&gt; 
 &lt;li&gt;Don&apos;t try to be a know-it-all. If you are not sure, say so; but you can always go find out and get back to them.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;How do I create a memorable conclusion for my speech? Seven ideas to a memorable conclusion:&lt;/p&gt; 
&lt;ol&gt; 
 &lt;li&gt;Best Wishes Close&lt;/li&gt; 
 &lt;li&gt;Gratitude Close&lt;/li&gt; 
 &lt;li&gt;Answer Close -- if your presentation opens with a question, answer it&lt;/li&gt; 
 &lt;li&gt;Action Close -- call to action&lt;/li&gt; 
 &lt;li&gt;Dialogue Close&lt;/li&gt; 
 &lt;li&gt;Poem Close&lt;/li&gt; 
 &lt;li&gt;Circular Close -- bring the audience back to the starting point&lt;/li&gt; 
&lt;/ol&gt; 
&lt;p&gt;How do I refine my speech content? Four tools to refine your content:&lt;/p&gt; 
&lt;ol&gt; 
 &lt;li&gt;Choose simple words with the fewest syllables&lt;/li&gt; 
 &lt;li&gt;Use active voice&lt;/li&gt; 
 &lt;li&gt;Repeat key phrases&lt;/li&gt; 
 &lt;li&gt;Use rhetorical devices (similes, metaphors, alliterations)&lt;/li&gt; 
&lt;/ol&gt; 
&lt;h1&gt;Chapter 3: Speech Delivery&lt;/h1&gt; 
&lt;p&gt;I know my content very well, so do I really need to care about anything else? Yes; what are your miscommunications? Bad (nervous) habits?&lt;/p&gt; 
&lt;p&gt;How should I move during my presentation? Posture--straighten your back and head, broaden your shoulders, stand with firm footing. Movement--speakers should move only when they want to communicate an idea. Movement helps in the following areas:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Transition: transition from one point to another&lt;/li&gt; 
 &lt;li&gt;Drama: depict the actual movement that happens in a scene&lt;/li&gt; 
 &lt;li&gt;Increase impact: putting a strong foot forward to convey an important and strong point, etc&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;How do I make effective eye contact? While practicing your speech, close your eyes. Imagine your audience in your mind. Divide into quadrants. Imagine talking to one person in the first quadrant, looking them in the eye, for 5 to 10 seconds. Move to the second quadrant: find a person, look them in the eye for 5 to 10 seconds. Third, fourth, repeat.&lt;/p&gt; 
&lt;p&gt;Is there a simple way to improve the quality of my voice? How to...&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;... sound clear: speak every word with clarity. Make sure you pronounce every syllable of each word. Complete every word before you go on to the next word. Make sure you enunciate the endings of words properly. Make sure you maintain breath and energy throughout the sentence.&lt;/li&gt; 
 &lt;li&gt;... find your optimum tone: Practice your speech in a tone that you would use with a friend. Then gradually increase your tone from soft to loud. When you feel that your voice feels natural and resonant, that&apos;s your optimum tone.&lt;/li&gt; 
 &lt;li&gt;... control the pace of your speech: the human ear can grasp words easily when spoken at a range of 120 to 160 words per minute. Find your current pace of speech (start reading content and stop the timer after 1 minute) and adjust accordingly. Note that certain parts of the speech work great if spoken slowly.&lt;/li&gt; 
 &lt;li&gt;... pause effectively: practice pausing. Pauses help you connect with the audience, build anticipation before you deliver the punch line, gives time for the audience to laugh after you deliver the punch line, acts as a signal that you are going to say something very important, gives time for the audience to reflect on an important point, and acts as a transition tool for moving from one point to another.&lt;/li&gt; 
 &lt;li&gt;... use emotion: Feel the emotion in your heart before you express it through words.&lt;/li&gt; 
 &lt;li&gt;... say dialogue or monologue: use the emotion and attitude of the person speaking in the dialogue/monologue. You have to clearly distinguish the characters in a dialogue.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;How do I use my hands during the presentation? Two forms of gestures: emphatic and non-emphatic. Emphatic gestures are gestures to emphasize any point. Non-emphatic gestures help you describe an object/character, prompt the audience or depict the scene. Practice gestures until you internalize or have your speech in muscle memory. Video-record your speech; observe your gestures. Be comfortable enough on stage that you don&apos;t need to gesture--not gesturing (keeping your hands to your side) can add impact to certain parts of your presentation. Learning to speak without any gesture is a great skill to master.&lt;/p&gt; 
&lt;p&gt;How to create correct facial expressions during the presentation? Facial expressions communicate a lot more than what you say verbally. Practice the content, then consciously allow the emotions to flow on your face.&lt;/p&gt; 
&lt;h1&gt;Chapter 4: Preparation Steps&lt;/h1&gt; 
&lt;p&gt;How can I create and maintain my connection with the audience? Tools for creating a connection:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Your introduction. Plays a crucial role to build likability and trust. What expertise you bring to the table; why are you qualified to speak, without ego-boosting. How you can help your audience. An interest apart from the topic or any light remark.&lt;/li&gt; 
 &lt;li&gt;Use the pronouns you/we. Have as many &quot;you&quot;-focused sentences as possible. Frame content in such a way that you transition and involve the audience using &quot;you&quot; or &quot;we&quot; so that they understand that you care for them.&lt;/li&gt; 
 &lt;li&gt;Speak in the third person. Minimize the use of &quot;I&quot;. Unless it is your own original thought, realization, finding, experience or learning, do not use &quot;I&quot;. If the idea or teaching is someone else&apos;s, use him/her in the reference. My (your) job is to simplify and spread the information. This helps in establishing your credibility.&lt;/li&gt; 
 &lt;li&gt;Be sincere.&lt;/li&gt; 
 &lt;li&gt;Maintain genuine eye contact. Eyes are doorways to form connection. While presenting, there is a tendency for your eyes to glaze over the audience, but the moment you talk with an audience, you develop a deeper bonding.&lt;/li&gt; 
 &lt;li&gt;Engage your audience. Ask interactive questions. Invite a few of them to the stage. Create a group activity.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;Is there a particular strategy to ensure that the audience will continue to listen? If you are looking for just one strategy in particular that will ensure an audience will continue to listen to you, then, ENTERTAIN! If you entertain well, the audience can&apos;t stop loving you. Try self-deprecating humor; the audience will respect your more because you are ready to let your guard down and poke fun at yourself.&lt;/p&gt; 
&lt;p&gt;What is the final checkpoint, before I freeze my content? The most important part in your content preparation is the clarity of your presentation.&lt;/p&gt; 
&lt;p&gt;Can the venue affect my presentation? Yes, in various ways:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Venue type: board room? Classroom-style? Auditorium?&lt;/li&gt; 
 &lt;li&gt;Time limit: are you going to be timed by someone else or will you manage it by yourself?&lt;/li&gt; 
 &lt;li&gt;Projector: check if the venue has a projector&lt;/li&gt; 
 &lt;li&gt;Audience seating position: audience is seated for making connection through eye contact; audience is concentrated together and not scattered (Never leave empty chairs for a presentation; energy dissipates in emptiness.)&lt;/li&gt; 
 &lt;li&gt;Acoustics&lt;/li&gt; 
 &lt;li&gt;Audibility: verify audibility with a friend/colleague by having them sit in all corners of the room&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;Can you give me the exact steps to practice my speech? Steps for practice:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Stand straight with firm footing. Keep your spine and head straight.&lt;/li&gt; 
 &lt;li&gt;Keep your hands at your sides with your fingers slightly curled.&lt;/li&gt; 
 &lt;li&gt;Keep your feet at around 8-12 inches distant from each other&lt;/li&gt; 
 &lt;li&gt;Don&apos;t worry about eye contact yet&lt;/li&gt; 
 &lt;li&gt;Practice your speech content until it smoothly rolls off your tongue. Refactor content if necessary.&lt;/li&gt; 
 &lt;li&gt;Check for any distracting mechanisms in your current speech.&lt;/li&gt; 
 &lt;li&gt;Next, practice by speaking your content in loud, soft, slow and at least in a fast tone. Make sure to enunciate the words clearly. Complete every word before going to the next.&lt;/li&gt; 
 &lt;li&gt;Check if you are starting the sentences in high energy and ending them in low energy.&lt;/li&gt; 
 &lt;li&gt;Start focusing on internalizing your speech. You should be able to tell the content even if somebody wakes you up in the middle of the night.&lt;/li&gt; 
 &lt;li&gt;If you are planning to pause at certain places in your talk, practice those pauses deliberately.&lt;/li&gt; 
 &lt;li&gt;Feel the emotion in your heart and practice.&lt;/li&gt; 
 &lt;li&gt;Ask a friend to give feedback on the relevance of your facial expressions to the intent of your speech&lt;/li&gt; 
 &lt;li&gt;Work on your eye contact; use the quadrant strategy in your imagination&lt;/li&gt; 
 &lt;li&gt;Let your hand gestures flow naturally. Practice the following rules of thumb: use open palms; do not point at the audience; move hands from shoulder level; stroke at the right word&lt;/li&gt; 
 &lt;li&gt;Work on your movements. Check your footwork; determine at what point of the stage you would be at different parts of your presentation.&lt;/li&gt; 
 &lt;li&gt;If you are using PPT, practice by sequencing the slides. Practice by asking your friend to navigate the slides for you. Or use a remote control for it.&lt;/li&gt; 
 &lt;li&gt;Rehearse by incorporating all the steps.&lt;/li&gt; 
 &lt;li&gt;Give a complete rehearsal to your close friends, family or others.&lt;/li&gt; 
 &lt;li&gt;Keep repeating the steps&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;Can you give me a strategy for not going blank on stage? If the speech is in muscle memory, then you will be excited and ready. You will not blank.&lt;/p&gt; 
&lt;h1&gt;Chapter 5: Presentation Day Steps&lt;/h1&gt; 
&lt;p&gt;How to dress for my presentation? Groom well.&lt;/p&gt; 
&lt;p&gt;Is there a checklist for the presentation day? Suggestions:&lt;/p&gt; 
&lt;p&gt;Before going to the venue:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Do eat light food. Breads and salads; you need energy to show energy in your presentation&lt;/li&gt; 
 &lt;li&gt;Do charge your laptop beforehand. Take your charger. If you have a PPT, have a backup.&lt;/li&gt; 
 &lt;li&gt;Do take a cab/car instead of public transport. If you are going to drive, start early to avoid traffic jams and parking problems&lt;/li&gt; 
 &lt;li&gt;Do hang around with a supportive friend. You need someone to bounce your content off. You will feel less stressful if there is a dependable person with you.&lt;/li&gt; 
 &lt;li&gt;Do reach the venue early.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;After going to the venue:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Do chat with the presentation planner and check the venue setting&lt;/li&gt; 
 &lt;li&gt;Do check if the projector is working. Try to display your PPT.&lt;/li&gt; 
 &lt;li&gt;Do check if you have a proper writing board and a working marker (if you are going to use one)&lt;/li&gt; 
 &lt;li&gt;Do check for arrangement of chairs. Check if the number of chairs is in accordance with the number of people who have confirmed their presence.&lt;/li&gt; 
 &lt;li&gt;Do not forget to check the temp for the A/C.&lt;/li&gt; 
 &lt;li&gt;Do test the microphone&lt;/li&gt; 
 &lt;li&gt;Do video-record your presentation. Ask a friend/colleague to record. Or ask the presentation planner to record.&lt;/li&gt; 
 &lt;li&gt;Do check for any distraction because of the lighting. Are the lights falling on your eyes? Take a call on whether you want the lights on or off during your presentation.&lt;/li&gt; 
 &lt;li&gt;Do remind the presentation planner or the anchor to ask the audience members to keep their cell phones on silent&lt;/li&gt; 
 &lt;li&gt;Do not forget to hand over a copy of your introduction to the planner or anchor&lt;/li&gt; 
 &lt;li&gt;Do not forget to reach out and greet your audience members as they enter the venue&lt;/li&gt; 
 &lt;li&gt;Do converse with your audience after your greetings. Ask questions on what brings them there. Keep it quick and move on; it has to be natural&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;What if my heart starts pounding, ears get heated and hands become cold, 10 minutes before the presentation? Steps to tackle last-minute anxiety:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Rub your left palm with your right hand for 10-15 seconds. Reverse.&lt;/li&gt; 
 &lt;li&gt;Slowly, breathe in and breathe out.&lt;/li&gt; 
 &lt;li&gt;If necessary, go to a private corner where no one is around and do some vigorous punching and kicking in the air. This boosts energy and excitement.&lt;/li&gt; 
 &lt;li&gt;Read (and answer) the following questions: What is my intent? Am I present? Will I have fun? How would I give this presentation if I knew this was the one ever?&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;How do I carry myself from seat to stage, once the anchor calls my name? Get up from your seat and spring to the stage; show enthusiasm because it is contagious. Wear a smile while you walk. As soon as you take position on stage, do not start off right away; instead, attract everyone&apos;s attention and create the connection before you start your speech. Stand and scan the audience for a good 4 to 5 seconds--your audience will stop doing other things and start focusing on you. Then begin.&lt;/p&gt; 
&lt;p&gt;How do I handle myself during the actual presentation? Be present. Be passionate. Be energetic.&lt;/p&gt; 
&lt;p&gt;How do I handle any unexpected problems during the actual presentation? Do not get flustered. Know that your audience will empathize if there is a problem and always want you to do well. Some example scenarios:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Losing train of thought. Strategies for bouncing back: have some stock lines in place that can be used in case you lose your train of thought; even if you forget, do not try to go back and share the missed portion; remember the structure, instead of the words.&lt;/li&gt; 
 &lt;li&gt;Power shuts down. Just be cool.&lt;/li&gt; 
 &lt;li&gt;Cell phone ringing. Keep a few lines ready to create humor: &quot;Tell your friend that I will call him later.&quot;&lt;/li&gt; 
 &lt;li&gt;Latecomer to your presentation. Ignore it, or be ready with some humor if it disrupts the talk.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;How do I carry myself off the stage after my presentation? After you say the last words, pause, smile, say goodbye internally, the audience will understand. Pass control to the anchor or MC. While you turn and walk off the stage, show genuine enthusiasm.&lt;/p&gt; 
&lt;p&gt;What should I do after the presentation? Reflect. Get audience feedback. Give your own feedback. Analyze your video.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Presentation Patterns</title>
      <link>https://tedneward.github.io/Research/speaking/presentation-patterns/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">speaking/presentation-patterns/index.html</guid>
      	<description>
	&lt;p&gt;&lt;em&gt;(by Neal Ford, Matthew McCullough, Nate Schutta)&lt;/em&gt;&lt;/p&gt; 
&lt;h1&gt;Part 1: Prepare&lt;/h1&gt; 
&lt;h2&gt;Chapter 1: Presentation Prelude Patterns&lt;/h2&gt; 
&lt;h3&gt;Pattern: Know Your Audience&lt;/h3&gt; 
&lt;p&gt;Preparing a great presentation is lost if you present it to the “wrong” audience. Seek data on your attendees; their occupations, relative ages, comfort level with the material, and general background. Tune your material to match as many of the attending demographics as possible.&lt;/p&gt; 
&lt;h3&gt;Pattern: Social Media Advertising&lt;/h3&gt; 
&lt;p&gt;Our current digital age has shifted the focus of marketing presentations from printed flyers and bulletin boards to Twitter, Facebook, blog posts, and e-mails. Presenters should aggressively utilize free and low-cost avenues to advertise their talk in an effort to increase attendance, ticket sales, or just general awareness, all of which can manifest as greater credibility for the presenter.&lt;/p&gt; 
&lt;h3&gt;Pattern: Required&lt;/h3&gt; 
&lt;p&gt;A command performance presents unique challenges and added stress. Unless the topic is near and dear to your heart, you may have to manufacture motivation and interest.&lt;/p&gt; 
&lt;h3&gt;Pattern: The Big Why&lt;/h3&gt; 
&lt;p&gt;You should be clear with yourself and to your audience as to why you’re giving this talk. It is a critical foundation for the vector you are using to address this talk’s topic. Clarifying your motivation does not rule out giving a talk for money, as advertising, to educate, or just to inspire.&lt;/p&gt; 
&lt;h3&gt;Pattern: Proposed&lt;/h3&gt; 
&lt;p&gt;Most presenters are required to submit a talk title, abstract, topic outline, and perhaps even samples of past work in video or PDF form. The most common ways to get into a conference—paying attention to the details and presenting a polished proposal—increase your odds your talk will be accepted.&lt;/p&gt; 
&lt;h3&gt;Antipattern: Abstract Attorney&lt;/h3&gt; 
&lt;p&gt;An abstract attorney is someone who takes the description of the presentation from the formal conference brochure way too seriously. They’ll often comment (negatively) on any and all deviations from the abstract either during the talk (in the form of an often condescending question) or afterward on session evaluations or on social media.&lt;/p&gt; 
&lt;h2&gt;Chapter 2: Creativity Patterns&lt;/h2&gt; 
&lt;h3&gt;Pattern: Narrative Arc&lt;/h3&gt; 
&lt;p&gt;Presentations are a form of storytelling; don’t ignore a few thousand years of oratory history. A Narrative Arc is a common trope; organizing your presentation in a similar way leverages your audience’s lifetime of story listening experience.&lt;/p&gt; 
&lt;h3&gt;Pattern: Fourthought&lt;/h3&gt; 
&lt;p&gt;Don’t rush to use a presentation tool when building a presentation. The four stages of creating a presentation are ideation, capture, organize, and design.&lt;/p&gt; 
&lt;h3&gt;Pattern: Crucible&lt;/h3&gt; 
&lt;p&gt;The act of constructing the presentation differs from presenting the presentation. The presentation will change (sometimes drastically) under the pressure of presenting it.&lt;/p&gt; 
&lt;h3&gt;Pattern: Concurrent Creation&lt;/h3&gt; 
&lt;p&gt;Presentation materials don’t need to be created in the same order as they are found in the presentation. Craft the material in the order that fits; no one will know you did things out of sequence.&lt;/p&gt; 
&lt;h3&gt;Pattern: Triad&lt;/h3&gt; 
&lt;p&gt;Your audience can only absorb a certain amount of material in a short time. If you limit your presentation to three main talking points, it allows you to cover them thoroughly without overwhelming your audience.&lt;/p&gt; 
&lt;h3&gt;Pattern: Expansion Joints&lt;/h3&gt; 
&lt;p&gt;Building a presentation for one (and only one) length is a missed opportunity. Crafting short-, medium-, and full-length versions of your talk provides additional opportunities for delivery and simplifies adapting to shorter windows if the promised time slot is cut short.&lt;/p&gt; 
&lt;h3&gt;Pattern: Talklet&lt;/h3&gt; 
&lt;p&gt;Instead of doing an hour-long presentation, do three semirelated 20-minute talks. This allows great flexibility for time, content, and narrative flow.&lt;/p&gt; 
&lt;h3&gt;Pattern: Unifying Visual Theme&lt;/h3&gt; 
&lt;p&gt;Use a common, repeating visual element to tie together the disparate parts of your presentation.&lt;/p&gt; 
&lt;h3&gt;Pattern: Brain Breaks&lt;/h3&gt; 
&lt;p&gt;Research suggests that the average adult attention span is about 20 minutes. Plan something that breaks the concentration coma: humor, a story, something titillating, audience participation, and so on roughly every 10 to 20 minutes. Reengage your audience or lose them to their smartphones.&lt;/p&gt; 
&lt;h3&gt;Antipattern: Alienating Artifact&lt;/h3&gt; 
&lt;p&gt;An alienating artifact is something that disenfranchises an audience member or audience members from the topic at hand. This can take the form of an image, a quote, or offensive language.&lt;/p&gt; 
&lt;h3&gt;Antipattern: Celery&lt;/h3&gt; 
&lt;p&gt;Just like the vegetable, a celery talk is one that expends more effort chewing (processing) on the part of the audience member than they get back in calories or value and new materials learned.&lt;/p&gt; 
&lt;h3&gt;Pattern: Leet Grammars&lt;/h3&gt; 
&lt;p&gt;Leet Grammars refers to correctly using appropriate slang, jargon, and other “insider” colloquialisms in your presentation to bond with your audience.&lt;/p&gt; 
&lt;h3&gt;Pattern: Lightning Talk&lt;/h3&gt; 
&lt;p&gt;Lightning Talk is a timed presentation, usually five minutes long and optionally constrained by aspecific number of slides. In many formats, the slides advance automatically.&lt;/p&gt; 
&lt;h3&gt;Pattern: Takahashi&lt;/h3&gt; 
&lt;p&gt;Takahashi is a stylized talk format originated by Masoyoshi Takahashi (and popularized in the West by Laurence Lessig) that uses one or two words per slide but transitions through them very quickly.&lt;/p&gt; 
&lt;h3&gt;Pattern: Cave Painting&lt;/h3&gt; 
&lt;p&gt;Use a huge sectioned canvas with your presentation laid out linearly, zooming in on the constituent sections as you proceed through your presentation.&lt;/p&gt; 
&lt;h1&gt;Part 2: Build&lt;/h1&gt; 
&lt;h2&gt;Chapter 3: Slide Construction Patterns&lt;/h2&gt; 
&lt;h3&gt;Antipattern: Cookie Cutter&lt;/h3&gt; 
&lt;p&gt;Ideas don’t have a predetermined word count and accordingly you shouldn’t artificially pad content to make it appear to fill a slide. No law says that every thought worth having will fit on a single slide, so stop trying.&lt;/p&gt; 
&lt;h3&gt;Pattern: Coda&lt;/h3&gt; 
&lt;p&gt;The coda is the concluding piece of a slide deck. It provides a partitioned place to put topic-relevant material that isn’t delivered in the spoken portion of the presentation.&lt;/p&gt; 
&lt;h3&gt;Antipattern: Injured Outlines&lt;/h3&gt; 
&lt;p&gt;Outlines should never have a single point at an indent level; don’t create bullet points that have only one sub-bullet. Bullets in presentations mimic outlines and it “looks” grammatically incorrect to have orphan bullets.&lt;/p&gt; 
&lt;h3&gt;Pattern: Peer Review&lt;/h3&gt; 
&lt;p&gt;Your first draft of a presentation won’t be your best, nor should it be your last. Find a well-informed colleague who knows the topic and have them critique your first draft.&lt;/p&gt; 
&lt;h3&gt;Pattern: Foreshadowing&lt;/h3&gt; 
&lt;p&gt;Like foreshadowing in literature, this pattern adds elements early in a talk to seed an idea that will be resolved (hopefully with more resonance) later.&lt;/p&gt; 
&lt;h3&gt;Antipattern: Bullet-riddled corpse&lt;/h3&gt; 
&lt;p&gt;A Bullet-Riddled Corpse is a presentation where every slide is a long series of dull bullet points. Typically, these slides will then be read to the audience insinuating they can’t read.&lt;/p&gt; 
&lt;h3&gt;Pattern: Greek Chorus&lt;/h3&gt; 
&lt;p&gt;Ancient Greek plays often featured a chorus, a group of players who stood aside from the action, making occasional comments and interludes during the play. Adding a Greek Chorus means you seed the audience with some partisans to interject comments, enthusiasm, or to help defend your case if you are outnumbered.&lt;/p&gt; 
&lt;h3&gt;Antipattern: Ant Fonts&lt;/h3&gt; 
&lt;p&gt;Don’t use tiny fonts in a desire to cram more information on a slide. Slide size is completely arbitrary and has no relationship to the proper size of the content. If you ever think (or worse, say) “You probably can’t read this in the back,” you’ve failed your audience. Slides with unreadable fonts often result from “helpful” software that modifies font size as you add more content. You don’t get bonus points for using fewer slides.&lt;/p&gt; 
&lt;h3&gt;Antipattern: Fontaholic&lt;/h3&gt; 
&lt;p&gt;A Fontaholic is someone who believes using a cacophony of fonts will “jazz up” a presentation. Disharmonic fonts are jarring. They make presentations gruesome and more difficult to read.&lt;/p&gt; 
&lt;h3&gt;Antipattern: Floodmarks&lt;/h3&gt; 
&lt;p&gt;Floodmarks are marketing and branding headers, footers, and watermarks that invade the content area of the slide. Your audience won’t forget who you work for or the name of the conference during the course of your talk. Egregious instances of this antipattern lead to several other antipatterns by occupying valuable real estate.&lt;/p&gt; 
&lt;h3&gt;Antipattern: Photomaniac&lt;/h3&gt; 
&lt;p&gt;A Photomaniac picks up random pieces of clipart, stock photography, and other tchotchkes, littering them about a presentation, filling any and all empty spaces.&lt;/p&gt; 
&lt;h3&gt;Pattern: Composite Animation&lt;/h3&gt; 
&lt;p&gt;A composite animation is when more than one simple animation provided by the presentation tool is applied to an object for a more impressive and educationally helpful combinatory effect.&lt;/p&gt; 
&lt;h3&gt;Pattern: A la carte Content&lt;/h3&gt; 
&lt;p&gt;Creating a presentation “on the fly” using the interest of the crowd to guide the presentation. Typically, this approach begins with a set of related slides (often structured as a Talklet series) that can be alternatively arranged. This technique works well if you have more content than the time slot allows or the talk naturally breaks along several subtopic lines.&lt;/p&gt; 
&lt;h3&gt;Pattern: Vacation Photos&lt;/h3&gt; 
&lt;p&gt;A picture is worth a thousand words, but does that translate into an effective presentation? Carefully selected images can stand in place of wordy slides. With this approach, the presenter becomes a greater focus of attention, supplying the full verbal channel and allowing the well-chosen images to amplify the spoken words.&lt;/p&gt; 
&lt;h3&gt;Pattern: Defy Defaults&lt;/h3&gt; 
&lt;p&gt;Don’t settle for the defaults or stock templates from any tool. If you do use a stock template, at least customize it so that it’s as unique as a signature.&lt;/p&gt; 
&lt;h3&gt;Antipattern: Borrowed Shoes&lt;/h3&gt; 
&lt;p&gt;From time to time, you may be called upon to deliver someone else’s presentation. You are speaking about something that you’re not sincere about, that doesn’t quite fit you, and that smells funny the entire time you’re delivering it. While it can be done in a pinch, the results are rarely awe-inspiring.&lt;/p&gt; 
&lt;h2&gt;Chapter 4: Temporal Patterns&lt;/h2&gt; 
&lt;h3&gt;Antipattern: Slideuments&lt;/h3&gt; 
&lt;p&gt;A Slideument is a presentation that is trying to be both a presentation aide and an attractive printed version of the presentation. An entire chapter is devoted to dealing with the issues raised by this commonly required antipattern.&lt;/p&gt; 
&lt;h3&gt;Pattern: Infodeck&lt;/h3&gt; 
&lt;p&gt;Infodeck is an emerging form of presentation intended to be consumed in solitude rather than to be presented to an audience. It is an instance of the Slideuments antipattern that actually works for its intended purpose.&lt;/p&gt; 
&lt;h3&gt;Pattern: Gradual Consistency&lt;/h3&gt; 
&lt;p&gt;Reveal content bit by bit, only showing the full connection between all the ideas as the conclusion of segments or modules.&lt;/p&gt; 
&lt;h3&gt;Pattern: Charred Trail&lt;/h3&gt; 
&lt;p&gt;The slide shows out-of-date content by graying it out as the presenter progresses through the slide. This prevents the audience from reading ahead and results in a more printable artifact.&lt;/p&gt; 
&lt;h3&gt;Pattern: Exuberant Title Top&lt;/h3&gt; 
&lt;p&gt;A technique that allows you to place a core idea on the center of the slide and then add supporting elements underneath as the main idea migrates to the top of the slide. The Slideuments pattern allows you to use fewer slides yet separate important points.&lt;/p&gt; 
&lt;h3&gt;Pattern: Invisibility&lt;/h3&gt; 
&lt;p&gt;This pattern uses invisible elements that don’t appear on printed versions of the slides but are revealed throughout your talk. This preserves a sense of surprise when you are forced to provide handouts (Slideuments?) in advance of your talk.&lt;/p&gt; 
&lt;h3&gt;Pattern: Context Keeper&lt;/h3&gt; 
&lt;p&gt;An organizational device within a presentation that reveals the structure of the talk, either temporally, by subject matter, or by some other contextually meaningful manner.&lt;/p&gt; 
&lt;h3&gt;Pattern: Breadcrumbs&lt;/h3&gt; 
&lt;p&gt;Create an agenda trail throughout your presentation to provide context on progress. In addition to providing context, this gives the audience a familiar element to ground them.&lt;/p&gt; 
&lt;h3&gt;Pattern: Bookends&lt;/h3&gt; 
&lt;p&gt;Use distinct slides throughout the presentation to supply agenda context. Often visually distinct from the standard slides, they provide a sense of progress as well. Bookend slides indicate the end of one section and the start of a new one.&lt;/p&gt; 
&lt;h3&gt;Pattern: Soft Transitions&lt;/h3&gt; 
&lt;p&gt;When you have stale content, one way to subtly transition away from it uses an almost-imperceptible fade transition for either the slide or elements on the slide. It should happen so gradually that the audience doesn’t even realize it’s happening. Add both slide and element transitions to soften the transition between slides.&lt;/p&gt; 
&lt;h3&gt;Pattern: Intermezzi&lt;/h3&gt; 
&lt;p&gt;Presentations should be made up of logical parts in the form of a Triad or Narrative Arc shape. Sometimes, these sections necessitate a color change, thematic shift, or outline introduction to clearly signal the beginning or ending of an act. This pattern is an implementation of the Context Keeper pattern and is similar to Bookends but is used during the course of the presentation to wrap sections, as opposed to wrapping the entire presentation.&lt;/p&gt; 
&lt;h3&gt;Pattern: Backtracking&lt;/h3&gt; 
&lt;p&gt;Backtracking is the intentional repetition of material for the purpose of reestablishing context. This helps the audience regain their conceptual footing as the narrative moves forward.&lt;/p&gt; 
&lt;h3&gt;Pattern: Preroll&lt;/h3&gt; 
&lt;p&gt;Prior to the start time of your talk, displaying the topic and presenter on screen can be informative and clarifying. If the information cannot comfortably fit on one slide, a series of slides can be recorded as a video and then embedded into the actual presentation and set to loop. When the presenter is ready to give the talk, he or she clicks the remote to advance past the animation to the first content slide.&lt;/p&gt; 
&lt;h3&gt;Pattern: Crawling Credits&lt;/h3&gt; 
&lt;p&gt;As pioneered by the movie Star Wars (with the later addition to the title Episode IV: A New Hope) in 1977, credits can be calmly and progressively shown in a seemingly infinite bottom-to-top slide. This gives each name, company, or URL equal but limited screen time without seeming hurried.&lt;/p&gt; 
&lt;h2&gt;Chapter 5: Demonstrations vs Presentations&lt;/h2&gt; 
&lt;h3&gt;Pattern: Live Demo&lt;/h3&gt; 
&lt;p&gt;Live Demo is running the product live in front of the audience. Thought of as a way to gain credibility and actively promote the product, this approach carries the significant risk of a failing demo. The return on investment is rarely worth the risk.&lt;/p&gt; 
&lt;h3&gt;Antipattern: Dead Demo&lt;/h3&gt; 
&lt;p&gt;This antipattern uses a live demonstration as a time filler when the presenter is short on expositional content.&lt;/p&gt; 
&lt;h3&gt;Pattern: Lipsync&lt;/h3&gt; 
&lt;p&gt;Rather than giving a live demonstration, record the interaction with the tool and play it back as part of the presentation. This approach reduces stress, prevents errors, and allows you to use the heads-up display to see slide metadata. You can also make additional points while the demonstration is playing.&lt;/p&gt; 
&lt;h3&gt;Pattern: Traveling Highlights&lt;/h3&gt; 
&lt;p&gt;Use highlighting (either intrinsic in the tool or a third-party add-on like OmniDazzle) to draw attention to something on the slide such as a picture or screenshot of another tool or application. Traveling Highlights implies that you use transitions to highlight different parts of the slide as you walk through the details.&lt;/p&gt; 
&lt;h3&gt;Pattern: Crawling Code&lt;/h3&gt; 
&lt;p&gt;Code is difficult to display inside a presentation. Simply pasting monochrome text onto a slide is not only ugly, but it often doesn’t fit on one screen. Crawling code is a means of showing just a portion of the code at a time while offering context of the other previous and upcoming lines. The out-of-attention lines are shaded to focus attention on the lines being discussed.&lt;/p&gt; 
&lt;h3&gt;Pattern: Emergence&lt;/h3&gt; 
&lt;p&gt;Emergence suggests that the big thing you’re ultimately going to show (tool, giant diagram, source code, etc.) isn’t a static display. Use motion, transitions, highlights, and other presentation effects to gradually reveal pieces or details.&lt;/p&gt; 
&lt;h3&gt;Pattern: Live on Tape&lt;/h3&gt; 
&lt;p&gt;This term refers to a recorded version of your entire presentation provided electronically. More effective and interactive than the standard “saving your presentation as a PDF.”&lt;/p&gt; 
&lt;h1&gt;Part 3: Deliver&lt;/h1&gt; 
&lt;h2&gt;Chapter 6: Stage Prep&lt;/h2&gt; 
&lt;h3&gt;Pattern: Preparation&lt;/h3&gt; 
&lt;p&gt;Murphy’s Law applies to presentations; nothing trumps being prepared. Plan for as many eventualities of as possible, be it a hardware failure, a room change, or an unruly crowd. It may seem prosaic, but consider a checklist: supported projector resolutions, techniques to manage the audience, display dongles, presenter remotes, notes on your topic, a bottle of water, and other needed items reduce the risk of common mistakes that less prepared presenters might make.&lt;/p&gt; 
&lt;h3&gt;Pattern: Posse&lt;/h3&gt; 
&lt;p&gt;Having team members or friends in the audience not only provides a visual focal point of some likely-to-be-smiling faces but also can act as assistants in times of need. They can also be seeded with useful questions and they can clap and nod at appropriate times; the audience symbiotically follows suit and has a more positive impression of the talk and you as the presenter. Friendly faces reduce stress and put you more at ease.&lt;/p&gt; 
&lt;h3&gt;Pattern: Seeding Satisfaction&lt;/h3&gt; 
&lt;p&gt;Even the friendliest of audiences benefits from some warm-up. Simple greetings, handshakes, and sincere questions, prior to the start of your presentation, break the ice and prime your audience to be more receptive to your message.&lt;/p&gt; 
&lt;h3&gt;Pattern: Display of High Value&lt;/h3&gt; 
&lt;p&gt;As a presenter, you should demonstrate to the audience that there is a difference between the speaker and audience members; the speaker is bringing new knowledge and discoveries and the audience is there to absorb, question, and clarify these new points.&lt;/p&gt; 
&lt;h3&gt;Antipattern: Shortchanged&lt;/h3&gt; 
&lt;p&gt;Dealing with a last-minute reduction in presentation time is unfortunately one of the skills frequent presenters have to hone. Coping well with the situation leaves the audience none the wiser. Managing this situation poorly leaves you rushing, cutting important material, and delivering a less meaningful presentation.&lt;/p&gt; 
&lt;h2&gt;Chapter 7: Performance antipatterns&lt;/h2&gt; 
&lt;h3&gt;Antipattern: Hiccup Words&lt;/h3&gt; 
&lt;p&gt;Hiccup Words are involuntary exclamations (“Ummm,” “Ahhh,” etc.) that distract and detract from the presentation. Dead air isn’t a cardinal sin, and it’s unlikely anyone in your audience will break into a presentation just because you paused.&lt;/p&gt; 
&lt;h3&gt;Antipattern: Disowning Your Topic&lt;/h3&gt; 
&lt;p&gt;If you think a topic is rudimentary, expect it is for your audience as well. Accelerate if you think the audience is already familiar with the topic. Don’t treat your topic as if it was the most interesting thing in the world—it’s not. Assume you’re speaking to a group of smart people who are terribly bored of hearing about your topic; ad-lib and go off the prepared path at will.&lt;/p&gt; 
&lt;h3&gt;Antipattern: Lipstick on a Pig&lt;/h3&gt; 
&lt;p&gt;This antipattern are talks with pointless or weak content dressed up with special effects. Contrary to the wishful practitioner’s hopes and dreams, audience members will see through the decorative facade to the fundamental lack of useful material or insight.&lt;/p&gt; 
&lt;h3&gt;Antipattern: Tower of Babble&lt;/h3&gt; 
&lt;p&gt;Presenters are inclined to use arcane jargon irrespective of the skill level of their audience. Follow that inclination and use three-letter acronyms and technospeak at liberty. Feel confident your audience understands those phrases even if they are giving you puzzled looks.&lt;/p&gt; 
&lt;h3&gt;Antipattern: Bunker&lt;/h3&gt; 
&lt;p&gt;Hiding behind something doesn’t engender trust with your audience. You speak to a group of people; making a more personal connection with them adds nuance and extra meaning to your presentation. Avoid podiums; walk around and engage with your audience. Stationary presenters often give very static presentations.&lt;/p&gt; 
&lt;h3&gt;Antipattern: Hecklers&lt;/h3&gt; 
&lt;p&gt;An audience of any substantial size will have individuals that aim to gain recognition through attacks on the presenter’s premise, approach, or discoveries. Coping with them requires preparation, a cool head, and decisive action. Dealing decisively with hecklers keeps the presentation on track and protects the congenial members of the audience.&lt;/p&gt; 
&lt;h3&gt;Antipattern: Going Meta&lt;/h3&gt; 
&lt;p&gt;Never talk about the talk itself. The audience isn’t interested in mechanics; they came to hear about the interesting topic that you are uniquely equipped to expound upon. This would be akin to a theatrical (not a director’s cut) release of Star Wars Episode IV: A New Hope spending time discussing how George Lucas used a certain kind of lens, the temperature of lighting on the set, and the brand of makeup on the actors.&lt;/p&gt; 
&lt;h3&gt;Antipattern: Backchannel&lt;/h3&gt; 
&lt;p&gt;The backchannel encompasses all the ways people can chat about your presentation while it’s occurring, either via text messages during a business meeting or tweeting during an event.&lt;/p&gt; 
&lt;h3&gt;Antipattern: Laser Weapons&lt;/h3&gt; 
&lt;p&gt;Laser pointers are generally a crutch for identifying content elements on a slide that could otherwise be emphasized by Traveling Highlights or as an attempt to explain a slide that “you probably can’t read in the back.”&lt;/p&gt; 
&lt;h3&gt;Antipattern: Negative Ignorance&lt;/h3&gt; 
&lt;p&gt;Never pose a question to the audience in the form of “Who here is not familiar with X?” People dislike admitting ignorance, especially in a circle of their peers. And turning it to a positive question isn’t much better.&lt;/p&gt; 
&lt;h3&gt;Antipattern: Dual-Headed Monster&lt;/h3&gt; 
&lt;p&gt;This antipattern delivers a presentation to both a live and a remote audience via some desktop sharing or video streaming tool. It reduces the value and richness of the presentation by trying to serve two audiences, each with disparate and competing format and delivery requirements.&lt;/p&gt; 
&lt;h2&gt;Chapter 8: Performance patterns&lt;/h2&gt; 
&lt;h3&gt;Pattern: Carnegie Hall&lt;/h3&gt; 
&lt;p&gt;The only true preparation for unusual occurrences is practice. This pattern defines the types and number of practice sessions you need.&lt;/p&gt; 
&lt;h3&gt;Pattern: Emotional state&lt;/h3&gt; 
&lt;p&gt;Presenters should be attuned to the condition and situation of their audience. Adapt the talk to fit the mood and needs of the audience.&lt;/p&gt; 
&lt;h3&gt;Pattern; Breathing Room&lt;/h3&gt; 
&lt;p&gt;Talking too fast and not leaving enough time for the audience to fully understand the deeper implications of the talk is a common antipattern many many presenters exhibit. While difficult, breathing room is the purposeful insertion of quiet to allow important concepts time to settle and germinate. While dead air might be a cardinal sin in radio, moments of pause allow your audience to integrate your message.&lt;/p&gt; 
&lt;h3&gt;Pattern: Shoeless&lt;/h3&gt; 
&lt;p&gt;Presenter creature comforts, while possibly perceived as odd or eccentric, can put the speaker at ease, enhancing the delivery. Such comforts include the removal of shoes, certain placement of the laptop, comfortable clothes, a favorite beverage, or stepping away from the lectern to mingle among the audience.&lt;/p&gt; 
&lt;h3&gt;Pattern: Mentor&lt;/h3&gt; 
&lt;p&gt;The audience wants to be led but not by the nose. Take on the role of guide and, via the presentation, provide your audience with new skills, ideas, and techniques as if you were their private tutor in your field.&lt;/p&gt; 
&lt;h3&gt;Pattern: Weatherman&lt;/h3&gt; 
&lt;p&gt;TV weathermen use green screens and monitors to see and gesture toward map details. Never turn your back on the audience. If you need to point to something on the screen, do it like a weatherman: Stand off to the side so that you can see both the screen and the audience as you gesture.&lt;/p&gt; 
&lt;h3&gt;Pattern: Seeding the First Question&lt;/h3&gt; 
&lt;p&gt;Purposely placing an obvious question for your audience to ask somewhere in the presentation as a way to break the ice for question-and-answer sessions.&lt;/p&gt; 
&lt;h3&gt;Pattern: Make It Rain&lt;/h3&gt; 
&lt;p&gt;Use props like chairs, paper airplanes, candy (typically thrown at/to audience members), and other devices to add flair to your presentation and encourage interaction, especially with preternaturally shy groups.&lt;/p&gt; 
&lt;h3&gt;Pattern: Entertainment&lt;/h3&gt; 
&lt;p&gt;Entertaining the audience is an important device to capture the attention but should not be used to excess. Like any seasoning, a little bit goes a long way; don’t confuse your message with your method.&lt;/p&gt; 
&lt;h3&gt;Pattern: The Stakeout&lt;/h3&gt; 
&lt;p&gt;Arriving on time for your talk seems too simple to even mention. However, chaos is conspiring to prevent you from doing just that. If the venue isn’t amenable to corporate camping, locate a nearby coffee shop or other work-conducive location. You can arrive at this staging area with ample time to spare but still have the opportunity to use your cushion productively should mayhem take a holiday. It also avoids aimlessly wandering the venue hallways.&lt;/p&gt; 
&lt;h3&gt;Pattern: Lightsaber&lt;/h3&gt; 
&lt;p&gt;When used minimally in the hands of a thoughtful presenter, a laser pointer can be a useful on-demand teaching tool.&lt;/p&gt; 
&lt;h3&gt;Pattern: Echo Chamber&lt;/h3&gt; 
&lt;p&gt;When an attendee asks a question, always repeat the question before answering. Restating the question assures you’ve heard the query and gives you time to formulate a response.&lt;/p&gt; 
&lt;h3&gt;Pattern: Red, Yellow, Green&lt;/h3&gt; 
&lt;p&gt;Several conferences, in order to simplify the voting process and increase participation, put red, yellow, and green cards near the entrance to the room. Upon exit, attendees drop a card into the voting bucket indicating their opinion of the talk. The scores can be tallied immediately.&lt;/p&gt; 
&lt;h3&gt;Analog Noise&lt;/h3&gt; 
&lt;p&gt;Computers make it possible to create visually flawless imagery and text. However, in sci-fi movies, even apparently digital communication has jitter, breakups, blockiness, and noise. The imperfection is a cue that the communications are happening over a long distance. “Analog noise” can be an endearing quality that makes the situation more believable for the audience. Such noise can be intentionally introduced via handwritten fonts, film grain, uneven lines, monochrome colors, and “amateur” photograph errors. Adding some noise to your slides adds visual interest and garners greater attention.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>4store</title>
      <link>https://tedneward.github.io/Research/storage/4store/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">storage/4store/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/4store/4store&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Looks like it&apos;s abandoned; the website &lt;a href=&quot;http://4store.org&quot;&gt;http://4store.org&lt;/a&gt; no longer appears viable and the last commit to GitHub was 3 years ago.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Public Speaking Topic Secrets for College, Community, Toastmasters and TED Talks</title>
      <link>https://tedneward.github.io/Research/speaking/public-speaking-topic-secrets/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">speaking/public-speaking-topic-secrets/index.html</guid>
      	<description>
	&lt;p&gt;&lt;em&gt;(by Ramakrishna Reddy)&lt;/em&gt;&lt;/p&gt; 
&lt;h1&gt;Ch1: Blueprint for Speech Topic Ideas&lt;/h1&gt; 
&lt;p&gt;Step 1: LARGER PURPOSE of the speech&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Why are you giving the speech?&lt;/li&gt; 
 &lt;li&gt;What is the occasion for the speech?&lt;/li&gt; 
 &lt;li&gt;What type of speech will suit my larger purpose?&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;Step 2: Topics that interest YOU&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;What do you know?&lt;/li&gt; 
 &lt;li&gt;What are you enthusiastic about?&lt;/li&gt; 
 &lt;li&gt;What are your life experiences?&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;Step 3: Topics that interest your AUDIENCE&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;What are your audience&apos;s needs?&lt;/li&gt; 
 &lt;li&gt;Do they belong to a certain age group?&lt;/li&gt; 
 &lt;li&gt;What are their shared experiences?&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;Toastmasters classification:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Informational&lt;/li&gt; 
 &lt;li&gt;Entertaining&lt;/li&gt; 
 &lt;li&gt;Persuasive&lt;/li&gt; 
 &lt;li&gt;Inspirational&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h1&gt;Ch2: How to find Informational Speech Topic Ideas&lt;/h1&gt; 
&lt;p&gt;Things you like (Books, Gardening, Exercise, Sports, Cooking, Psych, Internet, Expert)&lt;/p&gt; 
&lt;p&gt;Observations&lt;/p&gt; 
&lt;p&gt;Problem/Solutions&lt;/p&gt; 
&lt;h1&gt;Ch3: How to find Entertaining Speech Topic Ideas&lt;/h1&gt; 
&lt;p&gt;Humor is largely based on two principles:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Truth&lt;/li&gt; 
 &lt;li&gt;Surprise&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;Premise and punchline. As a rule of thumb, the premise should be true and should not be funny. The punchline should have the surprise. It can have exaggeration as well.&lt;/p&gt; 
&lt;p&gt;Self-Deprecating (Large relatable unexpected events, Unusual physical traits, Your current life situation, Your identity)&lt;/p&gt; 
&lt;p&gt;Characters in your life (Family, Your professional life, Social setting)&lt;/p&gt; 
&lt;h1&gt;Ch4: How to find Persuasive Speech Topic ideas&lt;/h1&gt; 
&lt;p&gt;Ideally, every persuasive/inspiring speech should have these three elements:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Ethos: relating to credibility--being fair, using proper language, using correct grammar, using appropriate vocabulary&lt;/li&gt; 
 &lt;li&gt;Pathos: relating to emotional--emotional tone, stories of emotional events&lt;/li&gt; 
 &lt;li&gt;Logos: relating to logic--facts or figures, citing history, logical arguments&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h1&gt;Ch5: How to find Inspiring Speech Topic ideas&lt;/h1&gt; 
&lt;p&gt;
 &lt;nothing&gt;&lt;/nothing&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Kanban</title>
      <link>https://tedneward.github.io/Research/reading/processes/kanban/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">reading/processes/kanban/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;http://www.infoq.com/minibooks/kanban-scrum-minibook&quot;&gt;Kanban and Scrum - making the most of both&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://leanpub.com/kanbanforskeptics&quot;&gt;Kanban for skeptics&lt;/a&gt; - Nick Oostvogels &lt;em&gt;(Leanpub account or valid email requested)&lt;/em&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Ship It!</title>
      <link>https://tedneward.github.io/Research/reading/processes/ship-it/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">reading/processes/ship-it/index.html</guid>
      	<description>
	&lt;p&gt;&lt;em&gt;(by Jared Richardson, William A Gwaltney)&lt;/em&gt;&lt;/p&gt; 
&lt;ol&gt; 
 &lt;li&gt;Choose your habits&lt;/li&gt; 
 &lt;li&gt;Stay in the sandbox&lt;/li&gt; 
 &lt;li&gt;If you need it, check it in&lt;/li&gt; 
 &lt;li&gt;Script builds on day one&lt;/li&gt; 
 &lt;li&gt;Any machine can be a build machine&lt;/li&gt; 
 &lt;li&gt;Build continuously&lt;/li&gt; 
 &lt;li&gt;Test continuously&lt;/li&gt; 
 &lt;li&gt;Avoid collective memory loss&lt;/li&gt; 
 &lt;li&gt;Exercise your product--automate your tests&lt;/li&gt; 
 &lt;li&gt;Use a common, flexible test harness&lt;/li&gt; 
 &lt;li&gt;Use the best tool for the job&lt;/li&gt; 
 &lt;li&gt;Use open formats to integrate tools&lt;/li&gt; 
 &lt;li&gt;Keep critical path technologies familiar&lt;/li&gt; 
 &lt;li&gt;Work to the list&lt;/li&gt; 
 &lt;li&gt;Let a tech lead&lt;/li&gt; 
 &lt;li&gt;Use daily meetings for frequent course corrections&lt;/li&gt; 
 &lt;li&gt;It&apos;s OK to say &quot;later&quot;&lt;/li&gt; 
 &lt;li&gt;Always review all code&lt;/li&gt; 
 &lt;li&gt;The goal is software, not compliance&lt;/li&gt; 
 &lt;li&gt;Architect as a group&lt;/li&gt; 
 &lt;li&gt;If production uses it, you should too&lt;/li&gt; 
 &lt;li&gt;Solve the hardest programs first&lt;/li&gt; 
 &lt;li&gt;An encapsulated architecture is a scalable architecture&lt;/li&gt; 
 &lt;li&gt;You can&apos;t steer a boat unless its moving&lt;/li&gt; 
 &lt;li&gt;Don&apos;t change legacy code until you can test it&lt;/li&gt; 
 &lt;li&gt;Use test-driven refactoring to clean up untestable code&lt;/li&gt; 
 &lt;li&gt;Mock client tests do the most with the least&lt;/li&gt; 
 &lt;li&gt;Continuously test changing code&lt;/li&gt; 
 &lt;li&gt;It has to work for everyone&lt;/li&gt; 
 &lt;li&gt;Integrate often, build and test continuously&lt;/li&gt; 
 &lt;li&gt;Deliver live demos early &amp;amp; often&lt;/li&gt; 
 &lt;li&gt;Publicize what you&apos;re doing and why&lt;/li&gt; 
 &lt;li&gt;Face time builds teamwork&lt;/li&gt; 
 &lt;li&gt;Only fix what needs fixing&lt;/li&gt; 
 &lt;li&gt;Disruptive best practices aren&apos;t&lt;/li&gt; 
 &lt;li&gt;Innovate from the bottom up&lt;/li&gt; 
 &lt;li&gt;Show, don&apos;t just tell&lt;/li&gt; 
 &lt;li&gt;Cultivate management buy-in&lt;/li&gt; 
 &lt;li&gt;Test continuously&lt;/li&gt; 
 &lt;li&gt;Test where the bugs are&lt;/li&gt; 
 &lt;li&gt;The list is a living document&lt;/li&gt; 
 &lt;li&gt;If it&apos;s not on the list, it&apos;s not part of the project&lt;/li&gt; 
 &lt;li&gt;Always give feedback fast&lt;/li&gt; 
&lt;/ol&gt;
	</description>
    </item>
    <item>
      <title>Endpoint Security</title>
      <link>https://tedneward.github.io/Research/security/endpoint/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">security/endpoint/index.html</guid>
      	<description>
	&lt;h3&gt;Anti-Virus / Anti-Malware&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/codeyourweb/fastfinder&quot;&gt;Fastfinder&lt;/a&gt; - Fast customisable cross-platform suspicious file finder. Supports md5/sha1/sha256 hashs, litteral/wildcard strings, regular expressions and YARA rules. Can easily be packed to be deployed on any windows / linux host.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.rfxn.com/projects/linux-malware-detect/&quot;&gt;Linux Malware Detect&lt;/a&gt; - A malware scanner for Linux designed around the threats faced in shared hosted environments.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/Neo23x0/Loki&quot;&gt;LOKI&lt;/a&gt; - Simple Indicators of Compromise and Incident Response Scanner&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://rkhunter.sourceforge.net/&quot;&gt;rkhunter&lt;/a&gt; - A Rootkit Hunter for Linux&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.clamav.net/&quot;&gt;ClamAv&lt;/a&gt; - ClamAV® is an open-source antivirus engine for detecting trojans, viruses, malware &amp;amp; other malicious threats.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Content Disarm &amp;amp; Reconstruct&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/docbleach/DocBleach&quot;&gt;DocBleach&lt;/a&gt; - An open-source Content Disarm &amp;amp; Reconstruct software sanitizing Office, PDF and RTF Documents.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Configuration Management&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/fleetdm/fleet&quot;&gt;Fleet device management&lt;/a&gt; - Fleet is the lightweight, programmable telemetry platform for servers and workstations. Get comprehensive, customizable data from all your devices and operating systems.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.rudder-project.org/&quot;&gt;Rudder&lt;/a&gt; - Rudder is an easy to use, web-driven, role-based solution for IT Infrastructure Automation &amp;amp; Compliance. Automate common system administration tasks (installation, configuration); Enforce configuration over time (configuring once is good, ensuring that configuration is valid and automatically fixing it is better); Inventory of all managed nodes; Web interface to configure and manage nodes and their configuration; Compliance reporting, by configuration and/or by node.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Authentication&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/google/google-authenticator&quot;&gt;google-authenticator&lt;/a&gt; - The Google Authenticator project includes implementations of one-time passcode generators for several mobile platforms, as well as a pluggable authentication module (PAM). One-time passcodes are generated using open standards developed by the Initiative for Open Authentication (OATH) (which is unrelated to OAuth). These implementations support the HMAC-Based One-time Password (HOTP) algorithm specified in RFC 4226 and the Time-based One-time Password (TOTP) algorithm specified in RFC 6238. &lt;a href=&quot;http://xmodulo.com/two-factor-authentication-ssh-login-linux.html&quot;&gt;Tutorials: How to set up two-factor authentication for SSH login on Linux&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/kurolabs/stegcloak&quot;&gt;Stegcloak&lt;/a&gt; - Securely assign Digital Authenticity to any written text&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Mobile / Android / iOS&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/ashishb/android-security-awesome&quot;&gt;android-security-awesome&lt;/a&gt; - A collection of android security related resources. A lot of work is happening in academia and industry on tools to perform dynamic analysis, static analysis and reverse engineering of android apps.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://wiki.secmobi.com/&quot;&gt;SecMobi Wiki&lt;/a&gt; - A collection of mobile security resources which including articles, blogs, books, groups, projects, tools and conferences. *&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/OWASP/owasp-mstg&quot;&gt;OWASP Mobile Security Testing Guide&lt;/a&gt; - A comprehensive manual for mobile app security testing and reverse engineering.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/kai5263499/osx-security-awesome&quot;&gt;OSX Security Awesome&lt;/a&gt; - A collection of OSX and iOS security resources&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/cossacklabs/themis&quot;&gt;Themis&lt;/a&gt; - High-level multi-platform cryptographic framework for protecting sensitive data: secure messaging with forward secrecy and secure data storage (AES256GCM), suits for building end-to-end encrypted applications.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://mobilesecuritywiki.com/&quot;&gt;Mobile Security Wiki&lt;/a&gt; - A collection of mobile security resources.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/iBotPeaches/Apktool&quot;&gt;Apktool&lt;/a&gt; - A tool for reverse engineering Android apk files.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/skylot/jadx&quot;&gt;jadx&lt;/a&gt; - Command line and GUI tools for produce Java source code from Android Dex and Apk files.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/Storyyeller/enjarify&quot;&gt;enjarify&lt;/a&gt; - A tool for translating Dalvik bytecode to equivalent Java bytecode.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/51j0/Android-Storage-Extractor&quot;&gt;Android Storage Extractor&lt;/a&gt; - A tool to extract local data storage of an Android application in one click.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/quark-engine/quark-engine&quot;&gt;Quark-Engine&lt;/a&gt; - An Obfuscation-Neglect Android Malware Scoring System.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.jetbrains.com/decompiler/&quot;&gt;dotPeek&lt;/a&gt; - Free-of-charge standalone tool based on ReSharper&apos;s bundled decompiler.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/GrapheneOS/hardened_malloc&quot;&gt;hardened_malloc&lt;/a&gt; - Hardened allocator designed for modern systems. It has integration into Android&apos;s Bionic libc and can be used externally with musl and glibc as a dynamic library for use on other Linux-based platforms. It will gain more portability / integration over time.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/ir193/AMExtractor&quot;&gt;AMExtractor&lt;/a&gt; - AMExtractor can dump out the physical content of your Android device even without kernel source code.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/frida/frida&quot;&gt;frida&lt;/a&gt; - Dynamic instrumentation toolkit for developers, reverse-engineers, and security researchers.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/UDcide/udcide&quot;&gt;UDcide&lt;/a&gt; - Android Malware Behavior Editor.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/ptswarm/reFlutter&quot;&gt;reFlutter&lt;/a&gt; - Flutter Reverse Engineering Framework&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Forensics&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/google/grr&quot;&gt;grr&lt;/a&gt; - GRR Rapid Response is an incident response framework focused on remote live forensics.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/volatilityfoundation/volatility&quot;&gt;Volatility&lt;/a&gt; - Python based memory extraction and analysis framework.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://mig.mozilla.org/&quot;&gt;mig&lt;/a&gt; - MIG is a platform to perform investigative surgery on remote endpoints. It enables investigators to obtain information from large numbers of systems in parallel, thus accelerating investigation of incidents and day-to-day operations security.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/diogo-fernan/ir-rescue&quot;&gt;ir-rescue&lt;/a&gt; - &lt;em&gt;ir-rescue&lt;/em&gt; is a Windows Batch script and a Unix Bash script to comprehensively collect host forensic data during incident response.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/dogoncouch/logdissect&quot;&gt;Logdissect&lt;/a&gt; - CLI utility and Python API for analyzing log files and other data.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/TonyPhipps/Meerkat&quot;&gt;Meerkat&lt;/a&gt; - PowerShell-based Windows artifact collection for threat hunting and incident response.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/google/rekall&quot;&gt;Rekall&lt;/a&gt; - The Rekall Framework is a completely open collection of tools, implemented in Python under the Apache and GNU General Public License, for the extraction and analysis of digital artifacts computer systems.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/504ensicsLabs/LiME.git&quot;&gt;LiME&lt;/a&gt; - Linux Memory Extractor&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/soxoj/maigret&quot;&gt;Maigret&lt;/a&gt; - Maigret collect a dossier on a person by username only, checking for accounts on a huge number of sites and gathering all the available information from web pages.&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Open Policy Agent (OPA)</title>
      <link>https://tedneward.github.io/Research/security/openpolicyagent/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">security/openpolicyagent/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.openpolicyagent.org/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/open-policy-agent&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;uses &lt;a href=&quot;/languages/rego&quot;&gt;Rego&lt;/a&gt; for its policy declarations/definitions&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>49 Habits for Public Speaking Success</title>
      <link>https://tedneward.github.io/Research/speaking/49-habits-for-public-speaking-success/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">speaking/49-habits-for-public-speaking-success/index.html</guid>
      	<description>
	&lt;p&gt;&lt;em&gt;(by Mark Davis)&lt;/em&gt;&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;strong&gt;Can we create a great talk?&lt;/strong&gt; Be willing to accept feedback; have a positive attitude; mental and physical preparation before the talk&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Open with a great first line&lt;/strong&gt; Audience does not want to be manipulated into sharing their feelings. Don&apos;t ask, &quot;How are we tonight?&quot; Why would we ask a question that leads to anything other than a positive outcome? Use a guaranteed opening, like telling a story, asking a question, or doing an activity. Get the audience leaning forward with compelling statements. We want the audience focused on wanting to hear more.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Get your speed right&lt;/strong&gt; Practice speaking slowly.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Love the microphone&lt;/strong&gt; Practice holding hairbrush/shampoo bottle. Hold it close to your mouth, just a few inches away. (Rest on chin.)&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Manage your water intake&lt;/strong&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Stay on time!&lt;/strong&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Mind your gaps and pauses Ums/ahs/well/so crutch words.&lt;/strong&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;You can do better than &quot;Hello&quot;&lt;/strong&gt; Plan a strong opening&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Do not drink alcohol before or during a talk!&lt;/strong&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Avoid dehydration&lt;/strong&gt; Particularly for hot climates/situations&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Get the volume right&lt;/strong&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Put variety into the speech&lt;/strong&gt; No monotones&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Trust the technicians, but test beforehand&lt;/strong&gt; Prepare for the worst; what will you do when you are outside, and no slides or computers are available?&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Dress for success&lt;/strong&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Keep the food in the green room&lt;/strong&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Relax and do your best&lt;/strong&gt; Nervous speakers think the audience wants to know they are nervous; audience is now focusing on the speaker&apos;s nerves and issues, which removes the focus from the speech. Only say what we want the audience to focus on.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Never apologize&lt;/strong&gt; Some speakers apologize because they want to downplay the audience&apos;s expectations. Do not apologize. No one wants to hear it. A confident start gives the audience permission to enjoy our talk.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;The weather doesn&apos;t matter&lt;/strong&gt; Do not talk about the weather unless it is relevant to the talk.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Location, location, location&lt;/strong&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Being funny is an art form&lt;/strong&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Be well rested&lt;/strong&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Control the body&lt;/strong&gt; Try not to be tied to a podium; if we can walk, we will not get as tired.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Pause. Breathe. Continue.&lt;/strong&gt; Best presentation has moments of silence. This is for the audience to reflect and consider what was said. If we talk too fast or do not pause, we can provide information overload, and then no one remembers anything.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Variety, not monotone&lt;/strong&gt; Monotones can be cured by increasing the volume. Watch TV news reporters and listen for the melody in their voices. Watch cartoons and listen to the changes in tone, pitch and volume of each character.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Don&apos;t hurry up, just wrap it up&lt;/strong&gt; Prepare a plan for when the talk goes off its original path. Know what can be cut from the presentation so you can finish on time.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Close well&lt;/strong&gt; Practice closing/ending. Tell the audience what you would like them to do at the end (call to action). Show them what additional resources are available.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Panel discussions (if you have to)&lt;/strong&gt; Have clear and specific topics for the panel discussion. Everyone must know the guidelines and stick to them. Have a moderator who will keep things on track. Engage the audience with questions they can respond to. Know the rules for interacting with the other panelists and respect when the other panelists are talking. Be prepared to answer questions from the audience and give concise answers. Every speaker should have equal time talking.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Don&apos;t let the small stuff stop you starting well&lt;/strong&gt; Tell a joke. Open with a story. Ask a question. Do an activity. Ask for a volunteer. Share something personal. Tell a secret. (Get the opening right.)&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Your attitude matters&lt;/strong&gt; Keep it positive with all management, organizing staff, and anyone talking to the audience.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Use the microphone&lt;/strong&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Take the feedback&lt;/strong&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;One introduction is enough&lt;/strong&gt; Getting started is better than sharing 20 years of your past experience. In a speech/TedTalk, the value you bring is your content, not your name. You are just the delivery vehicle for your message.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Be clear&lt;/strong&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Focus on the audience&lt;/strong&gt; Focus on delivering good material right away. Realize when we are wasting people&apos;s time, and what is valuable. Audience wants solutions right away.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Spare us the name-dropping&lt;/strong&gt; People trust in the reality of a personal story; they do not believe us when we have to refer to other people all the time. When we have the confidence to share original material, there is a better connection.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Talk with the audience&lt;/strong&gt; Every talk needs to be made in such a way that it is a conversation. The most effective presentation is focused on the audience, and a speech that engages the audience&apos;s values and interests will be applauded.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Make your facts real&lt;/strong&gt; Never use a fact as a fact without research.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Speak well of others&lt;/strong&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Beware your dominant thoughts&lt;/strong&gt; Never mention a topic you do not want to talk about, and try not to think about anything that could distract. Stay on topic.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Don&apos;t point&lt;/strong&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Talk towards the audience&lt;/strong&gt; Try to always keep your back to the side or back of the room. Aim to make eye contact with someone every five to seven seconds. If you have a big screen behind you, do not look at it. Use the laptop or monitors instead.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;They are already listening--talk already&lt;/strong&gt; Observe what the audience looks like in the beginning when they are all paying attention. If the body language and facial expressions stay the same, you are doing OK; if not, you have to adjust.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Make PowerPoint work for you&lt;/strong&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Use questions well&lt;/strong&gt; Have prepared questions that you can ask to allow you to repeat and recap key points. This also helps add material to support the initial presentation.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Speak to the group&lt;/strong&gt; Focus on the happy people--focus on where the smiles are. Everyone in the room is still listening to us, even if they do not look like it. Those who aren&apos;t looking directly at us can still see with their peripheral vision. We cannot read the minds of the audience, even if we can guess at their body language.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Use the equipment like a pro&lt;/strong&gt; Be a professional and just get started; trust that it all works. (Particularly if you did a tech check.)&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Be yourself&lt;/strong&gt; Don&apos;t claim ownership of unoriginal material.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Suggest, don&apos;t force&lt;/strong&gt; Everything a speaker presents is still just an idea/opinion/theory. People can always choose what to do with the information. Remember that no matter how knowledgeable we are, we do not know everything. Humility needs to be at the essence of why we teach, share, and educate our audiences. If we do not have the mindset to accept feedback, we will never improve.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Be humble&lt;/strong&gt; Be honest about our background, our area of study, our success. Being open about our qualifications and experience will allow us to be trusted by our audience. We can build a strong rapport by being specific in our knowledge and not trying to be the expert in all areas.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Always be patient with your crowd&lt;/strong&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Speak well to everyone&lt;/strong&gt; Audiences want to be there; want to learn; deserve respect; deserve a professional presentation; is not our friend until we communicate well and make them one; is not an enemy until we disrespect them and make them one.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Keep your language G-rated&lt;/strong&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Focus on the positive&lt;/strong&gt; Everything we say directs the audience&apos;s focus and attention. Do not say anything you do not want the audience to focus on.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Are you really that funny?&lt;/strong&gt; It is not the audience&apos;s fault if we are not funny.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Phones off&lt;/strong&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Plant positive seeds&lt;/strong&gt;&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>&quot;Old Agile vs New Agile&quot;</title>
      <link>https://tedneward.github.io/Research/reading/processes/old-agile-vs-new-agile/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">reading/processes/old-agile-vs-new-agile/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://dzone.com/articles/old-versus-new-agile&quot;&gt;DZone source&lt;/a&gt; citing Cliff Berg as original source, but link appears broken?&lt;/p&gt; 
&lt;p&gt;Agile has changed. In the &lt;a href=&quot;https://produxlabs.com/product-thinking-blog/episode-15-jeff-patton&quot;&gt;words of Jeff Patton&lt;/a&gt;,&lt;/p&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;“When people say Agile today, they mean something different today than they did in 2001... it&apos;s come to mean something else.”&lt;/p&gt; 
&lt;/blockquote&gt; 
&lt;p&gt;Unfortunately, some members of the Agile community are stuck in the past. They still believe early Agile myths and dogma such as:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Every team can and should self organize.&lt;/li&gt; 
 &lt;li&gt;Teams can and should be fully autonomous.&lt;/li&gt; 
 &lt;li&gt;Before Agile there was only waterfall.&lt;/li&gt; 
 &lt;li&gt;Programming is a mostly social activity, and is analogous to sports.&lt;/li&gt; 
 &lt;li&gt;Agile coaches do not need to take an interest in the technical aspects of how the work is done, such as DevOps issues.&lt;/li&gt; 
 &lt;li&gt;Facilitators do not need to understand the subject being discussed.&lt;/li&gt; 
 &lt;li&gt;Good leadership usually emerges.&lt;/li&gt; 
 &lt;li&gt;The team usually knows best.&lt;/li&gt; 
 &lt;li&gt;The human side of Agile is where the focus should be: the team will take care of the technical side in the course of their work if you merely empower them.&lt;/li&gt; 
 &lt;li&gt;A team needs a methodology or framework.&lt;/li&gt; 
 &lt;li&gt;The problems that need solving are mostly at the team level.&lt;/li&gt; 
 &lt;li&gt;Scrum and Kanban are the only choices.&lt;/li&gt; 
 &lt;li&gt;Popular Agile practices such as face-to-face communication, a team room, standups, TDD, and pair programming are best for everyone and all teams.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;Granted, not everyone bought into the above extremes, but a great many did, and these became assumed standard views across the Agile community during its early years. Yet if one looks at a range of compelling books and blogs that have come out in the past ten years from new authors, they paint a very different picture, and it is remarkably consistent. These arguably define a “new Agile”. Who are these new authors and what do they say? What is the “new Agile”?&lt;/p&gt; 
&lt;p&gt;One of my favorites is Klaus Leopold, and his book &lt;em&gt;Rethinking Agile: Why Agile Teams Have Nothing To Do With Business Agility&lt;/em&gt;. It is a non-technical book, so you won’t find DevOps in it, but despite that he brilliantly paints a vivid picture of why old-school Agile’s obsessive focus on teams causes us to lose sight of the product. He connects the dots on just how much has to happen to get a product to market and why an Agile team is only a tiny slice of that, and why all those involved need to understand the big picture and not just their little slice.&lt;/p&gt; 
&lt;p&gt;Another favorite is Mathew Skelton and Manuel Pais’s book &lt;a href=&quot;../management/team-topologies&quot;&gt;&lt;em&gt;Team Topologies&lt;/em&gt;&lt;/a&gt;. In it they expertly explain how teams exist in an ecosystem, and that the structures around those teams and how they interact is what is most important of all. Unlike old-school Agile’s tunnel vision about “the team”, Skelton and Pais explain why the entire product creation ecosystem is the wicked problem that must be solved.&lt;/p&gt; 
&lt;p&gt;Some old-school Agilists might react with, “But Agile has always pointed to the need for the organization to be Agile.” Well, I was around in the early days, and that is not true. The claim that the organization needs to be Agile really became loud during the late 2000s, after it became clear that inserting Scrum into an existing organization (which Scrum proponents happily supported) did not work, and we saw the rise of the mantra “Don’t do Agile, be Agile.” But by and large, Agilists had no answer for what it looked like for an organization to “be Agile”. Eventually the message became that an organization needs to have an “Agile mindset”, but again that is ill-defined. It is a catch-all for the unknown. In fact, this ambiguity is what led me and others in 2014 to launch Transition2Agile.com, for which we assembled a team that included people who had actually studied organizational behavior.&lt;/p&gt; 
&lt;p&gt;The books and blogs of new Agile are too numerous to list, but I need to mention some more so that you can see the pattern. Of particular note is the acclaimed book &lt;em&gt;Accelerate&lt;/em&gt; by Dr. Nicole Forsgren (now VP of Research and Strategy at GitHub), Jez Humble (arguably the “father” of continuous delivery), and Gene Kim (perhaps the “father” of DevOps). In that book they have an entire chapter about leadership, which states (in the Kindle Edition, pp. 238–239),&lt;/p&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;“Why have technology practitioners continuously sought to improve the approach to software development and deployment as well as the stability and security of infrastructure and platforms, yet, in large part, have overlooked (or are unclear about) the way to lead, manage, and sustain these endeavors?. . .we must improve the way we lead and manage IT.”&lt;/p&gt; 
&lt;/blockquote&gt; 
&lt;p&gt;They are pointing to the need for explicit leadership: self organization is not sufficient. In their book, they also provide statistically validated evidence that technical practices pertaining to DevOps strongly and causally correlate with business performance.&lt;/p&gt; 
&lt;p&gt;In the community of thinkers who write about business agility, the topic of leadership is central. The obsessive emphasis on self organization and autonomy are not present: the focus is on having the right kinds of leadership who can create the right climate and support so that people can be empowered. (“Empowered” is not the same as “autonomous.”) Academic writings on organization culture and leadership theory also emphasize the need for the right kinds of leadership.&lt;/p&gt; 
&lt;p&gt;(A note about team autonomy: Among people who really know how this works, “autonomous” is actually shorthand for “mostly autonomous”. For a team to be mostly autonomous, they need to have the right training, skills, experience, support teams, and self-service infrastructure; and even then, they are seldom 100% autonomous.)&lt;/p&gt; 
&lt;p&gt;There are countless other authors who have written powerful books about how humans work best together, including David Marquet, Dr. Daniel Kahneman, Eric Ries, MIrco Hering, Dr. Marta Wilson, Daniel Pink, Patrick Lencioni, Titus Winters (“Software Engineering at Google”), Mik Kersten, Greg McKeown, Jeff Dalton, and many others. Importantly, there are also authors who dismantle the extrovert-favoring and non-neurodiverse bias of the Agile community, including Susan Cain, Cal Newport, and Daniel Goleman. There are also bloggers such as Maarten Dalmijn and countless others who have pointed to myths and dysfunctions with some original Agile ideas and traditions.&lt;/p&gt; 
&lt;h4&gt;The “New Agile” Ideas&lt;/h4&gt; 
&lt;p&gt;And then there is &lt;a href=&quot;https://agile2.net/&quot;&gt;Agile 2&lt;/a&gt;. Agile 2 is new in that it aggregates the ideas of these new thinkers, and integrates these ideas into a cohesive system of thought, while adding missing pieces. Agile 2 interprets these many writings and translates them into a common and holistically integrated shared narrative.&lt;/p&gt; 
&lt;p&gt;But what is that narrative? Agile 2 is complex because humans are complex. It is not a set of bumper sticker maxims asserted without supporting explanation and rationale. Agile 2 is nuanced and broad, and is published with the thought that went into it. But I will summarize it, to give you a sense.&lt;/p&gt; 
&lt;p&gt;Agile 2 is defined by its &lt;a href=&quot;https://agile2.net/agile-2/the-values-and-principles-of-agile-2/&quot;&gt;Values and Principles&lt;/a&gt;. Most of those principles could be summarized as described &lt;a href=&quot;https://agile2.net/more-resources/agile-2-in-a-nutshell/&quot;&gt;here&lt;/a&gt;. Basically, Agile 2 says that extremes don’t usually work well, and that judgment is called for when applying any practice. It also emphasizes the critical importance of having the right kinds of leadership for each situation. Note that “kinds of leadership” is plural. Agile 2 favors emergent leadership and autonomy, but it views those as aspirations rather than assumptions, and includes the theory that senior leaders need to be intentional about the kinds of leadership needed within their organization, as well as take an experimental yet thoughtful approach to the problem of leadership.&lt;/p&gt; 
&lt;p&gt;Another main thesis of Agile 2 is that it embraces neurodiversity, and that effective collaboration about complex topics is not as simple as having a face-to-face conversation. It also recognizes that people not only need to collaborate, but they also need to focus and be able to attain deep thought—something that many people cannot do in a group setting.&lt;/p&gt; 
&lt;p&gt;Another key element of Agile 2 is focus on the product and the ecosystem, instead of on the team. The hard issues tend to be how collections of teams work together and within their ecosystem. Individuals are called out as well, as being important to mentor, develop and recognize just as much as teams need those things, pushing back on old-school Agile’s obsession with “the team”. Again, it is about balance rather than old-school Agile’s extreme focus on the team and minimization of the individual.&lt;/p&gt; 
&lt;h4&gt;Conclusion&lt;/h4&gt; 
&lt;p&gt;Agile needs to evolve — and it has. We all need to let go of early partially formed ideas and elevate our thinking. Much of the thinking is not new in the history of human discourse: many if not most Agile ideas, both new and old, have been expressed many times before; but what changes is the balance and the collections of ideas that link together into a narrative. We need to advance the narrative.&lt;/p&gt; 
&lt;p&gt;More recent Agile ideas are a more evolved expression of Agile. They are more “grown up” in a sense, because they reflect reality instead of a simplistic ideal. Recent ideas are more inclusive, diverse, and rich. Gone is the insistence that everyone works best a certain way: new Agile embraces neurodiversity and helping people to work together and collaborate even when they do not all work best and communicate best in the same way.&lt;/p&gt; 
&lt;p&gt;Finally, this grown-up new Agile is not just about teams: it is about ecosystems and teams, and it addresses head-on the need for leadership in many forms and in many directions, both outward-facing and inward-facing. New Agile builds on and resonates better with the thinking in other communities of thought, including business agility, DevOps, leadership, PeopleOps, and organization design.&lt;/p&gt; 
&lt;p&gt;It is long overdue. If you largely agree with what the aforementioned “new Agile” authors have been writing, then old-school Agile is dead. Long live new Agile, and long live Agile 2!&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>The Blank Sheet</title>
      <link>https://tedneward.github.io/Research/reading/the-blank-sheet/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">reading/the-blank-sheet/index.html</guid>
      	<description>
	&lt;p&gt;&lt;em&gt;(from &lt;a href=&quot;https://fs.blog/blank-sheet/&quot;&gt;https://fs.blog/blank-sheet/&lt;/a&gt;)&lt;/em&gt;&lt;/p&gt; 
&lt;p&gt;&lt;em&gt;The blank sheet method primes your brain for what you’re about to read and shows you what you’re learning.&lt;/em&gt;&lt;/p&gt; 
&lt;h2&gt;The Method&lt;/h2&gt; 
&lt;p&gt;Before you start reading a new book, take out a blank sheet of paper. Write down what you know about the book/subject you’re about to read — a mind map.&lt;/p&gt; 
&lt;p&gt;After you finish a reading session, spend a few minutes adding to the map with a different color pen.&lt;/p&gt; 
&lt;p&gt;Before you start your next reading session, review the page.&lt;/p&gt; 
&lt;p&gt;When you’re done reading, put these ‘blank sheets’ into a binder that you periodically review.&lt;/p&gt; 
&lt;h2&gt;Why does it work?&lt;/h2&gt; 
&lt;p&gt;The blank sheet method primes your brain for what you’re about to read, offers structure, and reinforces that you’re learning.&lt;/p&gt; 
&lt;p&gt;When you first start with a blank sheet, you’re forced to search your memory and put on paper what you know (or what you think you know) about a subject. As you read, you literally see the growth.&lt;/p&gt; 
&lt;p&gt;Not only will you add new knowledge, but equally valuable, you’ll remove things you thought you knew that turned out not to be so.&lt;/p&gt; 
&lt;p&gt;Reviewing what you know about a subject, as well as what you have already learned before a reading session, not only improves memory and recall but helps layer and connect ideas.&lt;/p&gt; 
&lt;p&gt;Most of the early connections come from putting the authors’ raw material onto your foundation. If you don’t know anything about the subject before you start, don’t worry. You can borrow the scaffolding in the book to get you started.&lt;/p&gt; 
&lt;p&gt;As your fluency in a subject grows, you’ll start connecting ideas across disciplines, disagreeing with authors about specific points, and even developing your own ideas.&lt;/p&gt; 
&lt;p&gt;This final step is essential for establishing deep fluency and connecting ideas across disciplines. When you finish the book, put the page into a binder. Review the binder every few months. Spaced repetition offers exponential returns for very little additional effort.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Fusionauth</title>
      <link>https://tedneward.github.io/Research/security/fusionauth/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">security/fusionauth/index.html</guid>
      	<description>
	&lt;h2&gt;Docker setup&lt;/h2&gt; 
&lt;pre&gt;&lt;code&gt;```
version: &apos;3&apos;

services:
db:
    image: postgres:12.9
    environment:
    PGDATA: /var/lib/postgresql/data/pgdata
    POSTGRES_USER: ${POSTGRES_USER}
    POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
    # Un-comment to access the db service directly
#   ports:
#     - 5432:5432
    networks:
    - db
    restart: unless-stopped
    volumes:
    - db_data:/var/lib/postgresql/data

fusionauth:
    image: fusionauth/fusionauth-app:latest
    depends_on:
    - db
    environment:
    DATABASE_URL: jdbc:postgresql://db:5432/fusionauth
    # Prior to version 1.19.0, use this deprecated name
    # DATABASE_ROOT_USER: ${POSTGRES_USER}
    DATABASE_ROOT_USERNAME: ${POSTGRES_USER}
    DATABASE_ROOT_PASSWORD: ${POSTGRES_PASSWORD}
    # Prior to version 1.19.0, use this deprecated name
    # DATABASE_USER: ${DATABASE_USER}
    DATABASE_USERNAME: ${DATABASE_USERNAME}
    DATABASE_PASSWORD: ${DATABASE_PASSWORD}
    # Prior to version 1.19.0, use this deprecated names
    # FUSIONAUTH_MEMORY: ${FUSIONAUTH_MEMORY}
    # FUSIONAUTH_SEARCH_ENGINE_TYPE: database
    # FUSIONAUTH_URL: http://fusionauth:9011
    # FUSIONAUTH_RUNTIME_MODE: development
    FUSIONAUTH_APP_MEMORY: ${FUSIONAUTH_APP_MEMORY}
    FUSIONAUTH_APP_RUNTIME_MODE: development
    FUSIONAUTH_APP_URL: http://fusionauth:9011
    SEARCH_TYPE: database


    networks:
    - db
    restart: unless-stopped
    ports:
    - 9011:9011
    volumes:
    - fa_config:/usr/local/fusionauth/config

networks:
db:
    driver: bridge

volumes:
db_data:
fa_config:
```

coupled with a .env file:
```
POSTGRES_USER=postgres
POSTGRES_PASSWORD=postgres
# Prior to version 1.19.0, using DATABASE_USER
DATABASE_USER=fusionauth
# &amp;gt;= 1.19.0, using DATABASE_USERNAME
DATABASE_USERNAME=fusionauth
DATABASE_PASSWORD=hkaLBM3RVnyYeYeqE3WI1w2e4Avpy0Wd5O3s3

ES_JAVA_OPTS=&quot;-Xms512m -Xmx512m&quot;

# Prior to version 1.19.0, using FUSIONAUTH_MEMORY
FUSIONAUTH_MEMORY=512M
# &amp;gt;= 1.19.0, using FUSIONAUTH_APP_MEMORY
FUSIONAUTH_APP_MEMORY=512M
```
&lt;/code&gt;&lt;/pre&gt;
	</description>
    </item>
    <item>
      <title>Security Patterns</title>
      <link>https://tedneward.github.io/Research/security/patterns/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">security/patterns/index.html</guid>
      	<description>
	&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://securitypatterns.distrinet-research.be/&quot;&gt;https://securitypatterns.distrinet-research.be/&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://hillside.net/plop/2022/papers/G1_P1.pdf&quot;&gt;https://hillside.net/plop/2022/papers/G1_P1.pdf&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://dl.acm.org/doi/10.5555/3631672.3631674&quot;&gt;https://dl.acm.org/doi/10.5555/3631672.3631674&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://coresecuritypatterns.websecuritypatterns.com/patterns.htm&quot;&gt;http://coresecuritypatterns.websecuritypatterns.com/patterns.htm&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://opensecurityarchitecture.org/&quot;&gt;https://opensecurityarchitecture.org/&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://archiv.infsec.ethz.ch/intranet_secured/education/as09/seceng/course_material_secured/patterns.pdf/patterns.pdf&quot;&gt;https://archiv.infsec.ethz.ch/intranet_secured/education/as09/seceng/course_material_secured/patterns.pdf/patterns.pdf&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>eXtreme Programming Explained</title>
      <link>https://tedneward.github.io/Research/reading/processes/extreme-programming-explained/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">reading/processes/extreme-programming-explained/index.html</guid>
      	<description>
	&lt;h1&gt;Principles:&lt;/h1&gt; 
&lt;ul&gt; 
 &lt;li&gt; &lt;p&gt;Rapid Feedback&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Assume Simplicity&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Incremental Change&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Embracing Change&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Quality Work&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Teach Learning&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Small Initial Investment&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Play to Win&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Concrete Experiments&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Open, Honest Communication&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Work with people&apos;s instincts, not against them&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Accepted Responsibility&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Local Adaptation&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Travel Light&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Honest Measurement&lt;/p&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h1&gt;Practices:&lt;/h1&gt; 
&lt;ul&gt; 
 &lt;li&gt; &lt;p&gt;The Planning Game&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Small Releases&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Metaphor&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Simple Design; do the simplest thing that could possibly work&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Testing&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Refactoring&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Pair Programming&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Collective Ownership&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Continuous Integration&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;40-hour week; you can&apos;t work a second week of overtime&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;On-site Customer&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Coding Standards; once and only once rule (DRY)&lt;/p&gt; &lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Release It!</title>
      <link>https://tedneward.github.io/Research/reading/processes/release-it/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">reading/processes/release-it/index.html</guid>
      	<description>
	&lt;p&gt;&lt;em&gt;(by Michael Nygard (Pragmatic Bookshelf, 2007, ISBN-13 978-0-9787392-1-8))&lt;/em&gt;&lt;/p&gt; 
&lt;h1&gt;Stability Antipatterns&lt;/h1&gt; 
&lt;ul&gt; 
 &lt;li&gt;Integration Points&lt;/li&gt; 
 &lt;li&gt;Chain Reactions&lt;/li&gt; 
 &lt;li&gt;Cascading Failures&lt;/li&gt; 
 &lt;li&gt;Users&lt;/li&gt; 
 &lt;li&gt;Blocked Threads&lt;/li&gt; 
 &lt;li&gt;Attacks of Self-Denial&lt;/li&gt; 
 &lt;li&gt;Scaling Effects&lt;/li&gt; 
 &lt;li&gt;Unbalanced Capacities&lt;/li&gt; 
 &lt;li&gt;Slow Responses&lt;/li&gt; 
 &lt;li&gt;SLA Inversion&lt;/li&gt; 
 &lt;li&gt;Unbounded Result Sets&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h1&gt;Stability Patterns&lt;/h1&gt; 
&lt;ul&gt; 
 &lt;li&gt;Use Timeouts&lt;/li&gt; 
 &lt;li&gt;Circuit Breaker&lt;/li&gt; 
 &lt;li&gt;Bulkheads&lt;/li&gt; 
 &lt;li&gt;Steady State&lt;/li&gt; 
 &lt;li&gt;Fail Fast&lt;/li&gt; 
 &lt;li&gt;Handshaking&lt;/li&gt; 
 &lt;li&gt;Test Harness&lt;/li&gt; 
 &lt;li&gt;Decoupling Middleware&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h1&gt;Capacity Antipatterns&lt;/h1&gt; 
&lt;ul&gt; 
 &lt;li&gt;Resource Pool Contention&lt;/li&gt; 
 &lt;li&gt;Excessive JSP Fragments&lt;/li&gt; 
 &lt;li&gt;AJAX Overkill&lt;/li&gt; 
 &lt;li&gt;Overstaying Sessions&lt;/li&gt; 
 &lt;li&gt;Wasted Space in HTML&lt;/li&gt; 
 &lt;li&gt;The Reload Button&lt;/li&gt; 
 &lt;li&gt;Handcrafted SQL&lt;/li&gt; 
 &lt;li&gt;Database Eutrophication&lt;/li&gt; 
 &lt;li&gt;Integration Point Latency&lt;/li&gt; 
 &lt;li&gt;Cookie Monsters&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h1&gt;Capacity Patterns&lt;/h1&gt; 
&lt;ul&gt; 
 &lt;li&gt;Pool Connections&lt;/li&gt; 
 &lt;li&gt;Use Caching Carefully&lt;/li&gt; 
 &lt;li&gt;Precompute Content&lt;/li&gt; 
 &lt;li&gt;Tune the Garbage Collector&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h1&gt;Networking&lt;/h1&gt; 
&lt;ul&gt; 
 &lt;li&gt;Multihomed Servers&lt;/li&gt; 
 &lt;li&gt;Routing&lt;/li&gt; 
 &lt;li&gt;Virtual IP Addresses&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h1&gt;Security&lt;/h1&gt; 
&lt;ul&gt; 
 &lt;li&gt;Principle of Least Privilege&lt;/li&gt; 
 &lt;li&gt;Configured Passwords&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h1&gt;Availability&lt;/h1&gt; 
&lt;ul&gt; 
 &lt;li&gt;Load Balancing&lt;/li&gt; 
 &lt;li&gt;Clustering&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h1&gt;Administration&lt;/h1&gt; 
&lt;ul&gt; 
 &lt;li&gt;Does QA Match Production?&lt;/li&gt; 
 &lt;li&gt;Configuration Files&lt;/li&gt; 
 &lt;li&gt;Start-up and Shutdown&lt;/li&gt; 
 &lt;li&gt;Administrative Interfaces&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h1&gt;Operations&lt;/h1&gt;
	</description>
    </item>
    <item>
      <title>Argus</title>
      <link>https://tedneward.github.io/Research/security/argus/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">security/argus/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/jasonxtn/argus.git&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;table&gt; 
 &lt;thead&gt; 
  &lt;tr&gt;
   &lt;th&gt; Category &lt;/th&gt;
   &lt;th&gt; Module Count &lt;/th&gt;
   &lt;th&gt; Key Examples &lt;/th&gt;
  &lt;/tr&gt; 
 &lt;/thead&gt; 
 &lt;tbody&gt; 
  &lt;tr&gt;
   &lt;td&gt; Network &amp;amp; Infrastructure &lt;/td&gt;
   &lt;td&gt; 52 &lt;/td&gt;
   &lt;td&gt; DNS Records, Open Ports Scan, WHOIS Lookup &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; Web Application Analysis &lt;/td&gt;
   &lt;td&gt; 50 &lt;/td&gt;
   &lt;td&gt; Directory Finder, Technology Stack Detection, GraphQL Probe &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; Security &amp;amp; Threat Intelligence &lt;/td&gt;
   &lt;td&gt; 33 &lt;/td&gt;
   &lt;td&gt; Censys Recon, Subdomain Enumeration, JS Malware Scanner &lt;/td&gt;
  &lt;/tr&gt; 
 &lt;/tbody&gt; 
&lt;/table&gt; 
&lt;h2&gt;Install&lt;/h2&gt; 
&lt;table&gt; 
 &lt;thead&gt; 
  &lt;tr&gt;
   &lt;th&gt; Option &lt;/th&gt;
   &lt;th&gt; Commands &lt;/th&gt;
   &lt;th&gt; Best For &lt;/th&gt;
  &lt;/tr&gt; 
 &lt;/thead&gt; 
 &lt;tbody&gt; 
  &lt;tr&gt;
   &lt;td&gt; No Install &lt;/td&gt;
   &lt;td&gt; git clone &lt;a href=&quot;https://github.com/jasonxtn/argus.git&quot;&gt;https://github.com/jasonxtn/argus.git&lt;/a&gt;; cd argus; pip install -r requirements.txt; python -m argus &lt;/td&gt;
   &lt;td&gt; Quick tests &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; Pip &lt;/td&gt;
   &lt;td&gt; pip install argus-recon; argus &lt;/td&gt;
   &lt;td&gt; Minimal setup &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; Full &lt;/td&gt;
   &lt;td&gt; git clone …; chmod +x install.sh; ./install.sh; python -m argus &lt;/td&gt;
   &lt;td&gt; Development &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; Docker &lt;/td&gt;
   &lt;td&gt; git clone …; docker build -t argus-recon:latest .; docker run … &lt;/td&gt;
   &lt;td&gt; Containers &lt;/td&gt;
  &lt;/tr&gt; 
 &lt;/tbody&gt; 
&lt;/table&gt;
	</description>
    </item>
    <item>
      <title>Network Security</title>
      <link>https://tedneward.github.io/Research/security/network/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">security/network/index.html</guid>
      	<description>
	&lt;h2&gt;Network architecture&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/sergiomarotco/Network-segmentation-cheat-sheet&quot;&gt;Network-segmentation-cheat-sheet&lt;/a&gt; - This project was created to publish the best practices for segmentation of the corporate network of any company. In general, the schemes in this project are suitable for any company.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Scanning / Pentesting&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.openvas.org/&quot;&gt;OpenVAS&lt;/a&gt; - OpenVAS is a framework of several services and tools offering a comprehensive and powerful vulnerability scanning and vulnerability management solution.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/rapid7/metasploit-framework&quot;&gt;Metasploit Framework&lt;/a&gt; - A tool for developing and executing exploit code against a remote target machine. Other important sub-projects include the Opcode Database, shellcode archive and related research.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.kali.org/&quot;&gt;Kali&lt;/a&gt; - Kali Linux is a Debian-derived Linux distribution designed for digital forensics and penetration testing. Kali Linux is preinstalled with numerous penetration-testing programs, including nmap (a port scanner), Wireshark (a packet analyzer), John the Ripper (a password cracker), and Aircrack-ng (a software suite for penetration-testing wireless LANs).&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://tsurugi-linux.org/&quot;&gt;tsurugi&lt;/a&gt; - heavily customized Linux distribution that designed to support DFIR investigations, malware analysis and OSINT activities. It is based on Ubuntu 20.04(64-bit with a 5.15.12 custom kernel)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/rafael-santiago/pig&quot;&gt;pig&lt;/a&gt; - A Linux packet crafting tool.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/gpotter2/awesome-scapy&quot;&gt;scapy&lt;/a&gt; - Scapy: the python-based interactive packet manipulation program &amp;amp; library.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/rfunix/Pompem&quot;&gt;Pompem&lt;/a&gt; - Pompem is an open source tool, which is designed to automate the search for exploits in major databases. Developed in Python, has a system of advanced search, thus facilitating the work of pentesters and ethical hackers. In its current version, performs searches in databases: Exploit-db, 1337day, Packetstorm Security...&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://nmap.org&quot;&gt;Nmap&lt;/a&gt; - Nmap is a free and open source utility for network discovery and security auditing.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/caffix/amass&quot;&gt;Amass&lt;/a&gt; - Amass performs DNS subdomain enumeration by scraping the largest number of disparate data sources, recursive brute forcing, crawling of web archives, permuting and altering names, reverse DNS sweeping and other techniques.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/rozgo/anevicon&quot;&gt;Anevicon&lt;/a&gt; - The most powerful UDP-based load generator, written in Rust.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/isgasho/finshir&quot;&gt;Finshir&lt;/a&gt; - A coroutines-driven Low &amp;amp; Slow traffic generator, written in Rust.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/GoVanguard/legion&quot;&gt;Legion&lt;/a&gt; - Open source semi-automated discovery and reconnaissance network penetration testing framework.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/aboul3la/Sublist3r&quot;&gt;Sublist3r&lt;/a&gt; - Fast subdomains enumeration tool for penetration testers&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/RustScan/RustScan&quot;&gt;RustScan&lt;/a&gt; - Faster Nmap scanning with Rust. Take a 17 minute Nmap scan down to 19 seconds.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/jtpereyda/boofuzz&quot;&gt;Boofuzz&lt;/a&gt; - Fuzzing engine and fuzz testing framework.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/RedTeamPentesting/monsoon&quot;&gt;monsoon&lt;/a&gt; - Very flexible and fast interactive HTTP enumeration/fuzzing.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/spectralops/netz&quot;&gt;Netz&lt;/a&gt;- Discover internet-wide misconfigurations, using zgrab2 and others.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/deepfence/ThreatMapper&quot;&gt;Deepfence ThreatMapper&lt;/a&gt; - Apache v2, powerful runtime vulnerability scanner for kubernetes, virtual machines and serverless.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/deepfence/SecretScanner&quot;&gt;Deepfence SecretScanner&lt;/a&gt; - Find secrets and passwords in container images and file systems.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/padok-team/cognito-scanner&quot;&gt;Cognito Scanner&lt;/a&gt; - CLI tool to pentest Cognito AWS instance. It implements three attacks: unwanted account creation, account oracle and identity pool escalation&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Monitoring / Logging&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/retracedhq/retraced&quot;&gt;BoxyHQ&lt;/a&gt; - Open source API for security and compliance audit logging.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://justniffer.sourceforge.net/&quot;&gt;justniffer&lt;/a&gt; - Justniffer is a network protocol analyzer that captures network traffic and produces logs in a customized way, can emulate Apache web server log files, track response times and extract all &quot;intercepted&quot; files from the HTTP traffic.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://dumpsterventures.com/jason/httpry/&quot;&gt;httpry&lt;/a&gt; - httpry is a specialized packet sniffer designed for displaying and logging HTTP traffic. It is not intended to perform analysis itself, but to capture, parse, and log the traffic for later analysis. It can be run in real-time displaying the traffic as it is parsed, or as a daemon process that logs to an output file. It is written to be as lightweight and flexible as possible, so that it can be easily adaptable to different applications.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://ngrep.sourceforge.net/&quot;&gt;ngrep&lt;/a&gt; - ngrep strives to provide most of GNU grep&apos;s common features, applying them to the network layer. ngrep is a pcap-aware tool that will allow you to specify extended regular or hexadecimal expressions to match against data payloads of packets. It currently recognizes IPv4/6, TCP, UDP, ICMPv4/6, IGMP and Raw across Ethernet, PPP, SLIP, FDDI, Token Ring and null interfaces, and understands BPF filter logic in the same fashion as more common packet sniffing tools, such as tcpdump and snoop.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/gamelinux/passivedns&quot;&gt;passivedns&lt;/a&gt; - A tool to collect DNS records passively to aid Incident handling, Network Security Monitoring (NSM) and general digital forensics. PassiveDNS sniffs traffic from an interface or reads a pcap-file and outputs the DNS-server answers to a log file. PassiveDNS can cache/aggregate duplicate DNS answers in-memory, limiting the amount of data in the logfile without loosing the essens in the DNS answer.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://sagan.quadrantsec.com/&quot;&gt;sagan&lt;/a&gt; - Sagan uses a &apos;Snort like&apos; engine and rules to analyze logs (syslog/event log/snmptrap/netflow/etc).&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.ntop.org/products/traffic-analysis/ntop/&quot;&gt;ntopng&lt;/a&gt; - Ntopng is a network traffic probe that shows the network usage, similar to what the popular top Unix command does.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/rabbitstack/fibratus&quot;&gt;Fibratus&lt;/a&gt; - Fibratus is a tool for exploration and tracing of the Windows kernel. It is able to capture the most of the Windows kernel activity - process/thread creation and termination, file system I/O, registry, network activity, DLL loading/unloading and much more. Fibratus has a very simple CLI which encapsulates the machinery to start the kernel event stream collector, set kernel event filters or run the lightweight Python modules called filaments.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/evilsocket/opensnitch&quot;&gt;opensnitch&lt;/a&gt; - OpenSnitch is a GNU/Linux port of the Little Snitch application firewall&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/wazuh/wazuh&quot;&gt;wazuh&lt;/a&gt; - Wazuh is a free and open source platform used for threat prevention, detection, and response. It is capable of monitoring file system changes, system calls and inventory changes.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/matanolabs/matano&quot;&gt;Matano&lt;/a&gt;: Open source serverless security lake platform on AWS that lets you ingest, store, and analyze petabytes of security data into an Apache Iceberg data lake and run realtime Python detections as code.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://falco.org/&quot;&gt;Falco&lt;/a&gt; - The cloud-native runtime security project and de facto Kubernetes threat detection engine now part of the CNCF.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/tenzir/vast&quot;&gt;VAST&lt;/a&gt; - Open source security data pipeline engine for structured event data, supporting high-volume telemetry ingestion, compaction, and retrieval; purpose-built for security content execution, guided threat hunting, and large-scale investigation.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/brexhq/substation&quot;&gt;Substation&lt;/a&gt; - Substation is a cloud native data pipeline and transformation toolkit written in Go.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;IDS / IPS / Host IDS / Host IPS&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.snort.org/&quot;&gt;Snort&lt;/a&gt; - Snort is a free and open source network intrusion prevention system (NIPS) and network intrusion detection system (NIDS)created by Martin Roesch in 1998. Snort is now developed by Sourcefire, of which Roesch is the founder and CTO. In 2009, Snort entered InfoWorld&apos;s Open Source Hall of Fame as one of the &quot;greatest [pieces of] open source software of all time&quot;.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://zeek.org/&quot;&gt;Zeek&lt;/a&gt; - Zeek is a powerful network analysis framework that is much different from the typical IDS you may know.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/corelight/zeek2es&quot;&gt;zeek2es&lt;/a&gt; - An open source tool to convert Zeek logs to Elastic/OpenSearch. You can also output pure JSON from Zeek&apos;s TSV logs!&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://drkeithjones.com&quot;&gt;DrKeithJones.com&lt;/a&gt; - A blog on cyber security and network security monitoring.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://ossec.github.io/&quot;&gt;OSSEC&lt;/a&gt; - Comprehensive Open Source HIDS. Not for the faint of heart. Takes a bit to get your head around how it works. Performs log analysis, file integrity checking, policy monitoring, rootkit detection, real-time alerting and active response. It runs on most operating systems, including Linux, MacOS, Solaris, HP-UX, AIX and Windows. Plenty of reasonable documentation. Sweet spot is medium to large deployments.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://suricata-ids.org/&quot;&gt;Suricata&lt;/a&gt; - Suricata is a high performance Network IDS, IPS and Network Security Monitoring engine. Open Source and owned by a community run non-profit foundation, the Open Information Security Foundation (OISF). Suricata is developed by the OISF and its supporting vendors.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://blog.securityonion.net/&quot;&gt;Security Onion&lt;/a&gt; - Security Onion is a Linux distro for intrusion detection, network security monitoring, and log management. It&apos;s based on Ubuntu and contains Snort, Suricata, Zeek, OSSEC, Sguil, Squert, Snorby, ELSA, Xplico, NetworkMiner, and many other security tools. The easy-to-use Setup wizard allows you to build an army of distributed sensors for your enterprise in minutes!&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/marshyski/sshwatch&quot;&gt;sshwatch&lt;/a&gt; - IPS for SSH similar to DenyHosts written in Python. It also can gather information about attacker during the attack in a log.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://fbb-git.gitlab.io/stealth/&quot;&gt;Stealth&lt;/a&gt; - File integrity checker that leaves virtually no sediment. Controller runs from another machine, which makes it hard for an attacker to know that the file system is being checked at defined pseudo random intervals over SSH. Highly recommended for small to medium deployments.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://bitbucket.org/camp0/aiengine&quot;&gt;AIEngine&lt;/a&gt; - AIEngine is a next generation interactive/programmable Python/Ruby/Java/Lua packet inspection engine with capabilities of learning without any human intervention, NIDS(Network Intrusion Detection System) functionality, DNS domain classification, network collector, network forensics and many others.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://denyhosts.sourceforge.net/&quot;&gt;Denyhosts&lt;/a&gt; - Thwart SSH dictionary based attacks and brute force attacks.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.fail2ban.org/wiki/index.php/Main_Page&quot;&gt;Fail2Ban&lt;/a&gt; - Scans log files and takes action on IPs that show malicious behavior.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.sshguard.net/&quot;&gt;SSHGuard&lt;/a&gt; - A software to protect services in addition to SSH, written in C&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://cisofy.com/lynis/&quot;&gt;Lynis&lt;/a&gt; - an open source security auditing tool for Linux/Unix.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/crowdsecurity/crowdsec&quot;&gt;CrowdSec&lt;/a&gt; - CrowdSec is a free, modern &amp;amp; collaborative behavior detection engine, coupled with a global IP reputation network. It stacks on Fail2Ban&apos;s philosophy but is IPV6 compatible and 60x faster (Go vs Python), uses Grok patterns to parse logs and YAML scenario to identify behaviors. CrowdSec is engineered for modern Cloud / Containers / VM based infrastructures (by decoupling detection and remediation). Once detected, you can remedy threats with various bouncers (firewall block, nginx http 403, Captchas, etc.) while the aggressive IPs can be sent to CrowdSec for curation before being shared among all users to further strengthen the community&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/wazuh/wazuh&quot;&gt;wazuh&lt;/a&gt; - Wazuh is a free and open source XDR platform used for threat prevention, detection, and response. It is capable of protecting workloads across on-premises, virtualized, containerized, and cloud-based environments. Great tool foor all kind of deployments, it includes SIEM capabitilies (indexing + searching + WUI).&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Honey Pot / Honey Net&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/paralax/awesome-honeypots&quot;&gt;awesome-honeypots&lt;/a&gt; - The canonical awesome honeypot list.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/foospidy/HoneyPy&quot;&gt;HoneyPy&lt;/a&gt; - HoneyPy is a low to medium interaction honeypot. It is intended to be easy to: deploy, extend functionality with plugins, and apply custom configurations.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://conpot.org/&quot;&gt;Conpot&lt;/a&gt; - ICS/SCADA Honeypot. Conpot is a low interactive server side Industrial Control Systems honeypot designed to be easy to deploy, modify and extend. By providing a range of common industrial control protocols we created the basics to build your own system, capable to emulate complex infrastructures to convince an adversary that he just found a huge industrial complex. To improve the deceptive capabilities, we also provided the possibility to server a custom human machine interface to increase the honeypots attack surface. The response times of the services can be artificially delayed to mimic the behaviour of a system under constant load. Because we are providing complete stacks of the protocols, Conpot can be accessed with productive HMI&apos;s or extended with real hardware. Conpot is developed under the umbrella of the Honeynet Project and on the shoulders of a couple of very big giants.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/zeroq/amun&quot;&gt;Amun&lt;/a&gt; - Amun Python-based low-interaction Honeypot.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://glastopf.org/&quot;&gt;Glastopf&lt;/a&gt; - Glastopf is a Honeypot which emulates thousands of vulnerabilities to gather data from attacks targeting web applications. The principle behind it is very simple: Reply the correct response to the attacker exploiting the web application.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/desaster/kippo&quot;&gt;Kippo&lt;/a&gt; - Kippo is a medium interaction SSH honeypot designed to log brute force attacks and, most importantly, the entire shell interaction performed by the attacker.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://kojoney.sourceforge.net/&quot;&gt;Kojoney&lt;/a&gt; - Kojoney is a low level interaction honeypot that emulates an SSH server. The daemon is written in Python using the Twisted Conch libraries.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/tnich/honssh&quot;&gt;HonSSH&lt;/a&gt; - HonSSH is a high-interaction Honey Pot solution. HonSSH will sit between an attacker and a honey pot, creating two separate SSH connections between them.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://sourceforge.net/projects/bifrozt/&quot;&gt;Bifrozt&lt;/a&gt; - Bifrozt is a NAT device with a DHCP server that is usually deployed with one NIC connected directly to the Internet and one NIC connected to the internal network. What differentiates Bifrozt from other standard NAT devices is its ability to work as a transparent SSHv2 proxy between an attacker and your honeypot. If you deployed an SSH server on Bifrozt’s internal network it would log all the interaction to a TTY file in plain text that could be viewed later and capture a copy of any files that were downloaded. You would not have to install any additional software, compile any kernel modules or use a specific version or type of operating system on the internal SSH server for this to work. It will limit outbound traffic to a set number of ports and will start to drop outbound packets on these ports when certain limits are exceeded.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://bruteforce.gr/honeydrive&quot;&gt;HoneyDrive&lt;/a&gt; - HoneyDrive is the premier honeypot Linux distro. It is a virtual appliance (OVA) with Xubuntu Desktop 12.04.4 LTS edition installed. It contains over 10 pre-installed and pre-configured honeypot software packages such as Kippo SSH honeypot, Dionaea and Amun malware honeypots, Honeyd low-interaction honeypot, Glastopf web honeypot and Wordpot, Conpot SCADA/ICS honeypot, Thug and PhoneyC honeyclients and more. Additionally it includes many useful pre-configured scripts and utilities to analyze, visualize and process the data it can capture, such as Kippo-Graph, Honeyd-Viz, DionaeaFR, an ELK stack and much more. Lastly, almost 90 well-known malware analysis, forensics and network monitoring related tools are also present in the distribution.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.cuckoosandbox.org/&quot;&gt;Cuckoo Sandbox&lt;/a&gt; - Cuckoo Sandbox is an Open Source software for automating analysis of suspicious files. To do so it makes use of custom components that monitor the behavior of the malicious processes while running in an isolated environment.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://dtag-dev-sec.github.io/mediator/feature/2017/11/07/t-pot-17.10.html&quot;&gt;T-Pot Honeypot Distro&lt;/a&gt; - T-Pot is based on the network installer of Ubuntu Server 16/17.x LTS. The honeypot daemons as well as other support components being used have been containerized using docker. This allows us to run multiple honeypot daemons on the same network interface while maintaining a small footprint and constrain each honeypot within its own environment. Installation over vanilla Ubuntu - &lt;a href=&quot;https://github.com/dtag-dev-sec/t-pot-autoinstall&quot;&gt;T-Pot Autoinstall&lt;/a&gt; - This script will install T-Pot 16.04/17.10 on a fresh Ubuntu 16.04.x LTS (64bit). It is intended to be used on hosted servers, where an Ubuntu base image is given and there is no ability to install custom ISO images. Successfully tested on vanilla Ubuntu 16.04.3 in VMware.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Full Packet Capture / Forensic&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/simsong/tcpflow&quot;&gt;tcpflow&lt;/a&gt; - tcpflow is a program that captures data transmitted as part of TCP connections (flows), and stores the data in a way that is convenient for protocol analysis and debugging. Each TCP flow is stored in its own file. Thus, the typical TCP flow will be stored in two files, one for each direction. tcpflow can also process stored &apos;tcpdump&apos; packet flows.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/deepfence/PacketStreamer&quot;&gt;Deepfence PacketStreamer&lt;/a&gt; - High-performance remote packet capture and collection tool, distributed tcpdump for cloud native environments.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.xplico.org/&quot;&gt;Xplico&lt;/a&gt; - The goal of Xplico is extract from an internet traffic capture the applications data contained. For example, from a pcap file Xplico extracts each email (POP, IMAP, and SMTP protocols), all HTTP contents, each VoIP call (SIP), FTP, TFTP, and so on. Xplico isn’t a network protocol analyzer. Xplico is an open source Network Forensic Analysis Tool (NFAT).&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/aol/moloch&quot;&gt;Moloch&lt;/a&gt; - Moloch is an open source, large scale IPv4 packet capturing (PCAP), indexing and database system. A simple web interface is provided for PCAP browsing, searching, and exporting. APIs are exposed that allow PCAP data and JSON-formatted session data to be downloaded directly. Simple security is implemented by using HTTPS and HTTP digest password support or by using apache in front. Moloch is not meant to replace IDS engines but instead work along side them to store and index all the network traffic in standard PCAP format, providing fast access. Moloch is built to be deployed across many systems and can scale to handle multiple gigabits/sec of traffic.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.openfpc.org&quot;&gt;OpenFPC&lt;/a&gt; - OpenFPC is a set of tools that combine to provide a lightweight full-packet network traffic recorder &amp;amp; buffering system. It&apos;s design goal is to allow non-expert users to deploy a distributed network traffic recorder on COTS hardware while integrating into existing alert and log management tools.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/USArmyResearchLab/Dshell&quot;&gt;Dshell&lt;/a&gt; - Dshell is a network forensic analysis framework. Enables rapid development of plugins to support the dissection of network packet captures.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/google/stenographer&quot;&gt;stenographer&lt;/a&gt; - Stenographer is a packet capture solution which aims to quickly spool all packets to disk, then provide simple, fast access to subsets of those packets.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Sniffer&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.wireshark.org&quot;&gt;wireshark&lt;/a&gt; - Wireshark is a free and open-source packet analyzer. It is used for network troubleshooting, analysis, software and communications protocol development, and education. Wireshark is very similar to tcpdump, but has a graphical front-end, plus some integrated sorting and filtering options.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://netsniff-ng.org/&quot;&gt;netsniff-ng&lt;/a&gt; - netsniff-ng is a free Linux networking toolkit, a Swiss army knife for your daily Linux network plumbing if you will. Its gain of performance is reached by zero-copy mechanisms, so that on packet reception and transmission the kernel does not need to copy packets from kernel space to user space and vice versa.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://addons.mozilla.org/en-US/firefox/addon/http-header-live/&quot;&gt;Live HTTP headers&lt;/a&gt; - Live HTTP headers is a free firefox addon to see your browser requests in real time. It shows the entire headers of the requests and can be used to find the security loopholes in implementations.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Security Information &amp;amp; Event Management&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.prelude-siem.org/&quot;&gt;Prelude&lt;/a&gt; - Prelude is a Universal &quot;Security Information &amp;amp; Event Management&quot; (SIEM) system. Prelude collects, normalizes, sorts, aggregates, correlates and reports all security-related events independently of the product brand or license giving rise to such events; Prelude is &quot;agentless&quot;.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.alienvault.com/open-threat-exchange/projects&quot;&gt;OSSIM&lt;/a&gt; - OSSIM provides all of the features that a security professional needs from a SIEM offering – event collection, normalization, and correlation.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/certsocietegenerale/FIR&quot;&gt;FIR&lt;/a&gt; - Fast Incident Response, a cybersecurity incident management platform.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/dogoncouch/LogESP&quot;&gt;LogESP&lt;/a&gt; - Open Source SIEM (Security Information and Event Management system).&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/wazuh/wazuh&quot;&gt;wazuh&lt;/a&gt; -Wazuh is a free, open source and enterprise-ready security monitoring solution for threat detection, integrity monitoring, incident response and compliance. It works with tons of data supported by an OpenSearch fork and custom WUI.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/tenzir/vast&quot;&gt;VAST&lt;/a&gt; - Open source security data pipeline engine for structured event data, supporting high-volume telemetry ingestion, compaction, and retrieval; purpose-built for security content execution, guided threat hunting, and large-scale investigation.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/matanolabs/matano&quot;&gt;Matano&lt;/a&gt; - Open source serverless security lake platform on AWS that lets you ingest, store, and analyze petabytes of security data into an Apache Iceberg data lake and run realtime Python detections as code.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;VPN&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://openvpn.net/&quot;&gt;OpenVPN&lt;/a&gt; - OpenVPN is an open source software application that implements virtual private network (VPN) techniques for creating secure point-to-point or site-to-site connections in routed or bridged configurations and remote access facilities. It uses a custom security protocol that utilizes SSL/TLS for key exchange.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/firezone/firezone&quot;&gt;Firezone&lt;/a&gt; - Open-source VPN server and egress firewall for Linux built on WireGuard that makes it simple to manage secure remote access to your company’s private networks. Firezone is easy to set up (all dependencies are bundled thanks to Chef Omnibus), secure, performant, and self hostable.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Fast Packet Processing&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;http://dpdk.org/&quot;&gt;DPDK&lt;/a&gt; - DPDK is a set of libraries and drivers for fast packet processing.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/pfq/PFQ&quot;&gt;PFQ&lt;/a&gt; - PFQ is a functional networking framework designed for the Linux operating system that allows efficient packets capture/transmission (10G and beyond), in-kernel functional processing and packets steering across sockets/end-points.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.ntop.org/products/packet-capture/pf_ring/&quot;&gt;PF_RING&lt;/a&gt; - PF_RING is a new type of network socket that dramatically improves the packet capture speed.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.ntop.org/products/packet-capture/pf_ring/pf_ring-zc-zero-copy/&quot;&gt;PF_RING ZC (Zero Copy)&lt;/a&gt; - PF_RING ZC (Zero Copy) is a flexible packet processing framework that allows you to achieve 1/10 Gbit line rate packet processing (both RX and TX) at any packet size. It implements zero copy operations including patterns for inter-process and inter-VM (KVM) communications.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://elixir.bootlin.com/linux/latest/source/Documentation/networking/packet_mmap.rst&quot;&gt;PACKET_MMAP/TPACKET/AF_PACKET&lt;/a&gt; - It&apos;s fine to use PACKET_MMAP to improve the performance of the capture and transmission process in Linux.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://info.iet.unipi.it/~luigi/netmap/&quot;&gt;netmap&lt;/a&gt; - netmap is a framework for high speed packet I/O. Together with its companion VALE software switch, it is implemented as a single kernel module and available for FreeBSD, Linux and now also Windows.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Firewall&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.pfsense.org/&quot;&gt;pfSense&lt;/a&gt; - Firewall and Router FreeBSD distribution.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://opnsense.org/&quot;&gt;OPNsense&lt;/a&gt; - is an open source, easy-to-use and easy-to-build FreeBSD based firewall and routing platform. OPNsense includes most of the features available in expensive commercial firewalls, and more in many cases. It brings the rich feature set of commercial offerings with the benefits of open and verifiable sources.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.cipherdyne.org/fwknop/&quot;&gt;fwknop&lt;/a&gt; - Protects ports via Single Packet Authorization in your firewall.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Anti-Spam&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/spamscanner&quot;&gt;Spam Scanner&lt;/a&gt; - Anti-Spam Scanning Service and Anti-Spam API by &lt;a href=&quot;https://github.com/niftylettuce&quot;&gt;@niftylettuce&lt;/a&gt;.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/rspamd/rspamd&quot;&gt;rspamd&lt;/a&gt; - Fast, free and open-source spam filtering system.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://spamassassin.apache.org/&quot;&gt;SpamAssassin&lt;/a&gt; - A powerful and popular email spam filter employing a variety of detection technique.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://scammerlist.now.sh/&quot;&gt;Scammer-List&lt;/a&gt; - A free open source AI based Scam and Spam Finder with a free API&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Docker Images for Penetration Testing &amp;amp; Security&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;code&gt;docker pull kalilinux/kali-linux-docker&lt;/code&gt; &lt;a href=&quot;https://hub.docker.com/r/kalilinux/kali-linux-docker/&quot;&gt;official Kali Linux&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;docker pull owasp/zap2docker-stable&lt;/code&gt; - &lt;a href=&quot;https://github.com/zaproxy/zaproxy&quot;&gt;official OWASP ZAP&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;docker pull wpscanteam/wpscan&lt;/code&gt; - &lt;a href=&quot;https://hub.docker.com/r/wpscanteam/wpscan/&quot;&gt;official WPScan&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;docker pull remnux/metasploit&lt;/code&gt; - &lt;a href=&quot;https://hub.docker.com/r/remnux/metasploit/&quot;&gt;docker-metasploit&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;docker pull citizenstig/dvwa&lt;/code&gt; - &lt;a href=&quot;https://hub.docker.com/r/citizenstig/dvwa/&quot;&gt;Damn Vulnerable Web Application (DVWA)&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;docker pull wpscanteam/vulnerablewordpress&lt;/code&gt; - &lt;a href=&quot;https://hub.docker.com/r/wpscanteam/vulnerablewordpress/&quot;&gt;Vulnerable WordPress Installation&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;docker pull hmlio/vaas-cve-2014-6271&lt;/code&gt; - &lt;a href=&quot;https://hub.docker.com/r/hmlio/vaas-cve-2014-6271/&quot;&gt;Vulnerability as a service: Shellshock&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;docker pull hmlio/vaas-cve-2014-0160&lt;/code&gt; - &lt;a href=&quot;https://hub.docker.com/r/hmlio/vaas-cve-2014-0160/&quot;&gt;Vulnerability as a service: Heartbleed&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;docker pull opendns/security-ninjas&lt;/code&gt; - &lt;a href=&quot;https://hub.docker.com/r/opendns/security-ninjas/&quot;&gt;Security Ninjas&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;docker pull diogomonica/docker-bench-security&lt;/code&gt; - &lt;a href=&quot;https://hub.docker.com/r/diogomonica/docker-bench-security/&quot;&gt;Docker Bench for Security&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;docker pull ismisepaul/securityshepherd&lt;/code&gt; - &lt;a href=&quot;https://hub.docker.com/r/ismisepaul/securityshepherd/&quot;&gt;OWASP Security Shepherd&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;docker pull danmx/docker-owasp-webgoat&lt;/code&gt; - &lt;a href=&quot;https://hub.docker.com/r/danmx/docker-owasp-webgoat/&quot;&gt;OWASP WebGoat Project docker image&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;docker-compose build &amp;amp;&amp;amp; docker-compose up&lt;/code&gt; - &lt;a href=&quot;https://github.com/owasp/nodegoat#option-3---run-nodegoat-on-docker&quot;&gt;OWASP NodeGoat&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;docker pull citizenstig/nowasp&lt;/code&gt; - &lt;a href=&quot;https://hub.docker.com/r/citizenstig/nowasp/&quot;&gt;OWASP Mutillidae II Web Pen-Test Practice Application&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;docker pull bkimminich/juice-shop&lt;/code&gt; - &lt;a href=&quot;https://hub.docker.com/r/bkimminich/juice-shop&quot;&gt;OWASP Juice Shop&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;docker pull jeroenwillemsen/wrongsecrets&lt;/code&gt;- &lt;a href=&quot;https://hub.docker.com/r/jeroenwillemsen/wrongsecrets&quot;&gt;OWASP WrongSecrets&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;docker run -dit --name trd -p 8081:80 cylabs/cy-threat-response&lt;/code&gt; - &lt;a href=&quot;https://hub.docker.com/r/cylabs/cy-threat-response&quot;&gt;Cyware Threat Response Docker&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;docker-compose -d up&lt;/code&gt; - &lt;a href=&quot;https://github.com/cider-security-research/cicd-goat&quot;&gt;cicd-goat&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Supertokens</title>
      <link>https://tedneward.github.io/Research/security/supertokens/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">security/supertokens/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://supertokens.com/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/supertokens/supertokens-core&quot;&gt;Source&lt;/a&gt; | &lt;a href=&quot;https://supertokens.io/docs/community/introduction&quot;&gt;Docs&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Supertokens architecture is optimized to add secure authentication for your users without compromising on user and developer experience&lt;/p&gt; 
&lt;p&gt;Three building blocks of SuperTokens architecture&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Frontend SDK: Manages session tokens and renders login UI widgets&lt;/li&gt; 
 &lt;li&gt;Backend SDK: Provides APIs for sign-up, sign-in, signout, session refreshing, etc. Your Frontend will talk to these APIs&lt;/li&gt; 
 &lt;li&gt;SuperTokens Core: The HTTP service for the core auth logic and database operations. This service is used by the Backend SDK&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;SuperTokens is an open-core alternative to proprietary login providers like Auth0 or AWS Cognito. We are different because we offer:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Open source: SuperTokens can be used for free, forever, with no limits on the number of users.&lt;/li&gt; 
 &lt;li&gt;An on-premises deployment so that you control 100% of your user data, using your own database.&lt;/li&gt; 
 &lt;li&gt;An end-to-end solution with login, sign-ups, user and session management, without all the complexities of OAuth protocols.&lt;/li&gt; 
 &lt;li&gt;Ease of implementation and higher security.&lt;/li&gt; 
 &lt;li&gt;Extensibility: Anyone can contribute and make SuperTokens better!&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Philosophy&lt;/h3&gt; 
&lt;p&gt;Authentication directly affects the UX, dev experience, and security of any app. We believe that current solutions cannot optimize for all three &quot;pillars&quot;, leading to many applications hand-rolling their own auth. This not only leads to security issues but is also a massive time drain.&lt;/p&gt; 
&lt;p&gt;We want to change that - we believe the only way is to provide a solution that has the right level of abstraction gives you maximum control, is secure, and is simple to use - just like if you build it yourself, from scratch (minus the time to learn, build, and maintain).&lt;/p&gt; 
&lt;p&gt;We also believe in the principle of least vendor lock-in. Your having full control of your user&apos;s data means that you can switch away from SuperTokens without forcing your existing users to logout, reset their passwords, or in the worst case, sign up again.&lt;/p&gt; 
&lt;hr&gt; 
&lt;h1&gt;SuperTokens and &quot;vanilla&quot; JS&lt;/h1&gt; 
&lt;p&gt;&lt;a href=&quot;https://supertokens.com/docs/web-js/index.html&quot;&gt;Docs&lt;/a&gt; | &lt;a href=&quot;https://github.com/supertokens/supertokens-web-js&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Using SuperTokens with vanilla JS involves two main parts: the frontend using the &lt;code&gt;supertokens-web-js&lt;/code&gt; SDK and a backend that uses a SuperTokens Backend SDK (for Node.js, Python, Go, etc.).&lt;/p&gt; 
&lt;p&gt;Installation: &lt;code&gt;npm i -s supertokens-website&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;Usage:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;supertokens.init({
    apiDomain: &quot;&amp;lt;URL to your auth backend&amp;gt;&quot;
});
&lt;/code&gt;&lt;/pre&gt;
	</description>
    </item>
    <item>
      <title>Process-related reading (Scrum, XP, Kanban, ...)</title>
      <link>https://tedneward.github.io/Research/reading/processes/index/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">reading/processes/index/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://age-of-product.com/sprint-anti-patterns/&quot;&gt;&quot;28 Sprint Anti-Patterns&quot;&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://uxdesign.cc/the-age-of-agile-must-end-bc89c0f084b7&quot;&gt;The Age of Agile Must End&lt;/a&gt;: &quot;As far as manifestos go, this is one of the more pathetic documents ever created. It lists four &quot;Values&quot; and twelve &quot;Principles.&quot; They may have been well-intentioned at their inception — that intention was to treat developers as humans, not cogs in a machine — but now we’ve gone full circle. These principles have devolved into something caustic for organizations. Viewed now, they’re variations on a theme of how a scrum pod can absolve themselves of any accountability.&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Individuals and interactions over processes and tools. &lt;em&gt;(Yeah, we’re gonna do things however we want)&lt;/em&gt;&lt;/li&gt; 
 &lt;li&gt;Welcome changing requirements, even in late development. &lt;em&gt;(We can also change our minds whenever)&lt;/em&gt;&lt;/li&gt; 
 &lt;li&gt;Projects are built around motivated individuals, who should be trusted. &lt;em&gt;(Leave us alone, take what you get)&lt;/em&gt;&lt;/li&gt; 
 &lt;li&gt;Working software is the primary measure of progress. &lt;em&gt;(The fact that we produced something, anything, is all that matters)&lt;/em&gt;&lt;/li&gt; 
 &lt;li&gt;Simplicity — the art of maximizing the amount of work not done — is essential. &lt;em&gt;(We are going to do as little as possible)&lt;/em&gt;&lt;/li&gt; 
 &lt;li&gt;Best architectures, requirements, and designs emerge from self-organizing teams. &lt;em&gt;(Don’t tell us what to do)&lt;/em&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;&quot;The combination of Agile principles and Scrum practices is disastrous for startups. These are operational directives from management; designers, PM’s, and engineers are not self-organizing and choosing to work this way. It’s all in the name of an &quot;MVP&quot; and time to market; this is what happens. &lt;em&gt;Every. Time.&lt;/em&gt;&quot;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://www.infoq.com/articles/real-options-enhance-agility/&quot;&gt;&quot;Real options&quot; underlie agile practices&lt;/a&gt;: Whether people realise it or not, &quot;freedom to choose&quot; is the underlying principle behind many of the agile practices. We call this principle Real Options. An understanding of Real Options allows us to develop and refine new agile practices and take agile into directions it hasn&apos;t gone before. Real Options also help us understand why some people resist some of the practices. &lt;em&gt;(I disagree with the premise, but the rest of the article has some good weight to it.)&lt;/em&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://www.researchgate.net/publication/313360479_Software_Development_Waste&quot;&gt;&quot;Software Development Waste&quot;&lt;/a&gt;: &quot;The purpose of this paper is to identify and describe different kinds of waste in software development.&quot;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://launchschool.com/books/agile_planning&quot;&gt;Agile Planning: From Ideas to Story Cards&lt;/a&gt; - Launch School&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://trunkbaseddevelopment.com/&quot;&gt;Trunk-Based Development&lt;/a&gt;: Pushing to main/master ain&apos;t all as bad as it&apos;s cracked up to be. &quot;A source-control branching model, where developers collaborate on code in a single branch called ‘trunk’ *, resist any pressure to create other long-lived development branches by employing documented techniques. They therefore avoid merge hell, do not break the build, and live happily ever after.&quot;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://tuple.app/pair-programming-guide/&quot;&gt;Pair Programming Guide&lt;/a&gt;, including the &lt;a href=&quot;https://tuple.app/pair-programming-guide/antipatterns&quot;&gt;Pair Programming Antipatterns&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://salfreudenberg.wordpress.com/2017/03/26/the-tag-team-tools-tasks-and-roles-in-collaborative-software-development/&quot;&gt;&quot;The &apos;tag team&apos;: tools, tasks and roles in collaborative software development&quot;&lt;/a&gt; (&lt;a href=&quot;https://salfreudenberg.files.wordpress.com/2017/03/finalthesis.pdf&quot;&gt;PDF&lt;/a&gt;)&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Scrum</title>
      <link>https://tedneward.github.io/Research/reading/processes/scrum/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">reading/processes/scrum/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;http://www.infoq.com/minibooks/scrum-xp-from-the-trenches-2&quot;&gt;Scrum and XP from the Trenches&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>BetterAuth</title>
      <link>https://tedneward.github.io/Research/security/betterauth/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">security/betterauth/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.better-auth.com/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/better-auth/better-auth&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>OAuth</title>
      <link>https://tedneward.github.io/Research/security/oauth/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">security/oauth/index.html</guid>
      	<description>
	&lt;h2&gt;Reading&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://pages.apigee.com/oauth-big-picture-ebook.html&quot;&gt;OAuth - The Big Picture&lt;/a&gt; (email address &lt;em&gt;requested&lt;/em&gt;)&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Web Security</title>
      <link>https://tedneward.github.io/Research/security/web/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">security/web/index.html</guid>
      	<description>
	&lt;h3&gt;Organizations&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.owasp.org&quot;&gt;OWASP&lt;/a&gt; - The Open Web Application Security Project (OWASP) is a 501(c)(3) worldwide not-for-profit charitable organization focused on improving the security of software.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://portswigger.net&quot;&gt;Portswigger&lt;/a&gt; - PortSwigger offers tools for web application security, testing &amp;amp; scanning. Choose from a wide range of security tools &amp;amp; identify the very latest vulnerabilities.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Web Application Firewall&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.modsecurity.org/&quot;&gt;ModSecurity&lt;/a&gt; - ModSecurity is a toolkit for real-time web application monitoring, logging, and access control.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/bunkerity/bunkerweb&quot;&gt;BunkerWeb&lt;/a&gt; - BunkerWeb is a full-featured open-source web server with ModeSecurity WAF, HTTPS with transparent Let&apos;s Encrypt renewal, automatic ban of strange behaviors based on HTTP codes, bot and bad IPs block, connection limits, state-of-the-art security presets, Web UI and much more.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/nbs-system/naxsi&quot;&gt;NAXSI&lt;/a&gt; - NAXSI is an open-source, high performance, low rules maintenance WAF for NGINX, NAXSI means Nginx Anti Xss &amp;amp; Sql Injection.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/uptimejp/sql_firewall&quot;&gt;sql_firewall&lt;/a&gt; SQL Firewall Extension for PostgreSQL&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/ironbee/ironbee&quot;&gt;ironbee&lt;/a&gt; - IronBee is an open source project to build a universal web application security sensor. IronBee as a framework for developing a system for securing web applications - a framework for building a web application firewall (WAF).&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/curiefense/curiefense&quot;&gt;Curiefense&lt;/a&gt; - Curiefense adds a broad set of automated web security tools, including a WAF to Envoy Proxy.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/openappsec/openappsec&quot;&gt;open-appsec&lt;/a&gt; - open-appsec is an open source machine-learning security engine that preemptively and automatically prevents threats against Web Application &amp;amp; APIs.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Scanning / Pentesting&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://spyse.com/&quot;&gt;Spyse&lt;/a&gt; - Spyse is an OSINT search engine that provides fresh data about the entire web. All the data is stored in its own DB for instant access and interconnected with each other for flexible search.&lt;br&gt; Provided data: IPv4 hosts, sub/domains/whois, ports/banners/protocols, technologies, OS, AS, wide SSL/TLS DB and more.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://sqlmap.org/&quot;&gt;sqlmap&lt;/a&gt; - sqlmap is an open source penetration testing tool that automates the process of detecting and exploiting SQL injection flaws and taking over of database servers. It comes with a powerful detection engine, many niche features for the ultimate penetration tester and a broad range of switches lasting from database fingerprinting, over data fetching from the database, to accessing the underlying file system and executing commands on the operating system via out-of-band connections.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.owasp.org/index.php/OWASP_Zed_Attack_Proxy_Project&quot;&gt;ZAP&lt;/a&gt; - The Zed Attack Proxy (ZAP) is an easy to use integrated penetration testing tool for finding vulnerabilities in web applications. It is designed to be used by people with a wide range of security experience and as such is ideal for developers and functional testers who are new to penetration testing. ZAP provides automated scanners as well as a set of tools that allow you to find security vulnerabilities manually.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.owasp.org/index.php/Testing_Checklist&quot;&gt;OWASP Testing Checklist v4&lt;/a&gt; - List of some controls to test during a web vulnerability assessment. Markdown version may be found &lt;a href=&quot;https://github.com/amocrenco/owasp-testing-checklist-v4-markdown/blob/master/README.md&quot;&gt;here&lt;/a&gt;.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://w3af.org/&quot;&gt;w3af&lt;/a&gt; - w3af is a Web Application Attack and Audit Framework. The project’s goal is to create a framework to help you secure your web applications by finding and exploiting all web application vulnerabilities.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/lanmaster53/recon-ng&quot;&gt;Recon-ng&lt;/a&gt; - Recon-ng is a full-featured Web Reconnaissance framework written in Python. Recon-ng has a look and feel similar to the Metasploit Framework.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/trustedsec/ptf&quot;&gt;PTF&lt;/a&gt; - The Penetration Testers Framework (PTF) is a way for modular support for up-to-date tools.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/guardicore/monkey&quot;&gt;Infection Monkey&lt;/a&gt; - A semi automatic pen testing tool for mapping/pen-testing networks. Simulates a human attacker.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/tijme/angularjs-csti-scanner&quot;&gt;ACSTIS&lt;/a&gt; - ACSTIS helps you to scan certain web applications for AngularJS Client-Side Template Injection (sometimes referred to as CSTI, sandbox escape or sandbox bypass). It supports scanning a single request but also crawling the entire web application for the AngularJS CSTI vulnerability.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/KishanBagaria/padding-oracle-attacker&quot;&gt;padding-oracle-attacker&lt;/a&gt; - padding-oracle-attacker is a CLI tool and library to execute padding oracle attacks (which decrypts data encrypted in CBC mode) easily, with support for concurrent network requests and an elegant UI.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/lirantal/is-website-vulnerable&quot;&gt;is-website-vulnerable&lt;/a&gt; - finds publicly known security vulnerabilities in a website&apos;s frontend JavaScript libraries.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/nil0x42/phpsploit&quot;&gt;PhpSploit&lt;/a&gt; - Full-featured C2 framework which silently persists on webserver via evil PHP oneliner. Built for stealth persistence, with many privilege-escalation &amp;amp; post-exploitation features.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/SpectralOps/keyscope&quot;&gt;Keyscope&lt;/a&gt; - Keyscope is an extensible key and secret validation for checking active secrets against multiple SaaS vendors built in Rust&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/v8blink/Chromium-based-XSS-Taint-Tracking&quot;&gt;Cyclops&lt;/a&gt; - The Cyclops is a web browser with XSS detection feature, it is chromium-based xss detection that used to find the flows from a source to a sink.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/marcinguy/scanmycode-ce&quot;&gt;Scanmycode CE (Community Edition)&lt;/a&gt; - Code Scanning/SAST/Static Analysis/Linting using many tools/Scanners with One Report. Currently supports: PHP, Java, Scala, Python, Ruby, Javascript, GO, Secret Scanning, Dependency Confusion, Trojan Source, Open Source and Proprietary Checks (total ca. 1000 checks)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/rusty-ferris-club/recon&quot;&gt;recon&lt;/a&gt; - a fast Rust based CLI that uses SQL to query over files, code, or malware with content classification and processing for security experts&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/Zigrin-Security/CakeFuzzer&quot;&gt;CakeFuzzer&lt;/a&gt; - The ultimate web application security testing tool for CakePHP-based web applications. CakeFuzzer employs a predefined set of attacks that are randomly modified before execution. Leveraging its deep understanding of the Cake PHP framework, Cake Fuzzer launches attacks on all potential application entry points.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/CERT-Polska/Artemis/&quot;&gt;Artemis&lt;/a&gt; - A modular vulnerability scanner with automatic report generation capabilities.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Runtime Application Self-Protection&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.sqreen.io/&quot;&gt;Sqreen&lt;/a&gt; - Sqreen is a Runtime Application Self-Protection (RASP) solution for software teams. An in-app agent instruments and monitors the app. Suspicious user activities are reported and attacks are blocked at runtime without code modification or traffic redirection.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/baidu/openrasp&quot;&gt;OpenRASP&lt;/a&gt; - An open source RASP solution actively maintained by Baidu Inc. With context-aware detection algorithm the project achieved nearly no false positives. And less than 3% performance reduction is observed under heavy server load.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Development&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.manning.com/books/api-security-in-action&quot;&gt;API Security in Action&lt;/a&gt; - Book covering API security including secure development, token-based authentication, JSON Web Tokens, OAuth 2, and Macaroons. (early access, published continuously, final release summer 2020)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.manning.com/books/secure-by-design?a_aid=danbjson&amp;amp;a_bid=0b3fac80&quot;&gt;Secure by Design&lt;/a&gt; - Book that identifies design patterns and coding styles that make lots of security vulnerabilities less likely. (early access, published continuously, final release fall 2017)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.manning.com/books/understanding-api-security&quot;&gt;Understanding API Security&lt;/a&gt; - Free eBook sampler that gives some context for how API security works in the real world by showing how APIs are put together and how the OAuth protocol can be used to protect them.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.manning.com/books/oauth-2-in-action&quot;&gt;OAuth 2 in Action&lt;/a&gt; - Book that teaches you practical use and deployment of OAuth 2 from the perspectives of a client, an authorization server, and a resource server.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/zaproxy/zap-api-nodejs&quot;&gt;OWASP ZAP Node API&lt;/a&gt; - Leverage the OWASP Zed Attack Proxy (ZAP) within your NodeJS applications with this official API.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/apps/guardrails&quot;&gt;GuardRails&lt;/a&gt; - A GitHub App that provides security feedback in Pull Requests.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/Bearer/bearer&quot;&gt;Bearer&lt;/a&gt; - Scan code for security risks and vulnerabilities leading to sensitive data exposures.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/bridgecrewio/checkov/&quot;&gt;Checkov&lt;/a&gt; - A static analysis tool for infrastucture as code (Terraform).&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/tfsec/tfsec/&quot;&gt;TFSec&lt;/a&gt; - A static analysis tool for infrastucture as code (Terraform).&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/Checkmarx/kics&quot;&gt;KICS&lt;/a&gt; - Scans IaC projects for security vulnerabilities, compliance issues, and infrastructure misconfiguration. Currently working with Terraform projects, Kubernetes manifests, Dockerfiles, AWS CloudFormation Templates, and Ansible playbooks.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/insidersec/insider&quot;&gt;Insider CLI&lt;/a&gt; - A open source Static Application Security Testing tool (SAST) written in GoLang for Java (Maven and Android), Kotlin (Android), Swift (iOS), .NET Full Framework, C# and Javascript (Node.js).&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.manning.com/books/full-stack-python-security&quot;&gt;Full Stack Python Security&lt;/a&gt; - A comprehensive look at cybersecurity for Python developers&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.manning.com/books/making-sense-of-cyber-security&quot;&gt;Making Sense of Cyber Security&lt;/a&gt; - A jargon-free, practical guide to the key concepts, terminology, and technologies of cybersecurity perfect for anyone planning or implementing a security strategy. (early access, published continuously, final release early 2022)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://owasp.org/www-project-application-security-verification-standard/&quot;&gt;Security Checklist by OWASP&lt;/a&gt; - A checklist by OWASP for testing web applications based on assurance level. Covers multiple topics like Architecture, IAM, Sanitization, Cryptography and Secure Configuration.&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Levels of War</title>
      <link>https://tedneward.github.io/Research/reading/levels-of-war/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">reading/levels-of-war/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.clausewitz.com/readings/Dunn.htm&quot;&gt;Levels of War: Just a Set of Labels?&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://thestrategybridge.org/the-bridge/2016/5/5/the-institutional-level-of-war&quot;&gt;The Institutional Level of War&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>DevOps</title>
      <link>https://tedneward.github.io/Research/reading/processes/devops/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">reading/processes/devops/index.html</guid>
      	<description>
	&lt;h2&gt;Articles&lt;/h2&gt; 
&lt;p&gt;&lt;a href=&quot;https://github.com/MichaelCade/90DaysOfDevOps&quot;&gt;90 Days of DevOps&lt;/a&gt;: &quot;This repository is my documenting repository for learning the world of DevOps. I started this journey on the 1st January 2022 and I plan to run to March 31st for a complete 90-day romp on spending an hour a day including weekends to get a foundational knowledge across a lot of different areas that make up DevOps.&quot; Including:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;What is and why do we use DevOps&lt;/li&gt; 
 &lt;li&gt;Learning a Programming Language&lt;/li&gt; 
 &lt;li&gt;Knowing Linux Basics&lt;/li&gt; 
 &lt;li&gt;Understand Networking&lt;/li&gt; 
 &lt;li&gt;Stick to one Cloud Provider (he uses Azure)&lt;/li&gt; 
 &lt;li&gt;Use Git Effectively&lt;/li&gt; 
 &lt;li&gt;Containers (Docker)&lt;/li&gt; 
 &lt;li&gt;Kubernetes&lt;/li&gt; 
 &lt;li&gt;Learn Infrastructure as Code (Terraform)&lt;/li&gt; 
 &lt;li&gt;Automate Configuration Management (Ansible)&lt;/li&gt; 
 &lt;li&gt;Create CI/CD Pipelines (Jenkins)&lt;/li&gt; 
 &lt;li&gt;Monitoring, Log Management, and Data Visualization&lt;/li&gt; 
 &lt;li&gt;Store &amp;amp; Protect Your Data&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Static Program Analysis</title>
      <link>https://tedneward.github.io/Research/reading/development/static-program-analysis/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">reading/development/static-program-analysis/index.html</guid>
      	<description>
	&lt;ul&gt; 
 &lt;li&gt;Static Analysis Roadmap 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://tpiazza.me/posts/2017-11-01-static-analysis-roadmap.html&quot;&gt;https://tpiazza.me/posts/2017-11-01-static-analysis-roadmap.html&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Best Practices for the use of Static Code Analysis within a Real-World Secure Development Lifecycle 
  &lt;ul&gt; 
   &lt;li&gt;2015; Jeremy Boone&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.nccgroup.trust/us/our-research/best-practices-for-the-use-of-static-code-analysis-within-a-real-world-secure-development-lifecycle/&quot;&gt;https://www.nccgroup.trust/us/our-research/best-practices-for-the-use-of-static-code-analysis-within-a-real-world-secure-development-lifecycle/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Bill Torpey - &lt;a href=&quot;http://btorpey.github.io/blog/categories/static-analysis/&quot;&gt;static analysis posts&lt;/a&gt; 
  &lt;ul&gt; 
   &lt;li&gt;Static Analysis with Clang - &lt;a href=&quot;http://btorpey.github.io/blog/2015/04/27/static-analysis-with-clang/&quot;&gt;http://btorpey.github.io/blog/2015/04/27/static-analysis-with-clang/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Mo&apos; Static - &lt;a href=&quot;http://btorpey.github.io/blog/2016/04/07/mo-static/&quot;&gt;http://btorpey.github.io/blog/2016/04/07/mo-static/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Even Mo&apos; Static - &lt;a href=&quot;http://btorpey.github.io/blog/2016/11/12/even-mo-static/&quot;&gt;http://btorpey.github.io/blog/2016/11/12/even-mo-static/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Lots o&apos; static - &lt;a href=&quot;http://btorpey.github.io/blog/2017/09/17/lotso-static/&quot;&gt;http://btorpey.github.io/blog/2017/09/17/lotso-static/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;OASIS Static Analysis Results Interchange Format (SARIF) TC 
  &lt;ul&gt; 
   &lt;li&gt;Defining a standard output format for static analysis tools&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.oasis-open.org/committees/tc_home.php?wg_abbrev=sarif&quot;&gt;https://www.oasis-open.org/committees/tc_home.php?wg_abbrev=sarif&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/oasis-tcs/sarif-spec&quot;&gt;https://github.com/oasis-tcs/sarif-spec&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Static Analysis Results: A Format and a Protocol: SARIF &amp;amp; SASP 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://blogs.grammatech.com/static-analysis-results-a-format-and-a-protocol-sarif-sasp&quot;&gt;https://blogs.grammatech.com/static-analysis-results-a-format-and-a-protocol-sarif-sasp&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;Integration of the Static Analysis Results Interchange Format in CogniCrypt 
    &lt;ul&gt; 
     &lt;li&gt;2019 arXiv&lt;/li&gt; 
     &lt;li&gt;Sriteja Kummita, Goran Piskachev&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://arxiv.org/abs/1907.02558&quot;&gt;https://arxiv.org/abs/1907.02558&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://semantic-domain.blogspot.com/2019/08/on-relationship-between-static-analysis.html&quot;&gt;On the Relationship Between Static Analysis and Type Theory&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Books&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://cs.au.dk/~amoeller/spa/&quot;&gt;Static Program Analysis&lt;/a&gt; by Anders Møller, Michael I. Schwartzbach&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Research&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;Static Analysis Symposia Central Site 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;http://staticanalysis.org/&quot;&gt;http://staticanalysis.org/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;A Few Billion Lines of Code Later: Using Static Analysis to Find Bugs in the Real World 
  &lt;ul&gt; 
   &lt;li&gt;Communications of the ACM, Vol. 53 No. 2, 2010&lt;/li&gt; 
   &lt;li&gt;Al Bessey, Ken Block, Ben Chelf, Andy Chou, Bryan Fulton, Seth Hallem, Charles Henri-Gros, Asya Kamsky, Scott McPeak, Dawson Engler&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://cacm.acm.org/magazines/2010/2/69354-a-few-billion-lines-of-code-later/fulltext&quot;&gt;https://cacm.acm.org/magazines/2010/2/69354-a-few-billion-lines-of-code-later/fulltext&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Automated Program Transformation for Improving Software Quality 
  &lt;ul&gt; 
   &lt;li&gt;2019 PhD Dissertation; Rijnard van Tonder&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.cs.cmu.edu/~rvantond/pdfs/rijnard-dissertation.pdf&quot;&gt;https://www.cs.cmu.edu/~rvantond/pdfs/rijnard-dissertation.pdf&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;How to Build Static Checking Systems Using Orders of Magnitude Less Code 
  &lt;ul&gt; 
   &lt;li&gt;ASPLOS 2016&lt;/li&gt; 
   &lt;li&gt;Fraser Brown, Andres Nötzli, Dawson Engler&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://web.stanford.edu/~mlfbrown/paper.pdf&quot;&gt;https://web.stanford.edu/~mlfbrown/paper.pdf&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://lambda-the-ultimate.org/node/5348&quot;&gt;http://lambda-the-ultimate.org/node/5348&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://blog.acolyer.org/2016/05/31/how-to-build-static-checking-systems-using-orders-of-magnitude-less-code/&quot;&gt;https://blog.acolyer.org/2016/05/31/how-to-build-static-checking-systems-using-orders-of-magnitude-less-code/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Lessons from Building Static Analysis Tools at Google 
  &lt;ul&gt; 
   &lt;li&gt;Communications of the ACM, Vol. 61 No. 4, 2018&lt;/li&gt; 
   &lt;li&gt;Caitlin Sadowski, Edward Aftandilian, Alex Eagle, Liam Miller-Cushon, Ciera Jaspan&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://cacm.acm.org/magazines/2018/4/226371-lessons-from-building-static-analysis-tools-at-google/abstract&quot;&gt;https://cacm.acm.org/magazines/2018/4/226371-lessons-from-building-static-analysis-tools-at-google/abstract&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://research.google.com/pubs/pub46576.html&quot;&gt;https://research.google.com/pubs/pub46576.html&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Object Model Construction for Inheritance in C++ and Its Applications to Program Analysis 
  &lt;ul&gt; 
   &lt;li&gt;Compiler Construction (CC) 2012&lt;/li&gt; 
   &lt;li&gt;Yang, Jing, Gogul Balakrishnan, Naoto Maeda, Franjo Ivancic, Aarti Gupta, Nishant Sinha, Sriram Sankaranarayanan, Naveen Sharma&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://dl.acm.org/citation.cfm?id=2259241&quot;&gt;https://dl.acm.org/citation.cfm?id=2259241&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://pages.cs.wisc.edu/~bgogul/Research/Papers/cc12.html&quot;&gt;http://pages.cs.wisc.edu/~bgogul/Research/Papers/cc12.html&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.semanticscholar.org/paper/Object-Model-Construction-for-Inheritance-in-C%2B%2B-a-Yang-Balakrishnan/510501c7051c03d5e2a70089deeda8dfc3a7304f&quot;&gt;https://www.semanticscholar.org/paper/Object-Model-Construction-for-Inheritance-in-C%2B%2B-a-Yang-Balakrishnan/510501c7051c03d5e2a70089deeda8dfc3a7304f&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.cs.colorado.edu/~srirams/papers/cc12-final.pdf&quot;&gt;https://www.cs.colorado.edu/~srirams/papers/cc12-final.pdf&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.225.2429&quot;&gt;http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.225.2429&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Scaling Static Analyses at Facebook 
  &lt;ul&gt; 
   &lt;li&gt;Dino Distefano, Manuel Fähndrich, Francesco Logozzo, Peter W. O&apos;Hearn&lt;/li&gt; 
   &lt;li&gt;Communications of the ACM, Vol. 62 No. 8, 2019&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://cacm.acm.org/magazines/2019/8/238344-scaling-static-analyses-at-facebook/fulltext&quot;&gt;https://cacm.acm.org/magazines/2019/8/238344-scaling-static-analyses-at-facebook/fulltext&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Source Language Representation of Function Summaries in Static Analysis 
  &lt;ul&gt; 
   &lt;li&gt;ICOOOLPS / ECOOP 2016&lt;/li&gt; 
   &lt;li&gt;Gábor Horváth, Norbert Pataki&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://2016.ecoop.org/event/icooolps-2016-source-language-representation-of-function-summaries-in-static-analysis&quot;&gt;https://2016.ecoop.org/event/icooolps-2016-source-language-representation-of-function-summaries-in-static-analysis&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Tailoring Programs for Static Analysis via Program Transformation 
  &lt;ul&gt; 
   &lt;li&gt;International Conference on Software Engineering (ICSE) 2020&lt;/li&gt; 
   &lt;li&gt;Rijnard van Tonder and Claire Le Goues&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.cs.cmu.edu/~rvantond/pdfs/tailoring-analysis-icse-2020.pdf&quot;&gt;https://www.cs.cmu.edu/~rvantond/pdfs/tailoring-analysis-icse-2020.pdf&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Toward Full Elasticity in Distributed Static Analysis 
  &lt;ul&gt; 
   &lt;li&gt;Diego Garbervetsky, Edgardo Zoppi, Thomas Ball, Ben Livshits&lt;/li&gt; 
   &lt;li&gt;2016 Microsoft Research Technical Report: MSR-TR-2015-88&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.microsoft.com/en-us/research/publication/toward-full-elasticity-distributed-static-analysis/&quot;&gt;https://www.microsoft.com/en-us/research/publication/toward-full-elasticity-distributed-static-analysis/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Undecidability of static analysis 
  &lt;ul&gt; 
   &lt;li&gt;ACM Letters on Programming Languages and Systems (LOPLAS) Volume 1 Issue 4, Dec. 1992&lt;/li&gt; 
   &lt;li&gt;William Landi&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://dl.acm.org/citation.cfm?id=161501&quot;&gt;https://dl.acm.org/citation.cfm?id=161501&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&quot;Two fundamental static-analysis problems are may alias and must alias. The former is not recursive (is undecidable), and the latter is not recursively enumerable (is uncomputable), even when all paths are executable in the program being analyzed for languages with if statements, loops, dynamic storage, and recursive data structures.&quot;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Testing</title>
      <link>https://tedneward.github.io/Research/reading/development/testing/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">reading/development/testing/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;http://principlesofchaos.org/&quot;&gt;Principles of Chaos Engineering&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://www.jamesshore.com/v2/projects/nullables/testing-without-mocks&quot;&gt;&quot;Testing Without Mocks: A Pattern Language&quot;&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;See also: &lt;a href=&quot;/reading/development/fuzzing&quot;&gt;Fuzzing&lt;/a&gt; || &lt;a href=&quot;/languages/compilers.correctness&quot;&gt;Compilers Correctness&lt;/a&gt;&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.sigsoft.org/&quot;&gt;ACM Special Interest Group on Software Engineering (SIGSOFT)&lt;/a&gt; 
  &lt;ul&gt; 
   &lt;li&gt;Open Table of Contents (TOC) Resources - &lt;a href=&quot;https://www.sigsoft.org/resources/opentoc.html&quot;&gt;https://www.sigsoft.org/resources/opentoc.html&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Testing Standards Working Party 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;http://www.testingstandards.co.uk/&quot;&gt;http://www.testingstandards.co.uk/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Living Glossary of Testing Terms - &lt;a href=&quot;http://www.testingstandards.co.uk/living_glossary.htm&quot;&gt;http://www.testingstandards.co.uk/living_glossary.htm&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;cpp-testing-no-excuses 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/d-led/cpp-testing-no-excuses&quot;&gt;https://github.com/d-led/cpp-testing-no-excuses&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;What Is a Good Test Case? 
  &lt;ul&gt; 
   &lt;li&gt;2003; Cem Kaner&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://www.kaner.com/pdfs/GoodTest.pdf&quot;&gt;http://www.kaner.com/pdfs/GoodTest.pdf&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;hr&gt; 
&lt;h1&gt;Blogs&lt;/h1&gt; 
&lt;ul&gt; 
 &lt;li&gt;Google Testing Blog 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://testing.googleblog.com/&quot;&gt;https://testing.googleblog.com/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Evolving Understanding About Exploratory Testing 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.developsense.com/blog/2008/09/evolving-understanding-about/&quot;&gt;https://www.developsense.com/blog/2008/09/evolving-understanding-about/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Exploratory Testing 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.satisfice.com/exploratory-testing&quot;&gt;https://www.satisfice.com/exploratory-testing&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;How SQLite Is Tested 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://sqlite.org/testing.html&quot;&gt;https://sqlite.org/testing.html&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;How the GNU coreutils are tested 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;http://www.pixelbeat.org/docs/coreutils-testing.html&quot;&gt;http://www.pixelbeat.org/docs/coreutils-testing.html&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Principles of Automated Testing 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;http://www.lihaoyi.com/post/PrinciplesofAutomatedTesting.html&quot;&gt;http://www.lihaoyi.com/post/PrinciplesofAutomatedTesting.html&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Refactoring for testability in C++ 
  &lt;ul&gt; 
   &lt;li&gt;Hard-to-test patterns in C++ and how to refactor them.&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/platisd/refactoring-for-testability-cpp&quot;&gt;https://github.com/platisd/refactoring-for-testability-cpp&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Testing in Production, the safe way 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://medium.com/@copyconstruct/testing-in-production-the-safe-way-18ca102d0ef1&quot;&gt;https://medium.com/@copyconstruct/testing-in-production-the-safe-way-18ca102d0ef1&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Blogs: Series&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://abseil.io/tips/&quot;&gt;Abseil C++ Tips of the Week (TotW)&lt;/a&gt; 
  &lt;ul&gt; 
   &lt;li&gt; &lt;h1&gt;122: Test Fixtures, Clarity, and Dataflow - &lt;a href=&quot;https://abseil.io/tips/122&quot;&gt;https://abseil.io/tips/122&lt;/a&gt;&lt;/h1&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;h1&gt;135: Test the Contract, not the Implementation - &lt;a href=&quot;https://abseil.io/tips/135&quot;&gt;https://abseil.io/tips/135&lt;/a&gt;&lt;/h1&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;James Grenning 
  &lt;ul&gt; 
   &lt;li&gt;TDD How-to: Get your Legacy C Into a Test Harness 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://wingman-sw.com/articles/tdd-legacy-c&quot;&gt;https://wingman-sw.com/articles/tdd-legacy-c&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://github.com/jwgrenning/cpputest-starter-project&quot;&gt;https://github.com/jwgrenning/cpputest-starter-project&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;TDD Guided by ZOMBIES 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;http://blog.wingman-sw.com/tdd-guided-by-zombies&quot;&gt;http://blog.wingman-sw.com/tdd-guided-by-zombies&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;Test-Driven Development For Embedded C++ Programmers 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://www.wingman-sw.com/articles/test-driven-development-for-embedded-c-plus-plus&quot;&gt;https://www.wingman-sw.com/articles/test-driven-development-for-embedded-c-plus-plus&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;John Regehr 
  &lt;ul&gt; 
   &lt;li&gt;Software Testing Using Function/Inverse Pairs - &lt;a href=&quot;https://blog.regehr.org/archives/708&quot;&gt;https://blog.regehr.org/archives/708&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Kent Beck 
  &lt;ul&gt; 
   &lt;li&gt;Programmer Test Principles 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://medium.com/@kentbeck_7670/programmer-test-principles-d01c064d7934&quot;&gt;https://medium.com/@kentbeck_7670/programmer-test-principles-d01c064d7934&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;“Unit” Tests? 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://www.facebook.com/notes/kent-beck/unit-tests/1726369154062608/&quot;&gt;https://www.facebook.com/notes/kent-beck/unit-tests/1726369154062608/&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Nelson Elhage 
  &lt;ul&gt; 
   &lt;li&gt;Two kinds of testing - &lt;a href=&quot;https://blog.nelhage.com/post/two-kinds-of-testing/&quot;&gt;https://blog.nelhage.com/post/two-kinds-of-testing/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;How I Write Tests - &lt;a href=&quot;https://blog.nelhage.com/2016/12/how-i-test/&quot;&gt;https://blog.nelhage.com/2016/12/how-i-test/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Design for Testability - &lt;a href=&quot;https://blog.nelhage.com/2016/03/design-for-testability/&quot;&gt;https://blog.nelhage.com/2016/03/design-for-testability/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Test suites as classifiers - &lt;a href=&quot;https://blog.nelhage.com/post/test-suites-as-classifiers/&quot;&gt;https://blog.nelhage.com/post/test-suites-as-classifiers/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;William Caputo 
  &lt;ul&gt; 
   &lt;li&gt;TDD: &quot;Failing to Falsify&quot; - &lt;a href=&quot;http://logosity.net/notes.html#2017.02&quot;&gt;http://logosity.net/notes.html#2017.02&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;The goal of &quot;unit testing&quot; in TDD - &lt;a href=&quot;http://logosity.net/notes.html#2017.09&quot;&gt;http://logosity.net/notes.html#2017.09&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;hr&gt; 
&lt;h1&gt;Books&lt;/h1&gt; 
&lt;ul&gt; 
 &lt;li&gt;Software Testing: From Theory to Practice 
  &lt;ul&gt; 
   &lt;li&gt;Maurício Aniche &amp;amp; Arie van Deursen&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://sttp.site/&quot;&gt;https://sttp.site/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;The Fuzzing Book: Tools and Techniques for Generating Software Tests 
  &lt;ul&gt; 
   &lt;li&gt;Andreas Zeller, Rahul Gopinath, Marcel Böhme, Gordon Fraser, Christian Holler&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.fuzzingbook.org/&quot;&gt;https://www.fuzzingbook.org/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;hr&gt; 
&lt;h1&gt;Courses&lt;/h1&gt; 
&lt;ul&gt; 
 &lt;li&gt;CMPT 473: Software Testing, Reliability and Security 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.cs.sfu.ca/~wsumner/&quot;&gt;Nick Sumner&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://www2.cs.sfu.ca/~wsumner/teaching/473/&quot;&gt;http://www2.cs.sfu.ca/~wsumner/teaching/473/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Software Analysis and Testing 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;http://www.cis.upenn.edu/~mhnaik/&quot;&gt;Mayur Naik&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://RightingCode.org/&quot;&gt;https://RightingCode.org/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://www.cis.upenn.edu/~mhnaik/edu/cis700/&quot;&gt;http://www.cis.upenn.edu/~mhnaik/edu/cis700/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/channel/UCvwqRhlkE_Wm2FF9qzvHfJw&quot;&gt;https://www.youtube.com/channel/UCvwqRhlkE_Wm2FF9qzvHfJw&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Software Testing: How to Make Software Fail 
  &lt;ul&gt; 
   &lt;li&gt;John Regehr &amp;amp; Sean Bennett&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.udacity.com/course/software-testing--cs258&quot;&gt;https://www.udacity.com/course/software-testing--cs258&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;hr&gt; 
&lt;h1&gt;Research&lt;/h1&gt; 
&lt;h2&gt;Research: 2010s&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;Assertions Are Strongly Correlated with Test Suite Effectiveness 
  &lt;ul&gt; 
   &lt;li&gt;ESEC/FSE 2015&lt;/li&gt; 
   &lt;li&gt;Yucheng Zhang, Ali Mesbah&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://salt.ece.ubc.ca/publications/fse15.html&quot;&gt;http://salt.ece.ubc.ca/publications/fse15.html&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Assurances in Software Testing: A Roadmap 
  &lt;ul&gt; 
   &lt;li&gt;ICSE-NIER 2019: International Conference on Software Engineering: New Ideas and Emerging Results&lt;/li&gt; 
   &lt;li&gt;Marcel Böhme&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://arxiv.org/abs/1807.10255&quot;&gt;https://arxiv.org/abs/1807.10255&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;AUSTIN (AUgmented Search-based TestINg): An open source tool for search based software testing of C programs 
  &lt;ul&gt; 
   &lt;li&gt;Search Based Software Engineering (SSBSE) 2010; Information and Software Technology, 55(1), 2013&lt;/li&gt; 
   &lt;li&gt;Kiran Lakhotia, Mark Harman, Hamilton Gross&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://www0.cs.ucl.ac.uk/staff/K.Lakhotia/docs/ist12.pdf&quot;&gt;http://www0.cs.ucl.ac.uk/staff/K.Lakhotia/docs/ist12.pdf&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://www0.cs.ucl.ac.uk/staff/mharman/ist-kiran.pdf&quot;&gt;http://www0.cs.ucl.ac.uk/staff/mharman/ist-kiran.pdf&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://www0.cs.ucl.ac.uk/staff/Yuanyuan.Zhang/StuConOS/StuConOS-Kiran.pdf&quot;&gt;http://www0.cs.ucl.ac.uk/staff/Yuanyuan.Zhang/StuConOS/StuConOS-Kiran.pdf&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://code.google.com/archive/p/austin-sbst/&quot;&gt;https://code.google.com/archive/p/austin-sbst/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/kiranlak/austin-sbst&quot;&gt;https://github.com/kiranlak/austin-sbst&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Compiler Instrumentation for Testing 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/martong/finstrument_mock&quot;&gt;https://github.com/martong/finstrument_mock&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Unit Testing in C++ with Compiler Instrumentation and Friends 
    &lt;ul&gt; 
     &lt;li&gt;Acta Cybernetica 23 (2017)&lt;/li&gt; 
     &lt;li&gt;Gábor Márton and Zoltán Porkoláb&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;http://www.inf.u-szeged.hu/actacybernetica/edb/vol23n2/actacyb_23_2_2017_14.xml&quot;&gt;http://www.inf.u-szeged.hu/actacybernetica/edb/vol23n2/actacyb_23_2_2017_14.xml&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;http://www.inf.u-szeged.hu/actacybernetica/edb/vol23n2/pdf/actacyb_23_2_2017_14.pdf&quot;&gt;http://www.inf.u-szeged.hu/actacybernetica/edb/vol23n2/pdf/actacyb_23_2_2017_14.pdf&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;Compile-Time Function Call Interception for Testing in C/C++ 
    &lt;ul&gt; 
     &lt;li&gt;Studia Universitatis Babeș-Bolyai Informatica, v. 63, n. 1, 2018&lt;/li&gt; 
     &lt;li&gt;Gábor Márton, Zoltán Porkoláb&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;http://www.cs.ubbcluj.ro/~studia-i/journal/journal/article/view/19&quot;&gt;http://www.cs.ubbcluj.ro/~studia-i/journal/journal/article/view/19&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://www.researchgate.net/publication/325900400_Compile-Time_Function_Call_Interception_for_Testing_in_CC&quot;&gt;https://www.researchgate.net/publication/325900400_Compile-Time_Function_Call_Interception_for_Testing_in_CC&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Does Refactoring of Test Smells Induce Fixing Flaky Tests? 
  &lt;ul&gt; 
   &lt;li&gt;International Conference on Software Maintenance and Evolution (ICSME) 2017&lt;/li&gt; 
   &lt;li&gt;Fabio Palomba and Andy Zaidman&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://azaidman.github.io/publications/palombaICSME2017.pdf&quot;&gt;https://azaidman.github.io/publications/palombaICSME2017.pdf&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.slideshare.net/fabiopalomba/does-refactoring-of-test-smells-induce-fixing-flaky-tests&quot;&gt;https://www.slideshare.net/fabiopalomba/does-refactoring-of-test-smells-induce-fixing-flaky-tests&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Regression Testing Minimisation, Selection and Prioritisation: A Survey 
  &lt;ul&gt; 
   &lt;li&gt;Software Testing, Verification and Reliability 22, 2 (2012)&lt;/li&gt; 
   &lt;li&gt;Shin Yoo and Mark Harman&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://www0.cs.ucl.ac.uk/staff/M.Harman/stvr-shin-survey.pdf&quot;&gt;http://www0.cs.ucl.ac.uk/staff/M.Harman/stvr-shin-survey.pdf&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;STADS: Software Testing as Species Discovery 
  &lt;ul&gt; 
   &lt;li&gt;ACM Trans. Softw. Eng. Methodol. 27(2) 2018&lt;/li&gt; 
   &lt;li&gt;Marcel Böhme&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://dl.acm.org/citation.cfm?doid=3210309&quot;&gt;https://dl.acm.org/citation.cfm?doid=3210309&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://arxiv.org/abs/1803.02130&quot;&gt;https://arxiv.org/abs/1803.02130&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Testing C++ generic libraries 
  &lt;ul&gt; 
   &lt;li&gt;International Conference on Software Maintenance (ICSM) 2012&lt;/li&gt; 
   &lt;li&gt;Andrew Sutton, Marcin Zalewski&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://ieeexplore.ieee.org/document/6405251&quot;&gt;https://ieeexplore.ieee.org/document/6405251&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.ii.uib.no/~magne/inf328s17-info/inf328-2017s-bldl-presentation-08-SuttonZalewski2012icsm-06405251.pdf&quot;&gt;https://www.ii.uib.no/~magne/inf328s17-info/inf328-2017s-bldl-presentation-08-SuttonZalewski2012icsm-06405251.pdf&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;The Art of Testing Less Without Sacrificing Quality 
  &lt;ul&gt; 
   &lt;li&gt;ICSE 2015&lt;/li&gt; 
   &lt;li&gt;Kim Herzig, Michaela Greiler, Jacek Czerwonka, Brendan Murphy&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.microsoft.com/en-us/research/publication/the-art-of-testing-less-without-sacrificing-quality/&quot;&gt;https://www.microsoft.com/en-us/research/publication/the-art-of-testing-less-without-sacrificing-quality/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://blog.acolyer.org/2015/06/25/the-art-of-testing-less-without-sacrificing-quality/&quot;&gt;https://blog.acolyer.org/2015/06/25/the-art-of-testing-less-without-sacrificing-quality/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;The Oracle Problem in Software Testing: A Survey 
  &lt;ul&gt; 
   &lt;li&gt;IEEE Transactions on Software Engineering 41(5) 2015&lt;/li&gt; 
   &lt;li&gt;Earl Barr, Mark Harman, Phil McMinn, Muzammil Shahbaz, Shin Yoo&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://ieeexplore.ieee.org/document/6963470&quot;&gt;https://ieeexplore.ieee.org/document/6963470&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://earlbarr.com/publications/testoracles.pdf&quot;&gt;http://earlbarr.com/publications/testoracles.pdf&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Repository of Publications on the Test Oracle Problem 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;http://crestweb.cs.ucl.ac.uk/resources/oracle_repository/&quot;&gt;http://crestweb.cs.ucl.ac.uk/resources/oracle_repository/&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Tools and Language Elements for Testing, Encapsulation and Controlling Abstraction in Large Scale C++ Projects 
  &lt;ul&gt; 
   &lt;li&gt;2019 Doctoral dissertation; Gábor Márton&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://www.tnkcs.inf.elte.hu/vedes/Marton_Gabor_Ertekezes1.pdf&quot;&gt;http://www.tnkcs.inf.elte.hu/vedes/Marton_Gabor_Ertekezes1.pdf&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.researchgate.net/publication/337717375_Tools_and_Language_Elements_for_Testing_Encapsulation_and_Controlling_Abstraction_in_Large_Scale_C_Projects&quot;&gt;https://www.researchgate.net/publication/337717375_Tools_and_Language_Elements_for_Testing_Encapsulation_and_Controlling_Abstraction_in_Large_Scale_C_Projects&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;When Testing Meets Code Review: Why and How Developers Review Tests 
  &lt;ul&gt; 
   &lt;li&gt;ICSE 2018&lt;/li&gt; 
   &lt;li&gt;Davide Spadini, Mauricio Aniche, Margaret-Anne Storey, Magiel Bruntink, Alberto Bacchelli&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://pure.tudelft.nl/portal/en/publications/when-testing-meets-code-review-why-and-how-developers-review-tests(256e7d56-352f-44ae-919b-97fad0eafe69).html&quot;&gt;https://pure.tudelft.nl/portal/en/publications/when-testing-meets-code-review-why-and-how-developers-review-tests(256e7d56-352f-44ae-919b-97fad0eafe69).html&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://pure.tudelft.nl/portal/files/38853938/PID5219697.pdf&quot;&gt;https://pure.tudelft.nl/portal/files/38853938/PID5219697.pdf&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Research: 2000s&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;Software Testing and Industry Needs 
  &lt;ul&gt; 
   &lt;li&gt;IEEE Software, vol. 23, no. 4, July-Aug. 2006&lt;/li&gt; 
   &lt;li&gt;R. L. Glass, R. Collard, A. Bertolino, J. Bach, C. Kaner&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://ieeexplore.ieee.org/stamp/stamp.jsp?arnumber=1657939&quot;&gt;https://ieeexplore.ieee.org/stamp/stamp.jsp?arnumber=1657939&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://ieeexplore.ieee.org/document/1657939/&quot;&gt;https://ieeexplore.ieee.org/document/1657939/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Software Testing Research: Achievements, Challenges, Dreams 
  &lt;ul&gt; 
   &lt;li&gt;Future of Software Engineering 2007; Antonia Bertolino&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://selab.netlab.uky.edu/homepage/sw-test-roadmap-bertolino.pdf&quot;&gt;http://selab.netlab.uky.edu/homepage/sw-test-roadmap-bertolino.pdf&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Research: 1990s&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;Bringing Testing Into the Fold 
  &lt;ul&gt; 
   &lt;li&gt;IEEE Software 13(3): 91-92 (1996)&lt;/li&gt; 
   &lt;li&gt;Edward V. Berard&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://doi.org/10.1109/52.493025&quot;&gt;https://doi.org/10.1109/52.493025&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;PIE: A Dynamic Failure-Based Technique 
  &lt;ul&gt; 
   &lt;li&gt;Jeffrey M. Voas&lt;/li&gt; 
   &lt;li&gt;IEEE Transactions on Software Engineering, Volume 18 Issue 8, 1992&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://dl.acm.org/citation.cfm?id=136558&quot;&gt;https://dl.acm.org/citation.cfm?id=136558&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://www.cs.odu.edu/~mln/ltrs-pdfs/NASA-92-ieeeswe.jmv.pdf&quot;&gt;http://www.cs.odu.edu/~mln/ltrs-pdfs/NASA-92-ieeeswe.jmv.pdf&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;PIE: propagation, infection, and execution&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Research: 1980s&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;On Testing Non-Testable Programs 
  &lt;ul&gt; 
   &lt;li&gt;The Computer Journal, vol. 25, no. 4, 1982&lt;/li&gt; 
   &lt;li&gt;E. J. Weyuker&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://academic.oup.com/comjnl/article/25/4/465/366384&quot;&gt;https://academic.oup.com/comjnl/article/25/4/465/366384&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;hr&gt; 
&lt;h1&gt;Concurrency&lt;/h1&gt; 
&lt;ul&gt; 
 &lt;li&gt;A Survey of Recent Trends in Testing Concurrent Software Systems 
  &lt;ul&gt; 
   &lt;li&gt;IEEE Transactions on Software Engineering (TSE), vol. 44, no. 8, 2018&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.computer.org/csdl/trans/ts/2018/08/07932530-abs.html&quot;&gt;https://www.computer.org/csdl/trans/ts/2018/08/07932530-abs.html&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://home.deib.polimi.it/margara/papers/2017_tse_testing_concurrent_software.pdf&quot;&gt;https://home.deib.polimi.it/margara/papers/2017_tse_testing_concurrent_software.pdf&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Applications of Synchronization Coverage 
  &lt;ul&gt; 
   &lt;li&gt;Principles and Practice of Parallel Programming (PPoPP) 2005&lt;/li&gt; 
   &lt;li&gt;Arkady Bron, Eitan Farchi, Yonit Magid, Yarden Nir, Shmuel Ur&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://doi.org/10.1145/1065944.1065972&quot;&gt;https://doi.org/10.1145/1065944.1065972&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Are Concurrency Coverage Metrics Effective for Testing: A Comprehensive Empirical Investigation 
  &lt;ul&gt; 
   &lt;li&gt;Journal of Software Testing, Verification and Reliability (STVR) 25(4) 2015&lt;/li&gt; 
   &lt;li&gt;S. Hong, M. Staats, J. Ahn, M. Kim, G. Rothermel&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://onlinelibrary.wiley.com/doi/10.1002/stvr.1539/abstract&quot;&gt;http://onlinelibrary.wiley.com/doi/10.1002/stvr.1539/abstract&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://orbilu.uni.lu/bitstream/10993/16540/1/main-journal-concurrent-cov-effectiveness.pdf&quot;&gt;https://orbilu.uni.lu/bitstream/10993/16540/1/main-journal-concurrent-cov-effectiveness.pdf&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Cuzz – Concurrency Fuzzing 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.microsoft.com/en-us/research/project/cuzz-concurrency-fuzzing/&quot;&gt;https://www.microsoft.com/en-us/research/project/cuzz-concurrency-fuzzing/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;hr&gt; 
&lt;h1&gt;Continuous Integration&lt;/h1&gt; 
&lt;ul&gt; 
 &lt;li&gt;ci_helloworld: A simple example of how to setup a complete CI environment for C and C++ 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/ainfosec/ci_helloworld&quot;&gt;https://github.com/ainfosec/ci_helloworld&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;A Test a Day Keeps Your Manager Away! 
    &lt;ul&gt; 
     &lt;li&gt;CppCon 2017; Rian Quinn&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=KdJhQuycD78&quot;&gt;https://www.youtube.com/watch?v=KdJhQuycD78&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&quot;During this session we will step through an open source project designed to demonstrate how to integrate different C++ analysis tools into your CI services. These tools include static analysis (Clang Tidy, Coverity Scan, Codeacy and CppCheck), dynamic analysis (Valgrind and Google&apos;s Sanitizers), source formatting (Astyle and Clang Format), documentation (Doxygen), code coverage (Codecov, Coveralls, and LLVM&apos;s Software-based Code Coverage), cross platform tests (Windows, Cygwin, Linux, and macOS), compiler tests (GCC, Clang, and Visual Studio) and finally C++ libraries designed to assist in reliability and automated testing (Catch, Hippomocks and the Guideline Support Library). In addition we will openly discuss the advantages and disadvantages of using various analysis tools, how to integrate these tools into existing projects (both large and small) as well as common problems encountered while using these tools autonomously in a CI environment.&quot;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Code Coverage &amp;amp; Continuous Integration 
  &lt;ul&gt; 
   &lt;li&gt;2019 ATPESC Tutorial: Better Scientific Software&lt;/li&gt; 
   &lt;li&gt;Jared O&apos;Neal&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=8JZi7OvGGCc&quot;&gt;https://www.youtube.com/watch?v=8JZi7OvGGCc&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://doi.org/10.6084/m9.figshare.9272813&quot;&gt;https://doi.org/10.6084/m9.figshare.9272813&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Examples 
    &lt;ul&gt; 
     &lt;li&gt;Travis CI Hello World: Simplest CI example 
      &lt;ul&gt; 
       &lt;li&gt;&lt;a href=&quot;https://github.com/jrdoneal/CI_HelloWorld&quot;&gt;https://github.com/jrdoneal/CI_HelloWorld&lt;/a&gt;&lt;/li&gt; 
       &lt;li&gt;&lt;a href=&quot;https://travis-ci.org/jrdoneal/CI_HelloWorld&quot;&gt;https://travis-ci.org/jrdoneal/CI_HelloWorld&lt;/a&gt;&lt;/li&gt; 
      &lt;/ul&gt; &lt;/li&gt; 
     &lt;li&gt;CI_Multiplatform: Multiplatform/Multicompiler Travis CI Example 
      &lt;ul&gt; 
       &lt;li&gt;CI example w/ multiple platforms and specific compiler versions&lt;/li&gt; 
       &lt;li&gt;&lt;a href=&quot;https://github.com/jrdoneal/CI_Multiplatform&quot;&gt;https://github.com/jrdoneal/CI_Multiplatform&lt;/a&gt;&lt;/li&gt; 
      &lt;/ul&gt; &lt;/li&gt; 
     &lt;li&gt;Code coverage, testing, and CI example (Fortran, C++) 
      &lt;ul&gt; 
       &lt;li&gt;&lt;a href=&quot;https://github.com/jrdoneal/infrastructure&quot;&gt;https://github.com/jrdoneal/infrastructure&lt;/a&gt;&lt;/li&gt; 
      &lt;/ul&gt; &lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Continuous Integration: Readings&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;Automated Reporting of Anti-Patterns and Decay in Continuous Integration 
  &lt;ul&gt; 
   &lt;li&gt;ICSE 2019&lt;/li&gt; 
   &lt;li&gt;Carmine Vassallo, Sebastian Proksch, Harald Gall, Massimiliano Di Penta&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://doi.org/10.5281/zenodo.2578271&quot;&gt;http://doi.org/10.5281/zenodo.2578271&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Continuous delivery: Patterns and antipatterns in the software life cycle 
  &lt;ul&gt; 
   &lt;li&gt;DZone refcard #145, 2011; P. M. Duvall&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://dzone.com/refcardz/continuous-delivery-patterns&quot;&gt;https://dzone.com/refcardz/continuous-delivery-patterns&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Continuous Integration: Improving Software Quality and Reducing Risk 
  &lt;ul&gt; 
   &lt;li&gt;2007; P. Duvall, S. M. Matyas, A. Glover&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://www.integratebutton.com/&quot;&gt;http://www.integratebutton.com/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Continuous Integration Theater 
  &lt;ul&gt; 
   &lt;li&gt;Empirical Software Engineering and Measurement (ESEM) 2019&lt;/li&gt; 
   &lt;li&gt;Wagner Felidré, Leonardo Furtado, Daniel da Costa, Bruno Cartaxo, Gustavo Pinto&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://arxiv.org/abs/1907.01602&quot;&gt;https://arxiv.org/abs/1907.01602&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://gustavopinto.org/blog/continuous-integration-theater/&quot;&gt;http://gustavopinto.org/blog/continuous-integration-theater/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Game Changers - Trunk Based Development 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://trunkbaseddevelopment.com/game-changers/&quot;&gt;https://trunkbaseddevelopment.com/game-changers/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;How to get code coverage from CI 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://codingnest.com/how-to-get-code-coverage-from-ci/&quot;&gt;https://codingnest.com/how-to-get-code-coverage-from-ci/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Modern C++ CI 
  &lt;ul&gt; 
   &lt;li&gt;CMake, Catch, spdlog, Travis, AppVeyor&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://juan-medina.com/2017/07/01/moderncppci/&quot;&gt;https://juan-medina.com/2017/07/01/moderncppci/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/LearningByExample/ModernCppCI&quot;&gt;https://github.com/LearningByExample/ModernCppCI&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Taming Google-Scale Continuous Testing 
  &lt;ul&gt; 
   &lt;li&gt;ICSE 2017&lt;/li&gt; 
   &lt;li&gt;Atif Memon, Bao Nguyen, Eric Nickell, John Micco, Sanjeev Dhanda, Rob Siemborski, Zebao Gao&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://research.google/pubs/pub45861/&quot;&gt;https://research.google/pubs/pub45861/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Continuous Integration: Software&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;Azure DevOps C++ build tasks for CMake and vcpkg 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/lukka/CppBuildTasks&quot;&gt;https://github.com/lukka/CppBuildTasks&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;CMake Modern: C++, CMake and Travis-CI Hello World 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/nboutin/cmake_modern&quot;&gt;https://github.com/nboutin/cmake_modern&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Continuous Integration Demo 
  &lt;ul&gt; 
   &lt;li&gt;A demo project for C++14 using CI systems like Travis CI, Circle CI, Google Test, Catch, etc.&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/daixtrose/continuous-integration-demo&quot;&gt;https://github.com/daixtrose/continuous-integration-demo&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;GitLab CI for C++ projects 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://mklimenko.github.io/english/2020/02/02/gitlab-ci-cpp/&quot;&gt;https://mklimenko.github.io/english/2020/02/02/gitlab-ci-cpp/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Continuous Integration: Software: AppVeyor&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;Intro to AppVeyor - C++ Weekly - Ep 80 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=R8OrWVVf5CM&quot;&gt;https://www.youtube.com/watch?v=R8OrWVVf5CM&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Boost.Hana .appveyor.yml 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/boostorg/hana/blob/master/.appveyor.yml&quot;&gt;https://github.com/boostorg/hana/blob/master/.appveyor.yml&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Continuous Integration: Software: GitHub Actions&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;Using GitHub Actions with C++ and CMake 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://cristianadam.eu/20191222/using-github-actions-with-c-plus-plus-and-cmake/&quot;&gt;https://cristianadam.eu/20191222/using-github-actions-with-c-plus-plus-and-cmake/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Speeding up C++ GitHub Actions using ccache 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://cristianadam.eu/20200113/speeding-up-c-plus-plus-github-actions-using-ccache/&quot;&gt;https://cristianadam.eu/20200113/speeding-up-c-plus-plus-github-actions-using-ccache/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Continuous Integration: Software: Travis&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;.travis.yml Examples 
  &lt;ul&gt; 
   &lt;li&gt;Boost.Hana: clang++, g++, Boost, Valgrind - &lt;a href=&quot;https://github.com/boostorg/hana/blob/master/.travis.yml&quot;&gt;https://github.com/boostorg/hana/blob/master/.travis.yml&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Catch2: &lt;a href=&quot;https://github.com/catchorg/Catch2/blob/master/.travis.yml&quot;&gt;https://github.com/catchorg/Catch2/blob/master/.travis.yml&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;meta: &lt;a href=&quot;https://github.com/Leandros/meta/blob/master/.travis.yml&quot;&gt;https://github.com/Leandros/meta/blob/master/.travis.yml&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;MPark.Variant: &lt;a href=&quot;https://github.com/mpark/variant/blob/master/.travis.yml&quot;&gt;https://github.com/mpark/variant/blob/master/.travis.yml&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;xstd: clang++, g++, binutils, Boost, libc++, lcov, lld, lldb - &lt;a href=&quot;https://github.com/rhalbersma/xstd/blob/master/.travis.yml&quot;&gt;https://github.com/rhalbersma/xstd/blob/master/.travis.yml&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;C++ CI: Clang, Travis, CMake, GTest, Coveralls &amp;amp; Appveyor 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;http://david-grs.github.io/cpp-clang-travis-cmake-gtest-coveralls-appveyor/&quot;&gt;http://david-grs.github.io/cpp-clang-travis-cmake-gtest-coveralls-appveyor/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/david-grs/clang_travis_cmake_gtest_coveralls_example&quot;&gt;https://github.com/david-grs/clang_travis_cmake_gtest_coveralls_example&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Intro To Travis CI - C++ Weekly - Ep 79 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=3ulKzD2cmSw&quot;&gt;https://www.youtube.com/watch?v=3ulKzD2cmSw&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Continuous integration with Travis CI 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://arne-mertz.de/2017/04/continuous-integration-travis-ci/&quot;&gt;https://arne-mertz.de/2017/04/continuous-integration-travis-ci/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;icc-travis: Script to help install Intel C/C++ Compiler on Travis CI. 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/nemequ/icc-travis&quot;&gt;https://github.com/nemequ/icc-travis&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Minimal Travis CI example for modern C++ 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/mpoullet/travis-cpp&quot;&gt;https://github.com/mpoullet/travis-cpp&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Richel Bilderbeek 
  &lt;ul&gt; 
   &lt;li&gt;C++ Travis CI tutorial 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;http://richelbilderbeek.nl/CppTravisCiTutorial.htm&quot;&gt;http://richelbilderbeek.nl/CppTravisCiTutorial.htm&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://github.com/richelbilderbeek/travis_cpp_tutorial&quot;&gt;https://github.com/richelbilderbeek/travis_cpp_tutorial&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;Favorite C++ setup 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://github.com/richelbilderbeek/the_richel_setup&quot;&gt;https://github.com/richelbilderbeek/the_richel_setup&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;TravisTorrent: Synthesizing Travis CI and GitHub for Full-Stack Research on Continuous Integration 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://travistorrent.testroots.org/&quot;&gt;https://travistorrent.testroots.org/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;hr&gt; 
&lt;h1&gt;Coverage&lt;/h1&gt; 
&lt;h2&gt;Coverage: Readings&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;A Large-Scale, Longitudinal Study of Test Coverage Evolution 
  &lt;ul&gt; 
   &lt;li&gt;Automated Software Engineering (ASE) 2018&lt;/li&gt; 
   &lt;li&gt;Michael Hilton, Jonathan Bell, Darko Marinov&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://jonbell.net/publications/coverage&quot;&gt;http://jonbell.net/publications/coverage&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.code-coverage.org/publications/&quot;&gt;https://www.code-coverage.org/publications/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Code Coverage Analytics: Understanding how lines are (un)covered 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://www.code-coverage.org/&quot;&gt;https://www.code-coverage.org/&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Applications of Synchronization Coverage 
  &lt;ul&gt; 
   &lt;li&gt;Principles and Practice of Parallel Programming (PPoPP) 2005&lt;/li&gt; 
   &lt;li&gt;Arkady Bron, Eitan Farchi, Yonit Magid, Yarden Nir, Shmuel Ur&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://doi.org/10.1145/1065944.1065972&quot;&gt;https://doi.org/10.1145/1065944.1065972&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Assessing Oracle Quality with Checked Coverage 
  &lt;ul&gt; 
   &lt;li&gt;International Conference on Software Testing, Verification and Validation ICST 2011&lt;/li&gt; 
   &lt;li&gt;David Schuler and Andreas Zeller&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://dl.acm.org/citation.cfm?id=1990075&quot;&gt;https://dl.acm.org/citation.cfm?id=1990075&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Automatic Self-Validation for Code Coverage Profilers 
  &lt;ul&gt; 
   &lt;li&gt;ASE 2019&lt;/li&gt; 
   &lt;li&gt;Yibiao Yang, Yanyan Jiang, Zhiqiang Zuo, Yang Wang, Hao Sun, Hongmin Lu, Yuming Zhou, Baowen Xu&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://2019.ase-conferences.org/details/ase-2019-papers/2/Automatic-Self-Validation-for-Code-Coverage-Profilers&quot;&gt;https://2019.ase-conferences.org/details/ase-2019-papers/2/Automatic-Self-Validation-for-Code-Coverage-Profilers&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Can Testedness be Effectively Measured 
  &lt;ul&gt; 
   &lt;li&gt;FSE 2016&lt;/li&gt; 
   &lt;li&gt;Ahmed, Gopinath, Brindescu, Groce, Jensen&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://rahul.gopinath.org/resources/fse2016/ahmed2016can.pdf&quot;&gt;https://rahul.gopinath.org/resources/fse2016/ahmed2016can.pdf&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://speakerdeck.com/ahmedi/can-testedness-be-effectively-measured&quot;&gt;https://speakerdeck.com/ahmedi/can-testedness-be-effectively-measured&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://rahul.gopinath.org/publications/#ahmed2016can&quot;&gt;https://rahul.gopinath.org/publications/#ahmed2016can&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Code Coverage at Google 
  &lt;ul&gt; 
   &lt;li&gt;ESEC/FSE 2019&lt;/li&gt; 
   &lt;li&gt;Marko Ivanković, Goran Petrović, René Just, Gordon Fraser&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://homes.cs.washington.edu/~rjust/publ/google_coverage_fse_2019.pdf&quot;&gt;https://homes.cs.washington.edu/~rjust/publ/google_coverage_fse_2019.pdf&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://ai.google/research/pubs/pub48413/&quot;&gt;https://ai.google/research/pubs/pub48413/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Code Coverage for Suite Evaluation by Developers 
  &lt;ul&gt; 
   &lt;li&gt;ICSE 2014&lt;/li&gt; 
   &lt;li&gt;Rahul Gopinath, Carlos Jensen, Alex Groce&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://research.engr.oregonstate.edu/hci/sites/research.engr.oregonstate.edu.hci/files/papers/gopinath2014code_0.pdf&quot;&gt;http://research.engr.oregonstate.edu/hci/sites/research.engr.oregonstate.edu.hci/files/papers/gopinath2014code_0.pdf&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Code Coverage is a Strong Predictor of Test Suite Effectiveness 
  &lt;ul&gt; 
   &lt;li&gt;GTAC 2016&lt;/li&gt; 
   &lt;li&gt;Rahul Gopinath&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=NKEptA3KP08&quot;&gt;https://www.youtube.com/watch?v=NKEptA3KP08&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://speakerdeck.com/rahulgopinath/code-coverage-is-a-strong-predictor-of-test-suite-effectiveness-in-the-real-world&quot;&gt;https://speakerdeck.com/rahulgopinath/code-coverage-is-a-strong-predictor-of-test-suite-effectiveness-in-the-real-world&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://docs.google.com/presentation/d/1_bNn_HTI1Vst6WAB62KHTtgbvxocjpnt2Y-8ugGyP8U&quot;&gt;https://docs.google.com/presentation/d/1_bNn_HTI1Vst6WAB62KHTtgbvxocjpnt2Y-8ugGyP8U&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Comparing non-adequate test suites using coverage criteria 
  &lt;ul&gt; 
   &lt;li&gt;International Symposium on Software Testing and Analysis (2013)&lt;/li&gt; 
   &lt;li&gt;Gligoric, M., Groce, A., Zhang, C., Sharma, R., Alipour, A., Marinov, D.&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://agroce.github.io/issta13.pdf&quot;&gt;https://agroce.github.io/issta13.pdf&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Coverage and Its Discontents 
  &lt;ul&gt; 
   &lt;li&gt;Onward! Essays, SPLASH 2014&lt;/li&gt; 
   &lt;li&gt;Alex Groce, Mohammad Amin Alipour, Rahul Gopinath&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://agroce.github.io/onwardessays14.pdf&quot;&gt;https://agroce.github.io/onwardessays14.pdf&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Coverage is Not Strongly Correlated with Test Suite Effectiveness 
  &lt;ul&gt; 
   &lt;li&gt;International Conference on Software Engineering 2014&lt;/li&gt; 
   &lt;li&gt;Laura Inozemtseva and Reid Holmes&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://www.linozemtseva.com/research/2014/icse/coverage/&quot;&gt;http://www.linozemtseva.com/research/2014/icse/coverage/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;ICSE 2014: &lt;a href=&quot;https://vimeo.com/92273013&quot;&gt;https://vimeo.com/92273013&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;GTAC 2015: &lt;a href=&quot;https://www.youtube.com/watch?v=sAfROROGujU&quot;&gt;https://www.youtube.com/watch?v=sAfROROGujU&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Covrig: A Framework for the Analysis of Code, Test, and Coverage Evolution in Real Software 
  &lt;ul&gt; 
   &lt;li&gt;ISSTA 2014&lt;/li&gt; 
   &lt;li&gt;Paul Marinescu, Petr Hosek, Cristian Cadar&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://srg.doc.ic.ac.uk/publications/covrig-issta-14.html&quot;&gt;https://srg.doc.ic.ac.uk/publications/covrig-issta-14.html&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Guidelines for coverage-based comparisons of non-adequate test suites 
  &lt;ul&gt; 
   &lt;li&gt;ACM Transactions on Software Engineering and Methodology (2015)&lt;/li&gt; 
   &lt;li&gt;Gligoric, M., Groce, A., Zhang, C., Sharma, R., Alipour, A., Marinov, D.&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://dl.acm.org/citation.cfm?id=2660767&quot;&gt;https://dl.acm.org/citation.cfm?id=2660767&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://mir.cs.illinois.edu/coco/&quot;&gt;http://mir.cs.illinois.edu/coco/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://users.ece.utexas.edu/~gligoric/papers/GligoricETAL15CoCoJournal.pdf&quot;&gt;http://users.ece.utexas.edu/~gligoric/papers/GligoricETAL15CoCoJournal.pdf&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;How to Misuse Code Coverage 
  &lt;ul&gt; 
   &lt;li&gt;1999; Brian Marick&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://www.exampler.com/testing-com/writings/coverage.pdf&quot;&gt;http://www.exampler.com/testing-com/writings/coverage.pdf&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Hunting for Bugs in Code Coverage Tools via Randomized Differential Testing 
  &lt;ul&gt; 
   &lt;li&gt;ICSE 2019&lt;/li&gt; 
   &lt;li&gt;Yibiao Yang, Yuming Zhou, Hao Sun, Zhendong Su, Zhiqiang Zuo, Lei Xu, Baowen Xu&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://2019.icse-conferences.org/event/icse-2019-technical-papers-how-reliable-are-code-coverage-tools-&quot;&gt;https://2019.icse-conferences.org/event/icse-2019-technical-papers-how-reliable-are-code-coverage-tools-&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Invasive Software Testing: Mutating Target Programs to Diversify Test Exploration for High Test Coverage 
  &lt;ul&gt; 
   &lt;li&gt;IEEE International Conference on Software Testing, Verification and Validation (ICST) 2018&lt;/li&gt; 
   &lt;li&gt;Y. Kim, S. Hong, B. Ko, L. Phan, M. Kim&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://swtv.kaist.ac.kr/publications/icst18-deminer.pdf&quot;&gt;http://swtv.kaist.ac.kr/publications/icst18-deminer.pdf&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Mythical Unit Test Coverage 
  &lt;ul&gt; 
   &lt;li&gt;IEEE Software, Volume 35, Issue 3, May/June 2018&lt;/li&gt; 
   &lt;li&gt;V. Antinyan, J. Derehag, A. Sandberg, M. Staron&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://ieeexplore.ieee.org/document/8354427/&quot;&gt;https://ieeexplore.ieee.org/document/8354427/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.researchgate.net/publication/324959836_Mythical_Unit_Test_Coverage&quot;&gt;https://www.researchgate.net/publication/324959836_Mythical_Unit_Test_Coverage&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Not All Coverage Measurements Are Equal: Fuzzing by Coverage Accounting for Input Prioritization 
  &lt;ul&gt; 
   &lt;li&gt;Network and Distributed System Security Symposium (NDSS) 2020&lt;/li&gt; 
   &lt;li&gt;Yanhao Wang, Xiangkun Jia, Yuwei Liu, Tiffany Bao, Dinghao Wu, and Purui Su&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://ajax4sec.github.io/papers/ndss20-fall-paper422.pdf&quot;&gt;https://ajax4sec.github.io/papers/ndss20-fall-paper422.pdf&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Selecting Software Test Data Using Data Flow Information 
  &lt;ul&gt; 
   &lt;li&gt;IEEE Transactions on Software Engineering 11(4) 1985&lt;/li&gt; 
   &lt;li&gt;Sandra Rapps and Elaine J. Weyuker&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://ieeexplore.ieee.org/document/1702019/&quot;&gt;http://ieeexplore.ieee.org/document/1702019/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;TestCov: Robust Test-Suite Execution and Coverage Measurement 
  &lt;ul&gt; 
   &lt;li&gt;ASE 2019&lt;/li&gt; 
   &lt;li&gt;Dirk Beyer, Thomas Lemberger&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://2019.ase-conferences.org/details/ase-2019-Demonstrations/34/TestCov-Robust-Test-Suite-Execution-and-Coverage-Measurement&quot;&gt;https://2019.ase-conferences.org/details/ase-2019-Demonstrations/34/TestCov-Robust-Test-Suite-Execution-and-Coverage-Measurement&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Turning Programs against Each Other: High Coverage Fuzz-Testing using Binary-Code Mutation and Dynamic Slicing 
  &lt;ul&gt; 
   &lt;li&gt;ESEC/FSE 2015&lt;/li&gt; 
   &lt;li&gt;Ulf Kargén and Nahid Shahmehri&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.ida.liu.se/~ulfka17/papers/FSE2015.pdf&quot;&gt;https://www.ida.liu.se/~ulfka17/papers/FSE2015.pdf&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Verification, coverage and maximization: The big picture 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://blog.foretellix.com/2016/12/23/verification-coverage-and-maximization-the-big-picture/&quot;&gt;https://blog.foretellix.com/2016/12/23/verification-coverage-and-maximization-the-big-picture/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Coverage: Software&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;afl-cov - AFL Fuzzing Code Coverage 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/mrash/afl-cov&quot;&gt;https://github.com/mrash/afl-cov&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;cmake_catch_coverage 
  &lt;ul&gt; 
   &lt;li&gt;Integration of CMake, Catch and CMake CodeCoverage module for C++ code.&lt;/li&gt; 
   &lt;li&gt;(CMake CodeCoverage depends on: gcov, gcovr, genhtml, lcov.)&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/fkromer/catch_cmake_coverage&quot;&gt;https://github.com/fkromer/catch_cmake_coverage&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Code Coverage in Chromium 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://chromium.googlesource.com/chromium/src/+/master/docs/testing/code_coverage.md&quot;&gt;https://chromium.googlesource.com/chromium/src/+/master/docs/testing/code_coverage.md&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;CompareCoverage 
  &lt;ul&gt; 
   &lt;li&gt;CompareCoverage (CmpCov in short) is a simple instrumentation module for C/C++ programs and libraries, which extracts information about data comparisons taking place in the code at run time, and saves it to disk in the form of standard .sancov files. It is based on the SanitizerCoverage instrumentation available in the clang compiler, which itself is tightly related to AddressSanitizer. Specifically, the library implements the instrumentation callbacks defined by the Tracing data flow feature of SanitizerCoverage.&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/googleprojectzero/CompareCoverage&quot;&gt;https://github.com/googleprojectzero/CompareCoverage&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;CovNavi: Code coverage navigation and analysis 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/Cisco-Talos/covnavi&quot;&gt;https://github.com/Cisco-Talos/covnavi&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Fuzzing driven code auditing and vice versa: Coverage analysis for better fuzzing 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://talosintelligence.com/resources/61&quot;&gt;https://talosintelligence.com/resources/61&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;cpp-llvm-coverage: How to use LLVM coverage for for C++ 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/Longhanks/cpp-llvm-coverage&quot;&gt;https://github.com/Longhanks/cpp-llvm-coverage&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;drcov: a DynamoRIO client tool that collects code coverage information 
  &lt;ul&gt; 
   &lt;li&gt;Dr. Memory provides optional code coverage information to aid in fuzz testing (Fuzz Testing Mode) or in general testing.&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://dynamorio.org/docs/page_drcov.html&quot;&gt;http://dynamorio.org/docs/page_drcov.html&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://drmemory.org/docs/page_coverage.html&quot;&gt;http://drmemory.org/docs/page_coverage.html&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/DynamoRIO/dynamorio/tree/master/clients/drcov&quot;&gt;https://github.com/DynamoRIO/dynamorio/tree/master/clients/drcov&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;GNU gcov 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://gcc.gnu.org/onlinedocs/gcc/Gcov.html&quot;&gt;https://gcc.gnu.org/onlinedocs/gcc/Gcov.html&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Writing Better Function Tests with GCOV 
    &lt;ul&gt; 
     &lt;li&gt;Linaro Connect 2018; Masami Hiramatsu&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=U_qWLa9KnW8&quot;&gt;https://www.youtube.com/watch?v=U_qWLa9KnW8&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;Gcovr 
    &lt;ul&gt; 
     &lt;li&gt;Gcovr provides a utility for managing the use of the GNU gcov utility and generating summarized code coverage results.&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;http://gcovr.com/&quot;&gt;http://gcovr.com/&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://github.com/gcovr/gcovr&quot;&gt;https://github.com/gcovr/gcovr&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;GCovHTML - Generate reports on code coverage 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://gitlab.com/stone.code/gcovhtml&quot;&gt;https://gitlab.com/stone.code/gcovhtml&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;Dev Santa Claus Part 2: C++ code coverage metrics with gcov 
    &lt;ul&gt; 
     &lt;li&gt;setting up code coverage metrics for a C++ codebase built using Bamboo, CMake and GCC.&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://genbattle.bitbucket.io/blog/2018/01/19/Dev-Santa-Claus-Part-2/&quot;&gt;https://genbattle.bitbucket.io/blog/2018/01/19/Dev-Santa-Claus-Part-2/&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;Using Gcov and Lcov to generate beautiful C++ code coverage statistics 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://codeflu.blog/2014/12/26/using-gcov-and-lcov-to-generate-beautiful-c-code-coverage-statistics/&quot;&gt;https://codeflu.blog/2014/12/26/using-gcov-and-lcov-to-generate-beautiful-c-code-coverage-statistics/&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Kcov 
  &lt;ul&gt; 
   &lt;li&gt;Code coverage tool for compiled programs, Python and Bash which uses debugging information to collect and report data without special compilation options&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://simonkagstrom.github.io/kcov/&quot;&gt;http://simonkagstrom.github.io/kcov/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/simonkagstrom/kcov&quot;&gt;https://github.com/simonkagstrom/kcov&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;C++ Weekly - Ep 111 - kcov - &lt;a href=&quot;https://www.youtube.com/watch?v=NRCnS5alouI&quot;&gt;https://www.youtube.com/watch?v=NRCnS5alouI&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Kcov - gcov, lcov and bcov - &lt;a href=&quot;https://simonkagstrom.livejournal.com/50380.html&quot;&gt;https://simonkagstrom.livejournal.com/50380.html&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Kcov - a single-step code coverage tool 
    &lt;ul&gt; 
     &lt;li&gt;Simon Kågström; SwedenCpp::Stockholm::0x0F, September 20, 2018&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=1QMHbp5LUKg&quot;&gt;https://www.youtube.com/watch?v=1QMHbp5LUKg&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;OpenCppCoverage: an open source code coverage tool for C++ under Windows 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/OpenCppCoverage/OpenCppCoverage&quot;&gt;https://github.com/OpenCppCoverage/OpenCppCoverage&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;LLVM 
  &lt;ul&gt; 
   &lt;li&gt;Clang Source-based Code Coverage 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://clang.llvm.org/docs/SourceBasedCodeCoverage.html&quot;&gt;https://clang.llvm.org/docs/SourceBasedCodeCoverage.html&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;SanitizerCoverage 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://clang.llvm.org/docs/SanitizerCoverage.html&quot;&gt;https://clang.llvm.org/docs/SanitizerCoverage.html&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;A quick tour of LLVM’s Sanitizer coverage 
      &lt;ul&gt; 
       &lt;li&gt;&lt;a href=&quot;https://tech.labs.oliverwyman.com/blog/2017/10/04/a-quick-tour-of-llvms-sanitizer-coverage/&quot;&gt;https://tech.labs.oliverwyman.com/blog/2017/10/04/a-quick-tour-of-llvms-sanitizer-coverage/&lt;/a&gt;&lt;/li&gt; 
      &lt;/ul&gt; &lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;TestCov: Test execution, coverage measurement, and test-suite reduction 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://gitlab.com/sosy-lab/software/test-suite-validator&quot;&gt;https://gitlab.com/sosy-lab/software/test-suite-validator&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Coverage: Mutation&lt;/h2&gt; 
&lt;p&gt;Mutation Analysis, Mutation Coverage, Mutation Testing&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Mutation testing resources: how to make better code by introducing bugs 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/theofidry/mutation-testing&quot;&gt;https://github.com/theofidry/mutation-testing&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://mutation-testing.slack.com/&quot;&gt;https://mutation-testing.slack.com/&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Coverage: Mutation: Readings&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;Mutation Testing Repository 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://mutationtesting.uni.lu/&quot;&gt;https://mutationtesting.uni.lu/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Evaluating Test Effectiveness with Mutation Analysis 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.fuzzingbook.org/html/MutationAnalysis.html&quot;&gt;https://www.fuzzingbook.org/html/MutationAnalysis.html&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;A Systematic Literature Review of How Mutation Testing Supports Quality Assurance Processes 
  &lt;ul&gt; 
   &lt;li&gt;Software Testing, Verification and Reliability 2018&lt;/li&gt; 
   &lt;li&gt;Qianqian Zhu, Annibale Panichella, Andy Zaidman&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://pure.tudelft.nl/portal/en/publications/a-systematic-literature-review-of-how-mutation-testing-supports-quality-assurance-processes(8767f68d-cea1-40b1-8933-a34825212860).html&quot;&gt;https://pure.tudelft.nl/portal/en/publications/a-systematic-literature-review-of-how-mutation-testing-supports-quality-assurance-processes(8767f68d-cea1-40b1-8933-a34825212860).html&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;A Systematic Literature Review of Techniques and Metrics to Reduce the Cost of Mutation Testing 
  &lt;ul&gt; 
   &lt;li&gt;Journal of Systems and Software (2019)&lt;/li&gt; 
   &lt;li&gt;Pizzoleto, Alessandro Viola, Fabiano Cutigi Ferrari, Jeff Offutt, Leo Fernandes, Márcio Ribeiro&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://cs.gmu.edu/~offutt/rsrch/papers/SLR-CostReductionMutation.pdf&quot;&gt;https://cs.gmu.edu/~offutt/rsrch/papers/SLR-CostReductionMutation.pdf&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;An Analysis and Survey of the Development of Mutation Testing 
  &lt;ul&gt; 
   &lt;li&gt;IEEE Trans. Software Eng. 37 (5) (2011)&lt;/li&gt; 
   &lt;li&gt;Y. Jia, M. Harman&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://dx.doi.org/10.1109/TSE.2010.62&quot;&gt;http://dx.doi.org/10.1109/TSE.2010.62&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://crest.cs.ucl.ac.uk/fileadmin/crest/sebasepaper/JiaH10.pdf&quot;&gt;http://crest.cs.ucl.ac.uk/fileadmin/crest/sebasepaper/JiaH10.pdf&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;An Empirical Study on Mutation, Statement and Branch Coverage Fault Revelation that Avoids the Unreliable Clean Program Assumption 
  &lt;ul&gt; 
   &lt;li&gt;ICSE 2017&lt;/li&gt; 
   &lt;li&gt;Titcheu Chekam Thierry, Mike Papadakis, Yves Le Traon, Mark Harman&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://sites.google.com/site/mikepapadakis/ICSE17.pdf&quot;&gt;https://sites.google.com/site/mikepapadakis/ICSE17.pdf&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://sites.google.com/site/mikepapadakis/faults-mutants&quot;&gt;https://sites.google.com/site/mikepapadakis/faults-mutants&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://sites.google.com/site/mikepapadakis/metallaxis&quot;&gt;https://sites.google.com/site/mikepapadakis/metallaxis&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;An Industrial Application of Mutation Testing: Lessons, Challenges, and Research Directions 
  &lt;ul&gt; 
   &lt;li&gt;International Workshop on Mutation Analysis (Mutation 2018)&lt;/li&gt; 
   &lt;li&gt;Goran Petrovic, Marko Ivankovic, Robert Kurtz, Paul Ammann, René Just&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://research.google/pubs/pub46907/&quot;&gt;https://research.google/pubs/pub46907/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Are Mutants a Valid Substitute for Real Faults in Software Testing? 
  &lt;ul&gt; 
   &lt;li&gt;Proceedings of the Symposium on the Foundations of Software Engineering 2014&lt;/li&gt; 
   &lt;li&gt;René Just, Darioush Jalali, Laura Inozemtseva, Michael D. Ernst, Reid Holmes, Gordon Fraser&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://www.linozemtseva.com/research/2014/fse/mutant_validity&quot;&gt;http://www.linozemtseva.com/research/2014/fse/mutant_validity&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;C++11/14 Mutation Operators Based on Common Fault Patterns 
  &lt;ul&gt; 
   &lt;li&gt;International Conference on Testing Software and Systems (ICTSS) 2018&lt;/li&gt; 
   &lt;li&gt;Parsai A., Demeyer S., De Busser S.&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://link.springer.com/chapter/10.1007%2F978-3-319-99927-2_9&quot;&gt;https://link.springer.com/chapter/10.1007%2F978-3-319-99927-2_9&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.parsai.net/files/research/C++11-14%20Mutation%20Operators%20Based%20on%20Common%20Fault%20Patterns%20(pre-print).pdf&quot;&gt;https://www.parsai.net/files/research/C++11-14%20Mutation%20Operators%20Based%20on%20Common%20Fault%20Patterns%20(pre-print).pdf&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Detecting Trivial Mutant Equivalences via Compiler Optimisations 
  &lt;ul&gt; 
   &lt;li&gt;IEEE Transactions on Software Engineering 44(4) 2018&lt;/li&gt; 
   &lt;li&gt;Marinos Kintis, Mike Papadakis, Yue Jia, Nicos Malevris, Yves Le Traon, Mark Harman&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://pages.cs.aueb.gr/~kintism/papers/tce/&quot;&gt;http://pages.cs.aueb.gr/~kintism/papers/tce/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://sites.google.com/site/mikepapadakis/tce-tse.pdf?attredirects=0&amp;amp;d=1&quot;&gt;https://sites.google.com/site/mikepapadakis/tce-tse.pdf?attredirects=0&amp;amp;d=1&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;How Verified (or Tested) is My Code? Falsification-Driven Verification and Testing 
  &lt;ul&gt; 
   &lt;li&gt;Automated Software Engineering (2018)&lt;/li&gt; 
   &lt;li&gt;Groce, Alex &amp;amp; Ahmed, Iftekhar &amp;amp; Jensen, Carlos &amp;amp; Mckenney, Paul &amp;amp; Holmes, Josie&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://agroce.github.io/asej18.pdf&quot;&gt;https://agroce.github.io/asej18.pdf&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;If You Can’t Kill a Supermutant, You Have a Problem 
  &lt;ul&gt; 
   &lt;li&gt;ICSTW Mutation 2018&lt;/li&gt; 
   &lt;li&gt;Rahul Gopinath, Björn Mathis, Andreas Zeller&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://rahul.gopinath.org/publications/#gopinath2018if&quot;&gt;https://rahul.gopinath.org/publications/#gopinath2018if&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://rahul.gopinath.org/resources/icstw2018/gopinath2018if.pdf&quot;&gt;https://rahul.gopinath.org/resources/icstw2018/gopinath2018if.pdf&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Is Mutation an Appropriate Tool for Testing Experiments? 
  &lt;ul&gt; 
   &lt;li&gt;ICSE 2005&lt;/li&gt; 
   &lt;li&gt;J. H. Andrews, L. C. Briand, Y. Labiche&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://dl.acm.org/citation.cfm?doid=1062455.1062530&quot;&gt;https://dl.acm.org/citation.cfm?doid=1062455.1062530&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.researchgate.net/publication/221554380_Is_Mutation_an_Appropriate_Tool_for_Testing_Experiments&quot;&gt;https://www.researchgate.net/publication/221554380_Is_Mutation_an_Appropriate_Tool_for_Testing_Experiments&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Mutant Quality Indicators 
  &lt;ul&gt; 
   &lt;li&gt;International Workshop on Mutation Analysis (MUTATION) 2018&lt;/li&gt; 
   &lt;li&gt;Mike Papadakis, Titcheu Chekam Thierry, Yves Le Traon&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://orbilu.uni.lu/bitstream/10993/34352/1/bare_conf1.pdf&quot;&gt;http://orbilu.uni.lu/bitstream/10993/34352/1/bare_conf1.pdf&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Mutation Testing Advances: An Analysis and Survey 
  &lt;ul&gt; 
   &lt;li&gt;Advances in Computers, Volume 112, 2018&lt;/li&gt; 
   &lt;li&gt;Mike Papadakis, Marinos Kintis, Jie Zhang, Yue Jia, Yves Le Traon, Mark Harman&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://sites.google.com/site/mikepapadakis/survey.pdf?attredirects=0&amp;amp;d=1&quot;&gt;https://sites.google.com/site/mikepapadakis/survey.pdf?attredirects=0&amp;amp;d=1&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://mutationtesting.uni.lu/survey.pdf&quot;&gt;https://mutationtesting.uni.lu/survey.pdf&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Mutation Testing: From Theory to Practice 
  &lt;ul&gt; 
   &lt;li&gt;2019 PhD Dissertation; Ali Parsai&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://repository.uantwerpen.be/docman/irua/479e80/161581.pdf&quot;&gt;https://repository.uantwerpen.be/docman/irua/479e80/161581.pdf&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.parsai.net/files/research/PhDThesisAliParsai2019.pdf&quot;&gt;https://www.parsai.net/files/research/PhDThesisAliParsai2019.pdf&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;On the Limits of Mutation Analysis 
  &lt;ul&gt; 
   &lt;li&gt;2017 PhD Dissertation; Rahul Gopinath&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://rahul.gopinath.org/resources/phd2017/gopinath2017on.pdf&quot;&gt;https://rahul.gopinath.org/resources/phd2017/gopinath2017on.pdf&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;State of Mutation Testing at Google 
  &lt;ul&gt; 
   &lt;li&gt;International Conference on Software Engineering: Software Engineering in Practice (ICSE-SEIP) 2018&lt;/li&gt; 
   &lt;li&gt;Goran Petrović and Marko Ivanković&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://ai.google/research/pubs/pub46584&quot;&gt;https://ai.google/research/pubs/pub46584&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://dl.acm.org/citation.cfm?id=3183521&quot;&gt;https://dl.acm.org/citation.cfm?id=3183521&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;The Care and Feeding of Wild-Caught Mutants 
  &lt;ul&gt; 
   &lt;li&gt;Foundations of Software Engineering (FSE) 2017&lt;/li&gt; 
   &lt;li&gt;David Bingham Brown, Michael Vaughn, Ben Liblit, Thomas W. Reps&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://research.cs.wisc.edu/wpis/abstracts/fse17.abs.html&quot;&gt;http://research.cs.wisc.edu/wpis/abstracts/fse17.abs.html&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Coverage: Mutation: Software&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;MART Framework for Multi-Programming Language Mutation Testing based on LLVM 
  &lt;ul&gt; 
   &lt;li&gt;LLVM Mutation Artisan (MART) -- a configurable mutation testing framework based on LLVM&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/thierry-tct/mart&quot;&gt;https://github.com/thierry-tct/mart&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Mart: A Mutant Generation Tool for LLVM 
    &lt;ul&gt; 
     &lt;li&gt;ACM Joint Meeting on European Software Engineering Conference and Symposium on the Foundations of Software Engineering (ESEC/FSE) 2019&lt;/li&gt; 
     &lt;li&gt;Thierry Titcheu Chekam, Mike Papadakis, Yves Le Traon&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://orbilu.uni.lu/retrieve/63878/72722/main.pdf&quot;&gt;https://orbilu.uni.lu/retrieve/63878/72722/main.pdf&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Mull: Mutation testing system built on top of LLVM 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/mull-project/mull&quot;&gt;https://github.com/mull-project/mull&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://lowlevelbits.org/llvm-based-mutation-testing-system.-request-for-comments/&quot;&gt;https://lowlevelbits.org/llvm-based-mutation-testing-system.-request-for-comments/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Mutation Testing Leaving the Stone Age - Alex Denisov, FOSDEM 2017 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=pVMupHK1BVY&quot;&gt;https://www.youtube.com/watch?v=pVMupHK1BVY&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;Mull it over: mutation testing based on LLVM 
    &lt;ul&gt; 
     &lt;li&gt;Mutation 2018; Alex Denisov, Stanislav Pankevich&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://lowlevelbits.org/pdfs/Mull_Mutation_2018.pdf&quot;&gt;https://lowlevelbits.org/pdfs/Mull_Mutation_2018.pdf&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Mutate++ - A C++ Mutation Test Environment 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/nlohmann/mutate_cpp&quot;&gt;https://github.com/nlohmann/mutate_cpp&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;SRCIROR: SRC and IR mutatOR 
  &lt;ul&gt; 
   &lt;li&gt;performs mutations on source code written in C/C++ and on the LLVM IR&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/TestingResearchIllinois/srciror&quot;&gt;https://github.com/TestingResearchIllinois/srciror&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;SRCIROR: A Toolset for Mutation Testing of C Source Code and LLVM Intermediate Representation 
    &lt;ul&gt; 
     &lt;li&gt;Automated Software Engineering (ASE) 2018; Farah Hariri and August Shi&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;http://mir.cs.illinois.edu/farah/publications/ase18_srciror.pdf&quot;&gt;http://mir.cs.illinois.edu/farah/publications/ase18_srciror.pdf&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Coverage: Mutation: Talks&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;Testing The Tests: Mutation Testing for C++ 
  &lt;ul&gt; 
   &lt;li&gt;NDC TechTown 2019; Seph De Busser&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=M-5_M8qZXaE&quot;&gt;https://www.youtube.com/watch?v=M-5_M8qZXaE&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;hr&gt; 
&lt;h1&gt;Generation&lt;/h1&gt; 
&lt;ul&gt; 
 &lt;li&gt;An Orchestrated Survey on Automated Software Test Case Generation 
  &lt;ul&gt; 
   &lt;li&gt;Journal of Systems and Software 86 (2013)&lt;/li&gt; 
   &lt;li&gt;Saswat Anand, Edmund K. Burke, Tsong Yueh Chen, John Clark, Myra B. Cohen, Wolfgang Grieskamp, Mark Harman, Mary Jean Harrold, Phil Mcminn&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://dl.acm.org/citation.cfm?id=2503991&quot;&gt;https://dl.acm.org/citation.cfm?id=2503991&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.678.1106&quot;&gt;http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.678.1106&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://romisatriawahono.net/lecture/rm/survey/software%20engineering/Software%20Testing/Anand%20-%20Automated%20Software%20Test%20Case%20generation%20-%202013.pdf&quot;&gt;http://romisatriawahono.net/lecture/rm/survey/software%20engineering/Software%20Testing/Anand%20-%20Automated%20Software%20Test%20Case%20generation%20-%202013.pdf&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Automated Software Test Generation: Some Challenges, Solutions, and Recent Advances 
  &lt;ul&gt; 
   &lt;li&gt;Special issue Nr. 10,000 of Lecture Notes in Computer Science, Springer, 2018&lt;/li&gt; 
   &lt;li&gt;George Candea and Patrice Godefroid&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://dslab.epfl.ch/pubs/automated-test-generation.pdf&quot;&gt;http://dslab.epfl.ch/pubs/automated-test-generation.pdf&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://patricegodefroid.github.io/public_psfiles/lncs10000-2018.pdf&quot;&gt;https://patricegodefroid.github.io/public_psfiles/lncs10000-2018.pdf&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;FSX: fine-grained incremental unit test generation for C/C++ programs 
  &lt;ul&gt; 
   &lt;li&gt;ISSTA 2016&lt;/li&gt; 
   &lt;li&gt;Hiroaki Yoshida, Susumu Tokumoto, Mukul R. Prasad, Indradeep Ghosh, Tadahiro Uehara&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://dl.acm.org/citation.cfm?id=2931055&quot;&gt;https://dl.acm.org/citation.cfm?id=2931055&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;KLEE: Unassisted and Automatic Generation of High-Coverage Tests for Complex Systems Programs 
  &lt;ul&gt; 
   &lt;li&gt;OSDI 2008&lt;/li&gt; 
   &lt;li&gt;C. Cadar, D. Dunbar, D. Engler&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://www.doc.ic.ac.uk/~cristic/papers/klee-osdi-08.pdf&quot;&gt;http://www.doc.ic.ac.uk/~cristic/papers/klee-osdi-08.pdf&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://klee.github.io/publications/&quot;&gt;https://klee.github.io/publications/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;KLOVER (KLee based cOVERage tool, for C/C++) 
  &lt;ul&gt; 
   &lt;li&gt;KLOVER: Automatic Test Generation for C and C++ Programs, Using Symbolic Execution 
    &lt;ul&gt; 
     &lt;li&gt;IEEE Software Volume 34, Issue 5, 2017&lt;/li&gt; 
     &lt;li&gt;H. Yoshida, G. Li, T. Kamiya, I. Ghosh, S. Rajan, S. Tokumoto, K. Munakata, T. Uehara&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;http://ieeexplore.ieee.org/document/8048666/&quot;&gt;http://ieeexplore.ieee.org/document/8048666/&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;KLOVER: A Symbolic Execution and Automatic Test Generation Tool for C++ Programs 
    &lt;ul&gt; 
     &lt;li&gt;CAV 2011&lt;/li&gt; 
     &lt;li&gt;Guodong Li, Indradeep Ghosh, and Sreeranga P. Rajan&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://link.springer.com/chapter/10.1007/978-3-642-22110-1_49&quot;&gt;https://link.springer.com/chapter/10.1007/978-3-642-22110-1_49&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.205.5180&quot;&gt;http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.205.5180&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;http://www.cs.utah.edu/~ligd/publications/KLOVER-CAV11.pdf&quot;&gt;http://www.cs.utah.edu/~ligd/publications/KLOVER-CAV11.pdf&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Symbolic Execution Algorithms for Test Generation 
  &lt;ul&gt; 
   &lt;li&gt;2009 Dissertation; Ru-Gang Xu&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://people.mpi-sws.org/~rupak/Papers/RuGangXuThesis.pdf&quot;&gt;https://people.mpi-sws.org/~rupak/Papers/RuGangXuThesis.pdf&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Symbolic Execution for Software Testing: Three Decades Later 
  &lt;ul&gt; 
   &lt;li&gt;CACM 2013&lt;/li&gt; 
   &lt;li&gt;C. Cadar and K. Sen&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://people.eecs.berkeley.edu/~ksen/papers/cacm13.pdf&quot;&gt;https://people.eecs.berkeley.edu/~ksen/papers/cacm13.pdf&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Test-Comp: International Competition on Software Testing 
  &lt;ul&gt; 
   &lt;li&gt;a comparative evaluation of automatic tools for software test generation&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://test-comp.sosy-lab.org/&quot;&gt;https://test-comp.sosy-lab.org/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Test Generation Using Symbolic Execution 
  &lt;ul&gt; 
   &lt;li&gt;Foundations of Software Technology and Theoretical Computer Science (FSTTCS) 2012&lt;/li&gt; 
   &lt;li&gt;Patrice Godefroid&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://drops.dagstuhl.de/opus/volltexte/2012/3845/&quot;&gt;http://drops.dagstuhl.de/opus/volltexte/2012/3845/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Generation: Random&lt;/h2&gt; 
&lt;p&gt;Random Testing&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;A Survey on Adaptive Random Testing 
  &lt;ul&gt; 
   &lt;li&gt;IEEE Transactions on Software Engineering (TSE) 14(8) 2015&lt;/li&gt; 
   &lt;li&gt;Rubing Huang, Weifeng Sun, Yinyin Xu, Haibo Chen, Dave Towey, Xin Xia&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://xin-xia.github.io/publication/tse198.pdf&quot;&gt;https://xin-xia.github.io/publication/tse198.pdf&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Adaptive Random Testing 
  &lt;ul&gt; 
   &lt;li&gt;Asian Computing Science Conference (ASIAN) 2004&lt;/li&gt; 
   &lt;li&gt;T.Y. Chen, H. Leung, I.K. Mak&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.397.2054&amp;amp;rep=rep1&amp;amp;type=pdf&quot;&gt;http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.397.2054&amp;amp;rep=rep1&amp;amp;type=pdf&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Adaptive Random Testing: the ART of Test Case Diversity 
  &lt;ul&gt; 
   &lt;li&gt;Journal of Systems and Software 83 (1) 2010&lt;/li&gt; 
   &lt;li&gt;Chen, T.Y., Kuo, F.-C., Merkel, R.G., Tse, T.H.&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://i.cs.hku.hk/~tse/Papers/2010s/rbartJSS.html&quot;&gt;http://i.cs.hku.hk/~tse/Papers/2010s/rbartJSS.html&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;John Regehr 
  &lt;ul&gt; 
   &lt;li&gt;The Central Limit Theorem Makes Random Testing Hard 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://blog.regehr.org/archives/660&quot;&gt;https://blog.regehr.org/archives/660&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;Randomly Testing a Static Analyzer 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://blog.regehr.org/archives/680&quot;&gt;https://blog.regehr.org/archives/680&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;Burning in a Module with Random Unit Testing 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://blog.regehr.org/archives/737&quot;&gt;https://blog.regehr.org/archives/737&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;Oracles for Random Testing 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://blog.regehr.org/archives/856&quot;&gt;https://blog.regehr.org/archives/856&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Random Test Run Length and Effectiveness 
  &lt;ul&gt; 
   &lt;li&gt;Automated Software Engineering (ASE) 2008&lt;/li&gt; 
   &lt;li&gt;J. H. Andrews, A. Groce, M. Weston, and Ru-Gang Xu&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://agroce.github.io/ase08.pdf&quot;&gt;https://agroce.github.io/ase08.pdf&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;The Confidence Sequence Method: a computer-age test for statistical SLOs 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://pvk.ca/Blog/2018/07/06/testing-slo-type-properties-with-the-confidence-sequence-method/&quot;&gt;https://pvk.ca/Blog/2018/07/06/testing-slo-type-properties-with-the-confidence-sequence-method/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Lazy Linear Knapsack 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://pvk.ca/Blog/2020/01/20/lazy-linear-knapsack/&quot;&gt;https://pvk.ca/Blog/2020/01/20/lazy-linear-knapsack/&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&quot;TL;DR: the estimation algorithm for individual sampling passes works, and the combination of Hypothesis and Confidence Sequence Method lets us painlessly test for a statistical property.&quot;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;hr&gt; 
&lt;h1&gt;Property-Based Testing&lt;/h1&gt; 
&lt;ul&gt; 
 &lt;li&gt;What is Property Based Testing? 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://hypothesis.works/articles/what-is-property-based-testing/&quot;&gt;https://hypothesis.works/articles/what-is-property-based-testing/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Finding Property Tests 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.hillelwayne.com/post/contract-examples/&quot;&gt;https://www.hillelwayne.com/post/contract-examples/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Generating Good Generators for Inductive Relations 
  &lt;ul&gt; 
   &lt;li&gt;POPL 2018&lt;/li&gt; 
   &lt;li&gt;Leonidas Lampropoulos, Zoe Paraskevopoulou, Benjamin C. Pierce&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.cis.upenn.edu/~llamp/pdf/GeneratingGoodGenerators.pdf&quot;&gt;https://www.cis.upenn.edu/~llamp/pdf/GeneratingGoodGenerators.pdf&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://popl18.sigplan.org/event/popl-2018-papers-generating-good-generators-for-inductive-relations&quot;&gt;https://popl18.sigplan.org/event/popl-2018-papers-generating-good-generators-for-inductive-relations&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://www.cs.cmu.edu/~popl-interviews/paraskevopoulou.html&quot;&gt;http://www.cs.cmu.edu/~popl-interviews/paraskevopoulou.html&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;How hard is it to guide test case generators with branch coverage feedback? 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://engineering.backtrace.io/posts/2020-03-11-how-hard-is-it-to-guide-test-case-generators-with-branch-coverage-feedback/&quot;&gt;https://engineering.backtrace.io/posts/2020-03-11-how-hard-is-it-to-guide-test-case-generators-with-branch-coverage-feedback/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;How to Specify it! A Guide to Writing Properties of Pure Functions 
  &lt;ul&gt; 
   &lt;li&gt;Trends in Functional Programming (TFP) 2019&lt;/li&gt; 
   &lt;li&gt;John Hughes&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.tfp2019.org/resources/tfp2019-how-to-specify-it.pdf&quot;&gt;https://www.tfp2019.org/resources/tfp2019-how-to-specify-it.pdf&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Lambda Days 2020 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=G0NUOst-53U&quot;&gt;https://www.youtube.com/watch?v=G0NUOst-53U&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://www.infoq.com/news/2020/02/property-based-testing-guide/&quot;&gt;https://www.infoq.com/news/2020/02/property-based-testing-guide/&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Property-Based Testing: Metamorphic&lt;/h2&gt; 
&lt;p&gt;Metamorphic Relations, Metamorphic Testing&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Metamorphic Testing 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.hillelwayne.com/post/metamorphic-testing/&quot;&gt;https://www.hillelwayne.com/post/metamorphic-testing/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://ieeexplore.ieee.org/xpl/conhome/1817204/all-proceedings&quot;&gt;IEEE/ACM International Workshop on Metamorphic Testing (MET)&lt;/a&gt; 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;http://icse-conferences.org/&quot;&gt;ICSE (International Conference on Software Engineering)&lt;/a&gt;: &lt;a href=&quot;https://dblp.org/db/conf/icse/&quot;&gt;https://dblp.org/db/conf/icse/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;A Survey on Metamorphic Testing 
  &lt;ul&gt; 
   &lt;li&gt;IEEE Transactions on Software Engineering 42(9) 2016&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://eprints.whiterose.ac.uk/110335/1/segura16-tse.pdf&quot;&gt;http://eprints.whiterose.ac.uk/110335/1/segura16-tse.pdf&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://www.cs.ecu.edu/reu/reufiles/read/metamorphicTesting-16.pdf&quot;&gt;http://www.cs.ecu.edu/reu/reufiles/read/metamorphicTesting-16.pdf&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://pdfs.semanticscholar.org/bc06/14b761bd5f5bad9e157515d7b428ebe63170.pdf&quot;&gt;https://pdfs.semanticscholar.org/bc06/14b761bd5f5bad9e157515d7b428ebe63170.pdf&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Automated Metamorphic Testing 
  &lt;ul&gt; 
   &lt;li&gt;COMPSAC 2003: International Conference on Computer Software and Applications&lt;/li&gt; 
   &lt;li&gt;Arnaud Gotlieb, Bernard Botella&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://people.rennes.inria.fr/Arnaud.Gotlieb/publications/GB03.pdf&quot;&gt;http://people.rennes.inria.fr/Arnaud.Gotlieb/publications/GB03.pdf&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Metamorphic Testing 
  &lt;ul&gt; 
   &lt;li&gt;CREST Open Workshop 2012&lt;/li&gt; 
   &lt;li&gt;Tsong Yueh Chen&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://crest.cs.ucl.ac.uk/cow/20/slides/COW20_Chen.pdf&quot;&gt;http://crest.cs.ucl.ac.uk/cow/20/slides/COW20_Chen.pdf&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://crest.cs.ucl.ac.uk/cow/20/videos/COW20_Chen.mp4&quot;&gt;http://crest.cs.ucl.ac.uk/cow/20/videos/COW20_Chen.mp4&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;How to test a non-testable program? 
    &lt;ul&gt; 
     &lt;li&gt;STEM Blitz October 2014&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=s_geSjqYEyo&quot;&gt;https://www.youtube.com/watch?v=s_geSjqYEyo&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Metamorphic Testing 20 Years Later: A Hands-on Introduction 
  &lt;ul&gt; 
   &lt;li&gt;ICSE 2018&lt;/li&gt; 
   &lt;li&gt;Sergio Segura, Zhi Quan (George) Zhou&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://dl.acm.org/citation.cfm?id=3183468&quot;&gt;https://dl.acm.org/citation.cfm?id=3183468&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.researchgate.net/publication/323025715_Metamorphic_Testing_20_Years_Later_A_Hands-on_Introduction&quot;&gt;https://www.researchgate.net/publication/323025715_Metamorphic_Testing_20_Years_Later_A_Hands-on_Introduction&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://zenodo.org/record/1256230/files/ICSE18-TB-Segura-Zhou.pdf&quot;&gt;https://zenodo.org/record/1256230/files/ICSE18-TB-Segura-Zhou.pdf&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Metamorphic Testing and Its Applications 
  &lt;ul&gt; 
   &lt;li&gt;International Symposium on Future Software Technology (ISFST) 2004&lt;/li&gt; 
   &lt;li&gt;Zhou, Zhi Quan, D. H. Huang, T. H. Tse, Zongyuan Yang, Haitao Huang, T. Y. Chen&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.cs.hku.hk/data/techreps/document/TR-2004-12.pdf&quot;&gt;https://www.cs.hku.hk/data/techreps/document/TR-2004-12.pdf&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Metamorphic Testing: A New Approach for Generating Next Test Cases 
  &lt;ul&gt; 
   &lt;li&gt;Technical Report HKUST-CS98-01 (Hong Kong University of Science and Technology) 1998&lt;/li&gt; 
   &lt;li&gt;T. Y. Chen, S. C. Cheung, S. M. Yiu&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://arxiv.org/abs/2002.12543&quot;&gt;https://arxiv.org/abs/2002.12543&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.cse.ust.hk/~scc/publ/CS98-01-metamorphictesting.pdf&quot;&gt;https://www.cse.ust.hk/~scc/publ/CS98-01-metamorphictesting.pdf&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Metamorphic Testing: A Review of Challenges and Opportunities 
  &lt;ul&gt; 
   &lt;li&gt;ACM Computing Surveys (CSUR) Volume 51, Issue 1, 2018&lt;/li&gt; 
   &lt;li&gt;Tsong Yueh Chen, Fei-Ching Kuo, Huai Liu, Pak-Lok Poon, Dave Towey, T. H. Tse, and Zhi Quan Zhou&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://dl.acm.org/citation.cfm?id=3143561&quot;&gt;https://dl.acm.org/citation.cfm?id=3143561&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://www.cs.hku.hk/research/techreps/document/TR-2017-04.pdf&quot;&gt;http://www.cs.hku.hk/research/techreps/document/TR-2017-04.pdf&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Metamorphic Testing: A Simple Yet Effective Approach for Testing Scientific Software 
  &lt;ul&gt; 
   &lt;li&gt;Computing in Science &amp;amp; Engineering 21(1) 2019&lt;/li&gt; 
   &lt;li&gt;U. Kanewala and T. Yueh Chen&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://doi.ieeecomputersociety.org/10.1109/MCSE.2018.2875368&quot;&gt;https://doi.ieeecomputersociety.org/10.1109/MCSE.2018.2875368&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Techniques for Testing Scientific Programs Without an Oracle 
  &lt;ul&gt; 
   &lt;li&gt;International Workshop on Software Engineering for Computational Science and Engineering (SE-CSE) 2013&lt;/li&gt; 
   &lt;li&gt;U. Kanewala and J. Bieman&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.cs.colostate.edu/~bieman/Pubs/kanewalaBieman_icsews13secse_preprint.pdf&quot;&gt;https://www.cs.colostate.edu/~bieman/Pubs/kanewalaBieman_icsews13secse_preprint.pdf&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;hr&gt; 
&lt;h1&gt;Reduction&lt;/h1&gt; 
&lt;p&gt;Test-Case Reduction, Minimization&lt;/p&gt; 
&lt;p&gt;See also: &lt;a href=&quot;https://github.com/MattPD/cpplinks/blob/master/debugging.md&quot;&gt;Debugging&lt;/a&gt;: &lt;a href=&quot;https://github.com/MattPD/cpplinks/blob/master/debugging.md#readings&quot;&gt;Readings&lt;/a&gt;: Delta Debugging&lt;/p&gt; 
&lt;h2&gt;Reduction: Readings&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;Everything You Ever Wanted To Know About Test-Case Reduction, But Didn’t Know to Ask 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://blog.trailofbits.com/2019/11/11/test-case-reduction/&quot;&gt;https://blog.trailofbits.com/2019/11/11/test-case-reduction/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Mitigating (and Exploiting) Test Reduction Slippage 
  &lt;ul&gt; 
   &lt;li&gt;A-TEST 2016: International Workshop on Automating Test Case Design, Selection, and Evaluation&lt;/li&gt; 
   &lt;li&gt;Josie Holmes, Alex Groce, Mohammad Amin Alipour&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://agroce.github.io/atest16.pdf&quot;&gt;https://agroce.github.io/atest16.pdf&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Notes on Test-Case Reduction 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.drmaciver.com/2019/01/notes-on-test-case-reduction/&quot;&gt;https://www.drmaciver.com/2019/01/notes-on-test-case-reduction/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Reduce Before You Localize: Delta-Debugging and Spectrum-Based Fault Localization 
  &lt;ul&gt; 
   &lt;li&gt;2018 IEEE International Symposium on Software Reliability Engineering Workshops (ISSREW)&lt;/li&gt; 
   &lt;li&gt;Arpit Christi, Matthew Lyle Olson, Mohammad Amin Alipour, Alex Groce&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://doi.org/10.1109/ISSREW.2018.00005&quot;&gt;https://doi.org/10.1109/ISSREW.2018.00005&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://agroce.github.io/idear18.pdf&quot;&gt;https://agroce.github.io/idear18.pdf&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Rust Bug Minimization Patterns 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;http://blog.pnkfx.org/blog/2019/11/18/rust-bug-minimization-patterns/&quot;&gt;http://blog.pnkfx.org/blog/2019/11/18/rust-bug-minimization-patterns/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Reduction: Software&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;C-Reduce 
  &lt;ul&gt; 
   &lt;li&gt;&quot;C-Reduce is a tool that takes a large C, C++, or OpenCL file that has a property of interest (such as triggering a compiler bug) and automatically produces a much smaller C/C++ file that has the same property. It is intended for use by people who discover and report bugs in compilers and other tools that process source code.&quot;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://embed.cs.utah.edu/creduce/&quot;&gt;https://embed.cs.utah.edu/creduce/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Delta Debugging 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.st.cs.uni-saarland.de/dd/&quot;&gt;https://www.st.cs.uni-saarland.de/dd/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Delta: Heuristically minimizes interesting files 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;http://delta.stage.tigris.org/&quot;&gt;http://delta.stage.tigris.org/&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;Minimizing Interesting Files with Delta 
      &lt;ul&gt; 
       &lt;li&gt;&lt;a href=&quot;http://delta.stage.tigris.org/using_delta.html&quot;&gt;http://delta.stage.tigris.org/using_delta.html&lt;/a&gt;&lt;/li&gt; 
      &lt;/ul&gt; &lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;halfempty: Fast, Parallel Testcase Minimization 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/googleprojectzero/halfempty&quot;&gt;https://github.com/googleprojectzero/halfempty&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Shrink Ray: a test-case reducer designed to be effective on a wide range of formats 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/DRMacIver/shrinkray&quot;&gt;https://github.com/DRMacIver/shrinkray&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Structured Shrinking: Structured shrinking of unknown file formats 
  &lt;ul&gt; 
   &lt;li&gt;a program and library that attempts to find structure in a file and uses it to produce smaller examples of the same sort of file.&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/DRMacIver/structureshrink&quot;&gt;https://github.com/DRMacIver/structureshrink&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;hr&gt; 
&lt;h1&gt;Software&lt;/h1&gt; 
&lt;ul&gt; 
 &lt;li&gt;Approval Tests for C++ 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/approvals/ApprovalTests.cpp&quot;&gt;https://github.com/approvals/ApprovalTests.cpp&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://claremacrae.co.uk/conferences/presentations.html&quot;&gt;https://claremacrae.co.uk/conferences/presentations.html&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Boost.Test 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;http://www.boost.org/libs/test/&quot;&gt;http://www.boost.org/libs/test/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Production use of Boost.Test 
    &lt;ul&gt; 
     &lt;li&gt;BoostCon 2010; Gennadiy Rozental&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=WUQkn4CnzF4&quot;&gt;https://www.youtube.com/watch?v=WUQkn4CnzF4&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;[Boost].UT: C++20 μ(micro)/Unit Testing Framework 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/boost-experimental/ut&quot;&gt;https://github.com/boost-experimental/ut&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Catch2 
  &lt;ul&gt; 
   &lt;li&gt;A modern, C++-native, header-only, test framework for unit-tests, TDD and BDD - using C++11, C++14, C++17 and later (or C++03 on the Catch1.x branch)&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://catch-lib.net&quot;&gt;http://catch-lib.net&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/catchorg/Catch2&quot;&gt;https://github.com/catchorg/Catch2&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Modern C++ Testing with Catch2 - Phil Nash 
    &lt;ul&gt; 
     &lt;li&gt;Meeting C++ 2017: &lt;a href=&quot;https://www.youtube.com/watch?v=3tIE6X5FjDE&quot;&gt;https://www.youtube.com/watch?v=3tIE6X5FjDE&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;CppCon 2018: &lt;a href=&quot;https://www.youtube.com/watch?v=Ob5_XZrFQH0&quot;&gt;https://www.youtube.com/watch?v=Ob5_XZrFQH0&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Cgreen - The Modern Unit Test and Mocking Framework for C and C++ 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/cgreen-devs/cgreen&quot;&gt;https://github.com/cgreen-devs/cgreen&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;CppUTest unit testing and mocking framework for C/C++ 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;http://cpputest.github.com&quot;&gt;http://cpputest.github.com&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/cpputest/cpputest&quot;&gt;https://github.com/cpputest/cpputest&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;CUTE: C++ Unit Testing Easier 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://cute-test.com/&quot;&gt;https://cute-test.com/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/PeterSommerlad/CUTE&quot;&gt;https://github.com/PeterSommerlad/CUTE&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;cwrap - A toolset for client server testing 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://cwrap.org/&quot;&gt;https://cwrap.org/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;cwrap&apos;s mission is to enable developers to test complex network-based and privileged software stacks on UNIX machines with limited network access and without root privileges by providing preloadable libraries to wrap standard libc functions.&lt;/li&gt; 
   &lt;li&gt;Testing your full software stack with cwrap 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://lwn.net/Articles/594863/&quot;&gt;https://lwn.net/Articles/594863/&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;Testing your software stack without root privileges using cwrap 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://developers.redhat.com/blog/2015/05/05/testing-your-software-stack-without-root-privileges-using-cwrap/&quot;&gt;https://developers.redhat.com/blog/2015/05/05/testing-your-software-stack-without-root-privileges-using-cwrap/&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;DeepState: A unit test-like interface for fuzzing and symbolic execution 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/trailofbits/deepstate&quot;&gt;https://github.com/trailofbits/deepstate&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;DeepState: Symbolic Unit Testing for C and C++ 
    &lt;ul&gt; 
     &lt;li&gt;NDSS 18 Workshop on Binary Analysis Research&lt;/li&gt; 
     &lt;li&gt;Peter Goodman and Alex Groce&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://www.cefns.nau.edu/~adg326/bar18.pdf&quot;&gt;https://www.cefns.nau.edu/~adg326/bar18.pdf&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;Fuzzing an API with DeepState 
    &lt;ul&gt; 
     &lt;li&gt;Part 1: &lt;a href=&quot;https://blog.trailofbits.com/2019/01/22/fuzzing-an-api-with-deepstate-part-1/&quot;&gt;https://blog.trailofbits.com/2019/01/22/fuzzing-an-api-with-deepstate-part-1/&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;Part 2: &lt;a href=&quot;https://blog.trailofbits.com/2019/01/23/fuzzing-an-api-with-deepstate-part-2/&quot;&gt;https://blog.trailofbits.com/2019/01/23/fuzzing-an-api-with-deepstate-part-2/&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;doctest 
  &lt;ul&gt; 
   &lt;li&gt;The fastest feature-rich C++11/14/17/20 single-header testing framework for unit tests and TDD&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/onqtam/doctest&quot;&gt;https://github.com/onqtam/doctest&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Google Test 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/google/googletest&quot;&gt;https://github.com/google/googletest&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;GUnit - Google.Test/Google.Mock/Cucumber on steroids 
  &lt;ul&gt; 
   &lt;li&gt;extends/simplifies Google.Test/Google.Mock and adds support for Gherkin (Behaviour Driven Development) to it&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/cpp-testing/GUnit&quot;&gt;https://github.com/cpp-testing/GUnit&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;OutputCheck: A tool for checking tool output inspired by LLVM&apos;s FileCheck 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/stp/OutputCheck&quot;&gt;https://github.com/stp/OutputCheck&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;RapidCheck: QuickCheck clone for C++ with the goal of being simple to use with as little boilerplate as possible. 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/emil-e/rapidcheck&quot;&gt;https://github.com/emil-e/rapidcheck&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Generating test cases so you don’t have to 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://labs.spotify.com/2015/06/25/rapid-check/&quot;&gt;https://labs.spotify.com/2015/06/25/rapid-check/&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;Property based testing in C++ - How to write 1000s of tests in one sitting? 
    &lt;ul&gt; 
     &lt;li&gt;code::dive 2016; Patryk Małek&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://codedive.pl/index/speaker/name/patryk-malek/year/2016/&quot;&gt;https://codedive.pl/index/speaker/name/patryk-malek/year/2016/&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=aiapg-3vDcQ&quot;&gt;https://www.youtube.com/watch?v=aiapg-3vDcQ&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://cdn2-ecros.pl/event/codedive/files/presentations/2016/Patryk_Malek_Property_based_testing_in_cpp.pdf&quot;&gt;https://cdn2-ecros.pl/event/codedive/files/presentations/2016/Patryk_Malek_Property_based_testing_in_cpp.pdf&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Software: Test Doubles&lt;/h2&gt; 
&lt;p&gt;Test Doubles: Faking, Mocking&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Fake Function Framework (fff) 
  &lt;ul&gt; 
   &lt;li&gt;A testing micro framework for creating function test doubles.&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/meekrosoft/fff&quot;&gt;https://github.com/meekrosoft/fff&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;gen-xfakes 
  &lt;ul&gt; 
   &lt;li&gt;Generate exploding fakes from C/C++ linker error output (used for unit testing)&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/jwgrenning/gen-xfakes&quot;&gt;https://github.com/jwgrenning/gen-xfakes&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Wrestle Legacy C and C++ into a Test Harness – Linker Errors 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;http://blog.wingman-sw.com/wrestle-legacy-c-cpp-into-tests-linker-errors&quot;&gt;http://blog.wingman-sw.com/wrestle-legacy-c-cpp-into-tests-linker-errors&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;PowerFake 
  &lt;ul&gt; 
   &lt;li&gt;C++ Faking library, which allows faking regular functions, static member functions and non-virtual member functions for testing purposes.&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://gitlab.com/hedayat/powerfake&quot;&gt;https://gitlab.com/hedayat/powerfake&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://hedayatvk.wordpress.com/2018/01/22/introducing-powerfake-for-c/&quot;&gt;https://hedayatvk.wordpress.com/2018/01/22/introducing-powerfake-for-c/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Software: Test Doubles: Mocking&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;FakeIt: a simple mocking framework for C++ 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/eranpeer/FakeIt&quot;&gt;https://github.com/eranpeer/FakeIt&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Google Mock: The Google C++ mocking framework 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/google/googletest/tree/master/googlemock&quot;&gt;https://github.com/google/googletest/tree/master/googlemock&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/google/googletest/tree/master/googlemock/docs&quot;&gt;https://github.com/google/googletest/tree/master/googlemock/docs&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;GUnit.GMock 
  &lt;ul&gt; 
   &lt;li&gt;GoogleMock without writing and maintaining mocks by hand&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/cpp-testing/GUnit/blob/master/docs/GMock.md&quot;&gt;https://github.com/cpp-testing/GUnit/blob/master/docs/GMock.md&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Hippomocks: Single-header mocking framework 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/dascandy/hippomocks&quot;&gt;https://github.com/dascandy/hippomocks&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Mockitopp: Simple mocking for C++ 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/tpounds/mockitopp&quot;&gt;https://github.com/tpounds/mockitopp&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Trompeloeil: Header-only C++14 mocking framework 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/rollbear/trompeloeil&quot;&gt;https://github.com/rollbear/trompeloeil&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;hr&gt; 
&lt;h1&gt;Talks&lt;/h1&gt; 
&lt;ul&gt; 
 &lt;li&gt;Google Test Automation Conference (GTAC) 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://developers.google.com/google-test-automation-conference/&quot;&gt;https://developers.google.com/google-test-automation-conference/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Talks: 2019&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;Back to Basics: Test-driven Development 
  &lt;ul&gt; 
   &lt;li&gt;CppCon 2019; Fedor Pikus&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=RoYljVOj2H8&quot;&gt;https://www.youtube.com/watch?v=RoYljVOj2H8&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Making Testing C++ Binaries Practical @ Facebook Scale: A CI Story 
  &lt;ul&gt; 
   &lt;li&gt;CppCon 2019; Mark Isaacson&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=p7xdNjdtojU&quot;&gt;https://www.youtube.com/watch?v=p7xdNjdtojU&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Talks: 2018&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;But is it fun? Software Testing in the Video Game Industry 
  &lt;ul&gt; 
   &lt;li&gt;ICST 2018&lt;/li&gt; 
   &lt;li&gt;Magnus Nordin (Electronic Arts), David King (DICE), and Stefan Posthuma (Electronic Arts)&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=CBIhu_9OolY&quot;&gt;https://www.youtube.com/watch?v=CBIhu_9OolY&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Ensuring Exception Safety Through Testing 
  &lt;ul&gt; 
   &lt;li&gt;CppCon 2018; Jon Cohen&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=XPzHNSUnTc4&quot;&gt;https://www.youtube.com/watch?v=XPzHNSUnTc4&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Talks: 2017&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;C++ Unit testing - the good, the bad &amp;amp; the ugly 
  &lt;ul&gt; 
   &lt;li&gt;NDC 2017; Dror Helper&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=EiN3cF_y3vM&quot;&gt;https://www.youtube.com/watch?v=EiN3cF_y3vM&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://vimeo.com/223984399&quot;&gt;https://vimeo.com/223984399&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.slideshare.net/dhelper/c-unit-testing-the-good-the-bad-the-ugly&quot;&gt;https://www.slideshare.net/dhelper/c-unit-testing-the-good-the-bad-the-ugly&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Microcontrollers in Micro-increments: A Test-driven C++ Workflow for Embedded Systems 
  &lt;ul&gt; 
   &lt;li&gt;CppCon 2017: Mike Ritchie&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=XuHlDtWYeD8&quot;&gt;https://www.youtube.com/watch?v=XuHlDtWYeD8&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Mocking C++ 
  &lt;ul&gt; 
   &lt;li&gt;C++Now 2017; Peter Bindels&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=t0wLm2iiEH0&quot;&gt;https://www.youtube.com/watch?v=t0wLm2iiEH0&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Mocking Frameworks considered harmful 
  &lt;ul&gt; 
   &lt;li&gt;CppCon 2017; Peter Sommerlad&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=uhuHZXTRfH4&quot;&gt;https://www.youtube.com/watch?v=uhuHZXTRfH4&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Talks: 2016&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;Assessing software quality from first principles 
  &lt;ul&gt; 
   &lt;li&gt;UCIBrenICS Seminar 2016&lt;/li&gt; 
   &lt;li&gt;Reid Holmes, University of British Columbia&lt;/li&gt; 
   &lt;li&gt;code coverage and mutation testing&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=RIVLHQjpTck&quot;&gt;https://www.youtube.com/watch?v=RIVLHQjpTck&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Talks: 2015&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;Advanced Unit Testing in C &amp;amp; C++ 
  &lt;ul&gt; 
   &lt;li&gt;CppCon 2015; Matt Hargett&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=Wmy6g-aVgZI&quot;&gt;https://www.youtube.com/watch?v=Wmy6g-aVgZI&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;All Your Tests are Terrible: Tales from the Trenches 
  &lt;ul&gt; 
   &lt;li&gt;CppCon 2015; T. Winters &amp;amp; H. Wright&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=u5senBJUkPc&quot;&gt;https://www.youtube.com/watch?v=u5senBJUkPc&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Fast Iteration Tools in the Production of the Talos Principle 
  &lt;ul&gt; 
   &lt;li&gt;GDC Europe 2015; Alen Ladavac&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://www.gdcvault.com/play/1022784/Fast-Iteration-Tools-in-the&quot;&gt;http://www.gdcvault.com/play/1022784/Fast-Iteration-Tools-in-the&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Talks: 2014&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;Pragmatic Unit Testing in C++ 
  &lt;ul&gt; 
   &lt;li&gt;CppCon 2014; Matt Hargett&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=Y8YVSohnlgY&quot;&gt;https://www.youtube.com/watch?v=Y8YVSohnlgY&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Static analysis - verification</title>
      <link>https://tedneward.github.io/Research/reading/development/static-verification/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">reading/development/static-verification/index.html</guid>
      	<description>
	&lt;ul&gt; 
 &lt;li&gt; &lt;p&gt;Formal Verification to Ensuring the Memory Safety of C++ Programs&lt;/p&gt; 
  &lt;ul&gt; 
   &lt;li&gt;2020 M.Sc. Thesis; Felipe R. Monteiro&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://feliperodri.github.io/papers/msc-manuscript.pdf&quot;&gt;https://feliperodri.github.io/papers/msc-manuscript.pdf&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://feliperodri.github.io/talks/msc-presentation.pdf&quot;&gt;https://feliperodri.github.io/talks/msc-presentation.pdf&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Apply model checking techniques to ensuring memory safety of C++ programs: 
    &lt;ul&gt; 
     &lt;li&gt;(i) Provide a logical formalization of essential features that the C++ programming language offers, such as templates, sequential and associative containers, inheritance, polymorphism, and exception handling.&lt;/li&gt; 
     &lt;li&gt;(ii) Provide a set of abstractions to the Standard C++ Libraries that reflects their semantics, in order to enable the verification of functional properties related to the use of these libraries.&lt;/li&gt; 
     &lt;li&gt;(iii) Extend an existing verifier to handle the verification of C++ programs based on (i) and (ii) and evaluate its efficiency and effectiveness in comparison to similar state-of-the-art approaches.&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Model Checking a C++ Software Framework, a Case Study&lt;/p&gt; 
  &lt;ul&gt; 
   &lt;li&gt;European Software Engineering Conference / Foundations of Software Engineering (ESEC/FSE) 2019&lt;/li&gt; 
   &lt;li&gt;John Lång, I.S.W.B. Prasetya&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://arxiv.org/abs/1907.00172&quot;&gt;https://arxiv.org/abs/1907.00172&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Verification: Software&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt; &lt;p&gt;CMBC: C Bounded Model Checker&lt;/p&gt; 
  &lt;ul&gt; 
   &lt;li&gt;CBMC is a Bounded Model Checker for C and C++ programs.&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://www.cprover.org/cbmc/&quot;&gt;http://www.cprover.org/cbmc/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/diffblue/cbmc&quot;&gt;https://github.com/diffblue/cbmc&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;DIVINE&lt;/p&gt; 
  &lt;ul&gt; 
   &lt;li&gt;DIVINE is a modern, explicit-state model checker. Based on the LLVM toolchain, it can verify programs written in multiple real-world programming languages, including C and C++.&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://divine.fi.muni.cz/&quot;&gt;https://divine.fi.muni.cz/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;ESBMC&lt;/p&gt; 
  &lt;ul&gt; 
   &lt;li&gt;ESBMC is an open source, permissively licensed, context-bounded model checker based on satisfiability modulo theories for the verification of single- and multi-threaded C/C++ programs.&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://www.esbmc.org/&quot;&gt;http://www.esbmc.org/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Symbiotic&lt;/p&gt; 
  &lt;ul&gt; 
   &lt;li&gt;Tool for verifying computer programs based on instrumentation, program slicing and symbolic executor KLEE.&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://staticafi.github.io/symbiotic/&quot;&gt;http://staticafi.github.io/symbiotic/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Tracing (in software) reading</title>
      <link>https://tedneward.github.io/Research/reading/development/tracing/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">reading/development/tracing/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://jvns.ca/blog/2014/04/20/debug-your-programs-like-theyre-closed-source/&quot;&gt;Debug your programs like they&apos;re closed source! (strace, ltrace)&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://queue.acm.org/detail.cfm?id=1117401&quot;&gt;Hidden in Plain Sight&lt;/a&gt;: ACM Queue 4(1) (2006); Bryan Cantrill&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://publications.polymtl.ca/2980/&quot;&gt;Multi-scale navigation of large trace data: A survey&lt;/a&gt;&lt;br&gt; - Concurrency and Computation: Practice and Experience, 29(10) 2017&lt;br&gt; - Ezzati-Jivan, N. &amp;amp; Dagenais, M. R&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://dl.acm.org/citation.cfm?id=3158644&quot;&gt;Survey and Analysis of Kernel and Userspace Tracers on Linux: Design, Implementation, and Overhead&lt;/a&gt;&lt;br&gt; - ACM Computing Surveys (CSUR) Volume 51 Issue 2, March 2018&lt;br&gt; - Mohamad Gebai, Michel R. Dagenais&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://github.com/VANDAL/SynchroTrace-gem5&quot;&gt;SynchroTrace&lt;/a&gt;:&lt;br&gt; - &lt;a href=&quot;http://vlsi.ece.drexel.edu/index.php?title=SynchroTrace&quot;&gt;http://vlsi.ece.drexel.edu/index.php?title=SynchroTrace&lt;/a&gt;&lt;br&gt; - &lt;a href=&quot;https://sites.tufts.edu/tcal/current-research-projects/synchrotrace/&quot;&gt;https://sites.tufts.edu/tcal/current-research-projects/synchrotrace/&lt;/a&gt;&lt;br&gt; - Synchronization-Aware Architecture-Agnostic Traces for Lightweight Multicore Simulation of CMP and HPC Workloads&lt;br&gt; - 2018 ACM Transactions on Architecture and Code Optimization (TACO) 15(1)&lt;br&gt; - &lt;a href=&quot;http://vlsi.ece.drexel.edu/images/b/b1/ST_2018.pdf&quot;&gt;http://vlsi.ece.drexel.edu/images/b/b1/ST_2018.pdf&lt;/a&gt;&lt;br&gt; - SynchroTrace: Synchronization-aware Architecture-agnostic Traces for Light-Weight Multicore Simulation&lt;br&gt; - 2015 IEEE International Symposium on Performance Analysis of Systems and Software (ISPASS)&lt;br&gt; - &lt;a href=&quot;http://dpac.ece.drexel.edu/wp-content/uploads/2013/04/SynchroTrace.pdf&quot;&gt;http://dpac.ece.drexel.edu/wp-content/uploads/2013/04/SynchroTrace.pdf&lt;/a&gt;&lt;/p&gt; 
&lt;h2&gt;Hardware Assistance / Processor Tracing&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;Hardware-assisted instruction profiling and latency detection 
  &lt;ul&gt; 
   &lt;li&gt;The Journal of Engineering, Volume 2016, Issue 10&lt;/li&gt; 
   &lt;li&gt;Suchakrapani Datt Sharma, Michel Dagenais&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://digital-library.theiet.org/content/journals/10.1049/joe.2016.0127&quot;&gt;https://digital-library.theiet.org/content/journals/10.1049/joe.2016.0127&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Hardware-assisted software event tracing 
  &lt;ul&gt; 
   &lt;li&gt;Concurrency and Computation: Practice and Experience, 29(10) 2017&lt;/li&gt; 
   &lt;li&gt;Vergé, A., Ezzati-Jivan, N. &amp;amp; Dagenais, M. R.&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://publications.polymtl.ca/2981/&quot;&gt;https://publications.polymtl.ca/2981/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Hardware trace reconstruction of runtime compiled code 
  &lt;ul&gt; 
   &lt;li&gt;Software: Practice and Experience 2018&lt;/li&gt; 
   &lt;li&gt;Sharma, S.D. &amp;amp; Dagenais, M.R.&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://doi.org/10.1002/spe.2567&quot;&gt;https://doi.org/10.1002/spe.2567&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Hardware Tracing for Fast and Precise Performance Analysis 
  &lt;ul&gt; 
   &lt;li&gt;2015; Suchakra Sharma&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://thenewstack.io/hardware-tracing-fast-precise-performance-analysis/&quot;&gt;https://thenewstack.io/hardware-tracing-fast-precise-performance-analysis/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;In-Depth System Analysis Using Hardware-Assisted Tracing 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.sigarch.org/in-depth-system-analysis-using-hardware-assisted-tracing/&quot;&gt;https://www.sigarch.org/in-depth-system-analysis-using-hardware-assisted-tracing/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Low-Impact System Performance Analysis Using Hardware Assisted Tracing Techniques 
  &lt;ul&gt; 
   &lt;li&gt;2017 PhD thesis; Sharma, S. D.&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://publications.polymtl.ca/2485/&quot;&gt;https://publications.polymtl.ca/2485/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://publications.polymtl.ca/2485/1/2017_SuchakrapaniDattSharma.pdf&quot;&gt;https://publications.polymtl.ca/2485/1/2017_SuchakrapaniDattSharma.pdf&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Low Overhead Hardware-Assisted Virtual Machine Analysis and Profiling 
  &lt;ul&gt; 
   &lt;li&gt;2016 IEEE Globecom Workshops&lt;/li&gt; 
   &lt;li&gt;Sharma, S. D., Bastien, G., Nemati, H. &amp;amp; Dagenais, M.&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://publications.polymtl.ca/2975/1/2016_Sharma_Low_overhead_hardware-assisted_virtual_machive.pdf&quot;&gt;https://publications.polymtl.ca/2975/1/2016_Sharma_Low_overhead_hardware-assisted_virtual_machive.pdf&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;libbts.c: minimal BTS tracing wrapper for Linux Perf 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://gist.github.com/pkhuong/1ce34e33c6df4b9be3bc9beb22415a47&quot;&gt;https://gist.github.com/pkhuong/1ce34e33c6df4b9be3bc9beb22415a47&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Andi Kleen&apos;s Intel Processor Trace resources 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;http://halobates.de/blog/p/406&quot;&gt;http://halobates.de/blog/p/406&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://web.archive.org/http://halobates.de/blog/p/406&quot;&gt;http://web.archive.org/http://halobates.de/blog/p/406&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Cheat sheet for Intel Processor Trace with Linux perf and gdb 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://halobates.de/blog/p/410&quot;&gt;https://halobates.de/blog/p/410&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;http://web.archive.org/http://halobates.de/blog/p/410&quot;&gt;http://web.archive.org/http://halobates.de/blog/p/410&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;Simple-PT: Simple Intel CPU processor tracing on Linux 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://github.com/andikleen/simple-pt&quot;&gt;https://github.com/andikleen/simple-pt&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Intel Processor Trace 
  &lt;ul&gt; 
   &lt;li&gt;Enhance performance analysis with Intel Processor Trace - &lt;a href=&quot;https://easyperf.net/blog/2019/08/23/Intel-Processor-Trace&quot;&gt;https://easyperf.net/blog/2019/08/23/Intel-Processor-Trace&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Better debugging experience - &lt;a href=&quot;https://easyperf.net/blog/2019/08/30/Intel-PT-part2&quot;&gt;https://easyperf.net/blog/2019/08/30/Intel-PT-part2&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Analyzing performance glitches - &lt;a href=&quot;https://easyperf.net/blog/2019/09/06/Intel-PT-part3&quot;&gt;https://easyperf.net/blog/2019/09/06/Intel-PT-part3&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Better profiling experience - &lt;a href=&quot;https://easyperf.net/blog/2019/09/13/Intel-PT-part4&quot;&gt;https://easyperf.net/blog/2019/09/13/Intel-PT-part4&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Failure Sketches: A Better Way to Debug 
  &lt;ul&gt; 
   &lt;li&gt;HotOS 2015&lt;/li&gt; 
   &lt;li&gt;Baris Kasikci, Benjamin Schubert, Cristiano Pereira, Gilles Pokam, Madan Musuvathi, George Candea&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.usenix.org/conference/hotos15/workshop-program/presentation/kasikci&quot;&gt;https://www.usenix.org/conference/hotos15/workshop-program/presentation/kasikci&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://dslab.epfl.ch/pubs/failure-sketches.pdf&quot;&gt;http://dslab.epfl.ch/pubs/failure-sketches.pdf&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://web.eecs.umich.edu/~barisk/public/fs-slides.pdf&quot;&gt;https://web.eecs.umich.edu/~barisk/public/fs-slides.pdf&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Failure Sketching: A Technique for Automated Root Cause Diagnosis of In-Production Failures 
  &lt;ul&gt; 
   &lt;li&gt;Symposium on Operating Systems Principles (SOSP) 2015&lt;/li&gt; 
   &lt;li&gt;Baris Kasikci, Benjamin Schubert, Cristiano Pereira, Gilles Pokam, George Candea&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=99hXVFe33w8&quot;&gt;https://www.youtube.com/watch?v=99hXVFe33w8&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://dslab.epfl.ch/proj/gist/&quot;&gt;http://dslab.epfl.ch/proj/gist/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://dslab.epfl.ch/pubs/gist.pdf&quot;&gt;http://dslab.epfl.ch/pubs/gist.pdf&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://web.eecs.umich.edu/~barisk/public/gist-slides.pdf&quot;&gt;https://web.eecs.umich.edu/~barisk/public/gist-slides.pdf&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://blog.acolyer.org/2015/10/12/failure-sketching-a-technique-for-automated-root-cause-diagnosis-of-in-production-failures/&quot;&gt;https://blog.acolyer.org/2015/10/12/failure-sketching-a-technique-for-automated-root-cause-diagnosis-of-in-production-failures/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Fuzzing 
  &lt;ul&gt; 
   &lt;li&gt;Internals of Hongfuzz - Intel PT 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://tunnelshade.in/blog/2018/09/hongfuzz-intel-pt-instrumentation/&quot;&gt;https://tunnelshade.in/blog/2018/09/hongfuzz-intel-pt-instrumentation/&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;PTrix: Efficient Hardware-Assisted Fuzzing for COTS Binary 
    &lt;ul&gt; 
     &lt;li&gt;2019 Asia Conference on Computer and Communications Security (AsiaCCS)&lt;/li&gt; 
     &lt;li&gt;Yaohui Chen, Dongliang Mu, Jun Xu, Zhichuang Sun, Wenbo Shen, Xinyu Xing, Long Lu, Bing Mao&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://arxiv.org/abs/1905.10499&quot;&gt;https://arxiv.org/abs/1905.10499&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://github.com/junxzm1990/afl-pt&quot;&gt;https://github.com/junxzm1990/afl-pt&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;WinAFL Intel PT mode 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://github.com/googleprojectzero/winafl/blob/master/readme_pt.md&quot;&gt;https://github.com/googleprojectzero/winafl/blob/master/readme_pt.md&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Intel PT Micro Tutorial - MICRO-48 (2015) 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://sites.google.com/site/intelptmicrotutorial/&quot;&gt;https://sites.google.com/site/intelptmicrotutorial/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;libipt - an Intel(R) Processor Trace decoder library 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/01org/processor-trace&quot;&gt;https://github.com/01org/processor-trace&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/intel/libipt&quot;&gt;https://github.com/intel/libipt&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Linux perf Documentation: Intel Processor Trace 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/torvalds/linux/blob/master/tools/perf/Documentation/intel-pt.txt&quot;&gt;https://github.com/torvalds/linux/blob/master/tools/perf/Documentation/intel-pt.txt&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Inferring Fine-grained Control Flow Inside SGX Enclaves with Branch Shadowing 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://arxiv.org/abs/1611.06952&quot;&gt;https://arxiv.org/abs/1611.06952&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.usenix.org/conference/usenixsecurity17/technical-sessions/presentation/lee-sangho&quot;&gt;https://www.usenix.org/conference/usenixsecurity17/technical-sessions/presentation/lee-sangho&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&quot;Table 1: Measuring branch misprediction penalty with RDTSCP, Intel PT CYC packet, and LBR elapsed cycle (10,000 times). We put 120 NOP instructions at the fall-through path. The LBR elapsed cycle is less noisy than RDTSCP and Intel PT.&quot;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;POMP: Postmortem Program Analysis with Hardware-Enhanced Post-Crash Artifacts 
  &lt;ul&gt; 
   &lt;li&gt;USENIX Security 2017&lt;/li&gt; 
   &lt;li&gt;Jun Xu, Dongliang Mu, Xinyu Xing, Peng Liu, Ping Chen, Bing Mao&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.usenix.org/conference/usenixsecurity17/technical-sessions/presentation/xu-jun&quot;&gt;https://www.usenix.org/conference/usenixsecurity17/technical-sessions/presentation/xu-jun&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/junxzm1990/pomp&quot;&gt;https://github.com/junxzm1990/pomp&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Processor-Tracing Guided Region Formation in Dynamic Binary Translation 
  &lt;ul&gt; 
   &lt;li&gt;ACM Transactions on Architecture and Code Optimization (TACO) 15(4):52 (2018)&lt;/li&gt; 
   &lt;li&gt;Ding-Yong Hong, Jan-Jan Wu, Yu-Ping Liu, Sheng-Yu Fu, Wei-Chung Hsu&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://dl.acm.org/citation.cfm?id=3281664&quot;&gt;https://dl.acm.org/citation.cfm?id=3281664&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;paper: &lt;a href=&quot;https://www.iis.sinica.edu.tw/papers/wuj/22203-F.pdf&quot;&gt;https://www.iis.sinica.edu.tw/papers/wuj/22203-F.pdf&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;slides: &lt;a href=&quot;https://www.iis.sinica.edu.tw/papers/wuj/22189-A.pdf&quot;&gt;https://www.iis.sinica.edu.tw/papers/wuj/22189-A.pdf&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;SATT Software Analyze Trace Tool 
  &lt;ul&gt; 
   &lt;li&gt;Experimental Linux SW tool to trace, process and analyze full stack SW traces utilizing Intel HW tracing block Intel PT (Intel Processor Trace).&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/01org/satt&quot;&gt;https://github.com/01org/satt&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Towards Production-Run Heisenbugs Reproduction on Commercial Hardware 
  &lt;ul&gt; 
   &lt;li&gt;USENIX Annual Technical Conference (ATC) 2017&lt;/li&gt; 
   &lt;li&gt;Shiyou Huang, Bowen Cai, Jeff Huang&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.usenix.org/conference/atc17/technical-sessions/presentation/huang&quot;&gt;https://www.usenix.org/conference/atc17/technical-sessions/presentation/huang&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;WinIPT: Windows Library for Intel Process Trace 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/ionescu007/winipt&quot;&gt;https://github.com/ionescu007/winipt&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Windows Intel PT Support 
  &lt;ul&gt; 
   &lt;li&gt;This driver implements the Intel Processor Trace functionality in Intel Skylake architecture for Microsoft Windows.&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/intelpt/WindowsIntelPT&quot;&gt;https://github.com/intelpt/WindowsIntelPT&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Harnessing Intel Processor Trace on Windows for Vulnerability Discovery 
    &lt;ul&gt; 
     &lt;li&gt;Richard Johnson - &lt;a href=&quot;http://moflow.org/&quot;&gt;http://moflow.org/&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;http://moflow.org/Presentations/Harnessing%20Intel%20Processor%20Trace%20on%20Windows%20for%20Vulnerability%20Discovery%20-%20rjohnson.pdf&quot;&gt;http://moflow.org/Presentations/Harnessing%20Intel%20Processor%20Trace%20on%20Windows%20for%20Vulnerability%20Discovery%20-%20rjohnson.pdf&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;HITB2017AMS&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=r8lzui24Cdw&quot;&gt;https://www.youtube.com/watch?v=r8lzui24Cdw&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;http://conference.hitb.org/hitbsecconf2017ams/materials/D1T1%20-%20Richard%20Johnson%20-%20Harnessing%20Intel%20Processor%20Trace%20on%20Windows%20for%20Vulnerability%20Discovery.pdf&quot;&gt;http://conference.hitb.org/hitbsecconf2017ams/materials/D1T1%20-%20Richard%20Johnson%20-%20Harnessing%20Intel%20Processor%20Trace%20on%20Windows%20for%20Vulnerability%20Discovery.pdf&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;hr&gt; 
&lt;h1&gt;Software&lt;/h1&gt; 
&lt;ul&gt; 
 &lt;li&gt;barectf: Generator of ANSI C tracers which output CTF 
  &lt;ul&gt; 
   &lt;li&gt;a command-line generator of ANSI C tracers which output Common Trace Format packets natively&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/efficios/barectf&quot;&gt;https://github.com/efficios/barectf&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Drltrace: library calls tracer for Windows and Linux applications 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/mxmssh/drltrace&quot;&gt;https://github.com/mxmssh/drltrace&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.slideshare.net/MaximShudrak/tricky-sample-hack-it-easy-applying-dynamic-binary-inastrumentation-to-lightweight-malware-behaviour-analysis&quot;&gt;https://www.slideshare.net/MaximShudrak/tricky-sample-hack-it-easy-applying-dynamic-binary-inastrumentation-to-lightweight-malware-behaviour-analysis&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;DTrace 
  &lt;ul&gt; 
   &lt;li&gt;Awesome DTrace - &lt;a href=&quot;http://awesome-dtrace.com/&quot;&gt;http://awesome-dtrace.com/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;DTrace Safety - &lt;a href=&quot;http://dtrace.org/blogs/bmc/2005/07/19/dtrace-safety/&quot;&gt;http://dtrace.org/blogs/bmc/2005/07/19/dtrace-safety/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;DTrace Internals: Digging into DTrace 
    &lt;ul&gt; 
     &lt;li&gt;BSDCan 2017; Arun Thomas&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=Vstwq5l_dwY&quot;&gt;https://www.youtube.com/watch?v=Vstwq5l_dwY&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;http://www.bsdcan.org/2017/schedule/events/793.en.html&quot;&gt;http://www.bsdcan.org/2017/schedule/events/793.en.html&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;DTrace for Linux 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://github.com/dtrace4linux/linux&quot;&gt;https://github.com/dtrace4linux/linux&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;FOSDEM 2018; Tomáš Jedlička 
      &lt;ul&gt; 
       &lt;li&gt;&lt;a href=&quot;https://fosdem.org/2018/schedule/event/debugging_tools_dtrace/&quot;&gt;https://fosdem.org/2018/schedule/event/debugging_tools_dtrace/&lt;/a&gt;&lt;/li&gt; 
      &lt;/ul&gt; &lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;DTrace on Windows 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://github.com/opendtrace/opendtrace/tree/windows&quot;&gt;https://github.com/opendtrace/opendtrace/tree/windows&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://github.com/microsoft/DTrace-on-Windows&quot;&gt;https://github.com/microsoft/DTrace-on-Windows&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://techcommunity.microsoft.com/t5/Windows-Kernel-Internals/DTrace-on-Windows/ba-p/362902&quot;&gt;https://techcommunity.microsoft.com/t5/Windows-Kernel-Internals/DTrace-on-Windows/ba-p/362902&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;DTrace Review 
    &lt;ul&gt; 
     &lt;li&gt;Google Tech Talks; August 15, 2007; Bryan Cantrill&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=TgmA48fILq8&quot;&gt;https://www.youtube.com/watch?v=TgmA48fILq8&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=6chLw2aodYQ&quot;&gt;https://www.youtube.com/watch?v=6chLw2aodYQ&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;minitrace: Simple C/C++ library for producing JSON traces suitable for Chrome&apos;s built-in trace viewer (about:tracing) 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/hrydgard/minitrace&quot;&gt;https://github.com/hrydgard/minitrace&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Phosphor: High performance event tracing 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;http://couchbase.github.io/phosphor/&quot;&gt;http://couchbase.github.io/phosphor/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/couchbase/phosphor&quot;&gt;https://github.com/couchbase/phosphor&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;PIEtrace: Platform Independent Executable Trace 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://sites.google.com/site/pitprj12/&quot;&gt;https://sites.google.com/site/pitprj12/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Software: Viewers&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;Babeltrace 
  &lt;ul&gt; 
   &lt;li&gt;The Babeltrace project provides trace read and write libraries, as well as a trace converter. Plugins can be created for any trace format to allow its conversion to/from another trace format.&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://diamon.org/babeltrace/&quot;&gt;http://diamon.org/babeltrace/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/efficios/babeltrace&quot;&gt;https://github.com/efficios/babeltrace&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Common Trace Format 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://diamon.org/ctf/&quot;&gt;https://diamon.org/ctf/&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;FlameGraph: Stack trace visualize 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/brendangregg/FlameGraph&quot;&gt;https://github.com/brendangregg/FlameGraph&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://www.brendangregg.com/flamegraphs.html&quot;&gt;http://www.brendangregg.com/flamegraphs.html&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;LTTng Scope 
  &lt;ul&gt; 
   &lt;li&gt;a trace viewer and analyzer for CTF traces, with a focus on LTTng kernel and user space traces.&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/lttng/lttng-scope&quot;&gt;https://github.com/lttng/lttng-scope&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://lttng.org/blog/2018/03/21/lttng-scope-0.3-a-basic-tutorial/&quot;&gt;https://lttng.org/blog/2018/03/21/lttng-scope-0.3-a-basic-tutorial/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;rgat: An instruction trace visualisation tool for dynamic program analysis 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/ncatlin/rgat&quot;&gt;https://github.com/ncatlin/rgat&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Trace Compass: an open-source (EPL-licensed) trace viewer and analyzer 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;http://tracecompass.org/&quot;&gt;http://tracecompass.org/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/tracecompass&quot;&gt;https://github.com/tracecompass&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://wiki.eclipse.org/Trace_Compass&quot;&gt;https://wiki.eclipse.org/Trace_Compass&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Software: Linux&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;Linux tracing systems &amp;amp; how they fit together 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://jvns.ca/blog/2017/07/05/linux-tracing-systems/&quot;&gt;https://jvns.ca/blog/2017/07/05/linux-tracing-systems/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;KUtrace 
  &lt;ul&gt; 
   &lt;li&gt;Low-overhead tracing of all Linux kernel-user transitions, for serious performance analysis. Includes kernel patches, loadable module, and post-processing software. Output is HTML/SVG per-CPU-core timeline that you can pan/zoom down to the nanosecond.&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/dicksites/KUtrace&quot;&gt;https://github.com/dicksites/KUtrace&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;KUTrace: Where have all the nanoseconds gone?, Richard Sites 
    &lt;ul&gt; 
     &lt;li&gt;Tracing Summit 2017; Richard Sites&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=UYwWollxzAk&quot;&gt;https://www.youtube.com/watch?v=UYwWollxzAk&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://tracingsummit.org/wiki/TracingSummit2017KUTrace&quot;&gt;https://tracingsummit.org/wiki/TracingSummit2017KUTrace&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://tracingsummit.org/w/images/3/30/TS17-kutrace.pdf&quot;&gt;https://tracingsummit.org/w/images/3/30/TS17-kutrace.pdf&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;Benchmarking &quot;Hello, World!&quot; 
    &lt;ul&gt; 
     &lt;li&gt;Six different views of the execution of &quot;Hello, World!&quot; show what is often missing in today&apos;s tools&lt;/li&gt; 
     &lt;li&gt;ACM Queue 16, 5 (2018); Richard L. Sites&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://queue.acm.org/detail.cfm?id=3291278&quot;&gt;https://queue.acm.org/detail.cfm?id=3291278&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;KUtrace 2020 
    &lt;ul&gt; 
     &lt;li&gt;Stanford EE380 Computer Systems Colloquium (2020); Dick Sites&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=2HE7tSZGna0&quot;&gt;https://www.youtube.com/watch?v=2HE7tSZGna0&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://ee.stanford.edu/event/seminar/ee380-computer-systems-colloquium-presents-kutrace-2020&quot;&gt;https://ee.stanford.edu/event/seminar/ee380-computer-systems-colloquium-presents-kutrace-2020&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;ltrace: Debugging program to track runtime library calls in dynamically linked programs 
  &lt;ul&gt; 
   &lt;li&gt;ltrace intercepts and records dynamic library calls which are called by an executed process and the signals received by that process. It can also intercept and print the system calls executed by the program.&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://ltrace.org/&quot;&gt;http://ltrace.org/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://gitlab.com/cespedes/ltrace&quot;&gt;https://gitlab.com/cespedes/ltrace&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;How does ltrace work? - &lt;a href=&quot;https://blog.packagecloud.io/eng/2016/03/14/how-does-ltrace-work/&quot;&gt;https://blog.packagecloud.io/eng/2016/03/14/how-does-ltrace-work/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;StackTrack — Linux Call graph visualization and execution tracking 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://stacktrack.github.io/&quot;&gt;https://stacktrack.github.io/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;uftrace: Function (graph) tracer for user-space 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/namhyung/uftrace&quot;&gt;https://github.com/namhyung/uftrace&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Understanding the runtime behaviors of C++ programs using uftrace tool 
    &lt;ul&gt; 
     &lt;li&gt;CppCon 2017; Honggyu Kim&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=s0B8hV2O8ps&quot;&gt;https://www.youtube.com/watch?v=s0B8hV2O8ps&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Software: Linux - BCC/BPF&lt;/h3&gt; 
&lt;h4&gt;Software: Linux - BCC/BPF - Readings&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;Dive into BPF: a list of reading material 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://qmonnet.github.io/whirl-offload/2016/09/01/dive-into-bpf/&quot;&gt;https://qmonnet.github.io/whirl-offload/2016/09/01/dive-into-bpf/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;The BSD Packet Filter 
  &lt;ul&gt; 
   &lt;li&gt;USENIX Winter 1993; Steven McCanne and Van Jacobson&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.usenix.org/conference/usenix-winter-1993-conference/presentation/bsd-packet-filter-new-architecture-user-level-&quot;&gt;https://www.usenix.org/conference/usenix-winter-1993-conference/presentation/bsd-packet-filter-new-architecture-user-level-&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;PWL 2017 talk by Suchakra Sharma 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://speakerdeck.com/tuxology/the-bsd-packet-filter&quot;&gt;https://speakerdeck.com/tuxology/the-bsd-packet-filter&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;http://step.polymtl.ca/~suchakra/PWL-Jun28-MTL.pdf&quot;&gt;http://step.polymtl.ca/~suchakra/PWL-Jun28-MTL.pdf&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;Notes on BPF &amp;amp; eBPF - &lt;a href=&quot;https://jvns.ca/blog/2017/06/28/notes-on-bpf---ebpf/&quot;&gt;https://jvns.ca/blog/2017/06/28/notes-on-bpf---ebpf/&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;BPF and XDP Reference Guide 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;http://docs.cilium.io/en/stable/bpf/&quot;&gt;http://docs.cilium.io/en/stable/bpf/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Brendan D. Gregg 
  &lt;ul&gt; 
   &lt;li&gt;Linux Enhanced BPF (eBPF) Tracing Tools - &lt;a href=&quot;http://www.brendangregg.com/ebpf.html&quot;&gt;http://www.brendangregg.com/ebpf.html&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;BPF Performance Tools: Linux System and Application Observability 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;http://www.brendangregg.com/bpf-performance-tools-book.html&quot;&gt;http://www.brendangregg.com/bpf-performance-tools-book.html&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://github.com/brendangregg/bpf-perf-tools-book&quot;&gt;https://github.com/brendangregg/bpf-perf-tools-book&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Ferris Ellis 
  &lt;ul&gt; 
   &lt;li&gt;eBPF, part 1: Past, Present, and Future - &lt;a href=&quot;https://ferrisellis.com/content/ebpf_past_present_future/&quot;&gt;https://ferrisellis.com/content/ebpf_past_present_future/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;eBPF, part 2: Syscall and Map Types - &lt;a href=&quot;https://ferrisellis.com/content/ebpf_syscall_and_maps/&quot;&gt;https://ferrisellis.com/content/ebpf_syscall_and_maps/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Linux Tracing Workshops Materials - Sasha Goldshtein 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/goldshtn/linux-tracing-workshop&quot;&gt;https://github.com/goldshtn/linux-tracing-workshop&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Software: Linux - BCC/BPF - Software&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;BPFtrace: High-level tracing language for Linux eBPF 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/iovisor/bpftrace&quot;&gt;https://github.com/iovisor/bpftrace&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://www.brendangregg.com/blog/2018-10-08/dtrace-for-linux-2018.html&quot;&gt;http://www.brendangregg.com/blog/2018-10-08/dtrace-for-linux-2018.html&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;BCC - Tools for BPF-based Linux IO analysis, networking, monitoring, and more 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;http://iovisor.github.io/bcc/&quot;&gt;http://iovisor.github.io/bcc/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/iovisor/bcc&quot;&gt;https://github.com/iovisor/bcc&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.iovisor.org/technology/bcc&quot;&gt;https://www.iovisor.org/technology/bcc&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/iovisor/bcc/blob/master/LINKS.md&quot;&gt;https://github.com/iovisor/bcc/blob/master/LINKS.md&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;uBPF: Userspace eBPF VM 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/iovisor/ubpf&quot;&gt;https://github.com/iovisor/ubpf&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;ply: Dynamic Tracing in Linux 
  &lt;ul&gt; 
   &lt;li&gt;A light-weight dynamic tracer for Linux that leverages the kernel&apos;s BPF VM in concert with kprobes and tracepoints to attach probes to arbitrary points in the kernel.&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://wkz.github.io/ply/&quot;&gt;https://wkz.github.io/ply/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/iovisor/ply&quot;&gt;https://github.com/iovisor/ply&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Software: Linux - BCC/BPF - Talks&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;Tools and mechanisms to debug BPF programs 
  &lt;ul&gt; 
   &lt;li&gt;FOSDEM 2020; Quentin Monnet&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://fosdem.org/2020/schedule/event/debugging_bpf/&quot;&gt;https://fosdem.org/2020/schedule/event/debugging_bpf/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Software: Linux - ftrace&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;Ftrace - &lt;a href=&quot;https://alex.dzyoba.com/blog/ftrace/&quot;&gt;https://alex.dzyoba.com/blog/ftrace/&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;Ftrace: The hidden light switch - &lt;a href=&quot;https://lwn.net/Articles/608497/&quot;&gt;https://lwn.net/Articles/608497/&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;ftrace: Where modifying a running kernel all started 
  &lt;ul&gt; 
   &lt;li&gt;Kernel Recipes 2019; Steven Rostedt&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=93uE_kWWQjs&quot;&gt;https://www.youtube.com/watch?v=93uE_kWWQjs&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Debugging realtime application with Ftrace 
  &lt;ul&gt; 
   &lt;li&gt;FOSDEM 2018; Pierre Ficheux&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://fosdem.org/2018/schedule/event/debugging_tools_ftrace/&quot;&gt;https://fosdem.org/2018/schedule/event/debugging_tools_ftrace/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Hooking Linux Kernel Functions 
  &lt;ul&gt; 
   &lt;li&gt;Part 1: Looking for the Perfect Solution - &lt;a href=&quot;https://www.apriorit.com/dev-blog/544-hooking-linux-functions-1&quot;&gt;https://www.apriorit.com/dev-blog/544-hooking-linux-functions-1&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Part 2: How to Hook Functions with Ftrace - &lt;a href=&quot;https://www.apriorit.com/dev-blog/546-hooking-linux-functions-2&quot;&gt;https://www.apriorit.com/dev-blog/546-hooking-linux-functions-2&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Part 3: What Are the Main Pros and Cons of Ftrace? - &lt;a href=&quot;https://www.apriorit.com/dev-blog/547-hooking-linux-functions-3&quot;&gt;https://www.apriorit.com/dev-blog/547-hooking-linux-functions-3&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;ftrace-hook: Linux kernel module demonstrating usage of ftrace framework for function hooking 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://github.com/ilammy/ftrace-hook&quot;&gt;https://github.com/ilammy/ftrace-hook&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;KernelShark 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;http://rostedt.homelinux.com/kernelshark/&quot;&gt;http://rostedt.homelinux.com/kernelshark/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Using KernelShark to analyze the real-time scheduler - &lt;a href=&quot;https://lwn.net/Articles/425583/&quot;&gt;https://lwn.net/Articles/425583/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;KernelShark 1.0; What’s new and what’s coming - &lt;a href=&quot;https://kernel-recipes.org/en/2018/talks/kernelshark-1-0-whats-new-and-whats-coming/&quot;&gt;https://kernel-recipes.org/en/2018/talks/kernelshark-1-0-whats-new-and-whats-coming/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;perf-tools: Performance analysis tools based on Linux perf_events (aka perf) and ftrace 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/brendangregg/perf-tools&quot;&gt;https://github.com/brendangregg/perf-tools&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Tracing the Linux kernel with ftrace 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://embeddedbits.org/tracing-the-linux-kernel-with-ftrace/&quot;&gt;https://embeddedbits.org/tracing-the-linux-kernel-with-ftrace/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Understanding the Linux Kernel via Ftrace - Kernel Recipes 2017 - Steven Rostedt 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://kernel-recipes.org/en/2017/talks/understanding-the-linux-kernel-via-ftrace/&quot;&gt;https://kernel-recipes.org/en/2017/talks/understanding-the-linux-kernel-via-ftrace/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=2ff-7UTg5rE&quot;&gt;https://www.youtube.com/watch?v=2ff-7UTg5rE&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;See what your computer is doing with Ftrace utilities 
  &lt;ul&gt; 
   &lt;li&gt;linux.conf.au 2019; Steven Rostedt&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=68osT1soAPM&quot;&gt;https://www.youtube.com/watch?v=68osT1soAPM&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://2019.linux.conf.au/schedule/presentation/130/&quot;&gt;https://2019.linux.conf.au/schedule/presentation/130/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Software: Linux - LTTng&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;LTTng: Linux Trace Toolkit Next Generation 
  &lt;ul&gt; 
   &lt;li&gt;an open source tracing framework for Linux&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://lttng.org/&quot;&gt;https://lttng.org/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/lttng&quot;&gt;https://github.com/lttng&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;LTTng analyses: Analyses scripts for LTTng kernel and user-space traces 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/lttng/lttng-analyses&quot;&gt;https://github.com/lttng/lttng-analyses&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;LTTng live streaming example 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;http://pavelmakhov.com/2017/01/lttng-streaming&quot;&gt;http://pavelmakhov.com/2017/01/lttng-streaming&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Software: Linux - ptrace&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;ptrace - process trace - &lt;a href=&quot;http://man7.org/linux/man-pages/man2/ptrace.2.html&quot;&gt;http://man7.org/linux/man-pages/man2/ptrace.2.html&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;Adventures into ptrace(2) Hell - &lt;a href=&quot;https://www.cyphar.com/blog/post/20160703-remainroot-ptrace-hell&quot;&gt;https://www.cyphar.com/blog/post/20160703-remainroot-ptrace-hell&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;DetTrace: A Reproducible Container Abstraction 
  &lt;ul&gt; 
   &lt;li&gt;A determinizing tracer using Ptrace&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/dettrace/dettrace&quot;&gt;https://github.com/dettrace/dettrace&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Reproducible Containers 
    &lt;ul&gt; 
     &lt;li&gt;Architectural Support for Programming Languages and Operating Systems (ASPLOS) 2020&lt;/li&gt; 
     &lt;li&gt;Omar S. Navarro Leija, Kelly Shiptoski, Ryan G. Scott, Baojun Wang, Nicholas Renner, Ryan R. Newton, Joseph Devietti&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://doi.org/10.1145/3373376.3378519&quot;&gt;https://doi.org/10.1145/3373376.3378519&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://gatowololo.github.io/resources/publications/dettrace.pdf&quot;&gt;https://gatowololo.github.io/resources/publications/dettrace.pdf&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=YkmS-vf12nE&quot;&gt;https://www.youtube.com/watch?v=YkmS-vf12nE&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Hiding Call To Ptrace - &lt;a href=&quot;https://github.com/yellowbyte/analysis-of-anti-analysis/blob/master/research/hiding_call_to_ptrace/hiding_call_to_ptrace.md&quot;&gt;https://github.com/yellowbyte/analysis-of-anti-analysis/blob/master/research/hiding_call_to_ptrace/hiding_call_to_ptrace.md&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;Intercepting and Emulating Linux System Calls with Ptrace - &lt;a href=&quot;http://nullprogram.com/blog/2018/06/23/&quot;&gt;http://nullprogram.com/blog/2018/06/23/&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;Ptrace-burrito: A plugin style wrapper around ptrace on Linux. 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/brainsmoke/ptrace-burrito&quot;&gt;https://github.com/brainsmoke/ptrace-burrito&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Using Ptrace For Fun And Profit 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://eklitzke.org/ptrace&quot;&gt;https://eklitzke.org/ptrace&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://eklitzke.org/ptrace-continued&quot;&gt;https://eklitzke.org/ptrace-continued&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Using ptrace(2) To Call a Userspace Function: Example of how to use the ptrace(2) system call to call a userspace method. 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://github.com/eklitzke/ptrace-call-userspace&quot;&gt;https://github.com/eklitzke/ptrace-call-userspace&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Software: Linux - strace&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;strace - the linux syscall tracer 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/strace/strace&quot;&gt;https://github.com/strace/strace&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Strace little book 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/NanXiao/strace-little-book&quot;&gt;https://github.com/NanXiao/strace-little-book&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://nanxiao.gitbooks.io/strace-little-book/&quot;&gt;https://nanxiao.gitbooks.io/strace-little-book/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Julia Evans 
  &lt;ul&gt; 
   &lt;li&gt;A zine about strace 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://jvns.ca/blog/2015/04/14/strace-zine/&quot;&gt;https://jvns.ca/blog/2015/04/14/strace-zine/&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://wizardzines.com/zines/strace/&quot;&gt;https://wizardzines.com/zines/strace/&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;strace posts: &lt;a href=&quot;https://jvns.ca/categories/strace/&quot;&gt;https://jvns.ca/categories/strace/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;How does strace work? 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://blog.packagecloud.io/eng/2016/02/29/how-does-strace-work/&quot;&gt;https://blog.packagecloud.io/eng/2016/02/29/how-does-strace-work/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;My Favourite Secret Weapon – strace 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://zwischenzugs.com/2011/08/29/my-favourite-secret-weapon-strace/&quot;&gt;https://zwischenzugs.com/2011/08/29/my-favourite-secret-weapon-strace/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Strace -- The Sysadmin&apos;s Microscope 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://blogs.oracle.com/ksplice/strace-the-sysadmins-microscope&quot;&gt;https://blogs.oracle.com/ksplice/strace-the-sysadmins-microscope&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;strace cheat sheet 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://blog.packagecloud.io/eng/2015/11/15/strace-cheat-sheet/&quot;&gt;https://blog.packagecloud.io/eng/2015/11/15/strace-cheat-sheet/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Strace: The Lost Chapter 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;http://price.mit.edu/blog/2010/08/strace-the-lost-chapter/&quot;&gt;http://price.mit.edu/blog/2010/08/strace-the-lost-chapter/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Software: Linux - strace - Talks&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;strace talks 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/strace/strace-talks&quot;&gt;https://github.com/strace/strace-talks&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Modern strace 
  &lt;ul&gt; 
   &lt;li&gt;DevConf.CZ 2019; Dmitry Levin&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=cwDFpzQuWSU&quot;&gt;https://www.youtube.com/watch?v=cwDFpzQuWSU&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://devconfcz2019.sched.com/event/JchD&quot;&gt;https://devconfcz2019.sched.com/event/JchD&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Postmodern strace 
  &lt;ul&gt; 
   &lt;li&gt;FOSDEM 2020; Dmitry Levin&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://fosdem.org/2020/schedule/event/debugging_strace_modern/&quot;&gt;https://fosdem.org/2020/schedule/event/debugging_strace_modern/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;strace --seccomp-bpf: a look under the hood 
  &lt;ul&gt; 
   &lt;li&gt;FOSDEM 2020; Paul Chaignon&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://fosdem.org/2020/schedule/event/debugging_strace_bpf/&quot;&gt;https://fosdem.org/2020/schedule/event/debugging_strace_bpf/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://pchaigno.github.io/strace/2019/10/02/introducing-strace-seccomp-bpf.html&quot;&gt;https://pchaigno.github.io/strace/2019/10/02/introducing-strace-seccomp-bpf.html&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Strace: Monitoring The Kernel-User-Space Conversation 
  &lt;ul&gt; 
   &lt;li&gt;NDC TechTown 2018; Michael Kerrisk&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=oFt6V56BOlo&quot;&gt;https://www.youtube.com/watch?v=oFt6V56BOlo&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://man7.org/conf/ndctechtown2018/system_call_tracing_with_strace-NDC-TechTown-Kerrisk.pdf&quot;&gt;http://man7.org/conf/ndctechtown2018/system_call_tracing_with_strace-NDC-TechTown-Kerrisk.pdf&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;strace: new features 
  &lt;ul&gt; 
   &lt;li&gt;FOSDEM 2018; Dmitry Levin&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://fosdem.org/2018/schedule/event/debugging_tools_strace_features/&quot;&gt;https://fosdem.org/2018/schedule/event/debugging_tools_strace_features/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Software: Windows&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;ATrace: a tool for tracing execution of binaries on Windows 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/K2/EhTrace&quot;&gt;https://github.com/K2/EhTrace&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Branch Monitoring Project 
  &lt;ul&gt; 
   &lt;li&gt;Branch Monitor is an alternative for runtime process monitoring on modern (Windows) systems. Our approach makes use of Branch Trace Store (BTS) from Intel&apos;s processors to implement a dynamic, transparent framework. The framework provide many analysis facilities, such as function call tracing and Control Flow Graph (CFG) reconstruction.&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/marcusbotacin/BranchMonitoringProject&quot;&gt;https://github.com/marcusbotacin/BranchMonitoringProject&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;DIMCT: Dirty Inter Module Calls Tracer 
  &lt;ul&gt; 
   &lt;li&gt;Allows tracing inter module calls for a specific module within a Windows process.&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/amossys/dimct&quot;&gt;https://github.com/amossys/dimct&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;libptrace: An event driven multi-core process debugging, tracing, and manipulation framework 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/immunityinc/libptrace&quot;&gt;https://github.com/immunityinc/libptrace&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;MemTrace: Memory Tracing Software 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/deplinenoise/ig-memtrace&quot;&gt;https://github.com/deplinenoise/ig-memtrace&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;tiny_tracer: A Pin Tool for tracing API calls and transition between sections of the traced module 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/hasherezade/tiny_tracer&quot;&gt;https://github.com/hasherezade/tiny_tracer&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Tracing executables with a Pin Tool (tiny_tracer) - &lt;a href=&quot;https://www.youtube.com/watch?v=kurzaoWuSHA&quot;&gt;https://www.youtube.com/watch?v=kurzaoWuSHA&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;tracectory: a tool to analyze and visualize x86 instruction traces 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://bitbucket.org/oebeling/tracectory/wiki/Home&quot;&gt;https://bitbucket.org/oebeling/tracectory/wiki/Home&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://bling.kapsi.fi/blog/x86-memory-access-visualization.html&quot;&gt;https://bling.kapsi.fi/blog/x86-memory-access-visualization.html&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;WinIPT: The Windows Library for Intel Process Trace 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://ionescu007.github.io/winipt/&quot;&gt;https://ionescu007.github.io/winipt/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/ionescu007/winipt&quot;&gt;https://github.com/ionescu007/winipt&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Software: Windows - ETW&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;ETW Central 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://randomascii.wordpress.com/2015/09/24/etw-central/&quot;&gt;https://randomascii.wordpress.com/2015/09/24/etw-central/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;etrace: Command-line tool for ETW tracing on files and real-time events 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/goldshtn/etrace&quot;&gt;https://github.com/goldshtn/etrace&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;EtwConsumerNT 
  &lt;ul&gt; 
   &lt;li&gt;Simple project that demonstrates how an ETW consumer can be created just by using NTDLL&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/wbenny/EtwConsumerNT&quot;&gt;https://github.com/wbenny/EtwConsumerNT&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;KrabsETW: a modern C++ wrapper and a .NET wrapper around the low-level ETW trace consumption functions 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/microsoft/krabsetw&quot;&gt;https://github.com/microsoft/krabsetw&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;LiveStacks: Collect, aggregate, and display live stack traces for ETW events, including CPU sampling, of native and .NET processes. 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/goldshtn/LiveStacks&quot;&gt;https://github.com/goldshtn/LiveStacks&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Hidden Treasure: Detecting Intrusions with ETW 
  &lt;ul&gt; 
   &lt;li&gt;Derbycon 2017; Zac Brown&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://www.irongeek.com/i.php?page=videos/derbycon7/t208-hidden-treasure-detecting-intrusions-with-etw-zac-brown&quot;&gt;http://www.irongeek.com/i.php?page=videos/derbycon7/t208-hidden-treasure-detecting-intrusions-with-etw-zac-brown&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;UIforETW: User interface for recording and managing ETW traces 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://randomascii.wordpress.com/2015/04/14/uiforetw-windows-performance-made-easier/&quot;&gt;https://randomascii.wordpress.com/2015/04/14/uiforetw-windows-performance-made-easier/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/google/UIforETW&quot;&gt;https://github.com/google/UIforETW&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;wtrace: Command line tracing tool for Windows, based on ETW 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/lowleveldesign/wtrace&quot;&gt;https://github.com/lowleveldesign/wtrace&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://lowleveldesign.org/2017/10/25/wtrace-2-2/&quot;&gt;https://lowleveldesign.org/2017/10/25/wtrace-2-2/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;hr&gt; 
&lt;h1&gt;Talks&lt;/h1&gt; 
&lt;ul&gt; 
 &lt;li&gt;Tracing Summit - &lt;a href=&quot;http://tracingsummit.org/&quot;&gt;http://tracingsummit.org/&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;2017&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;Now You See Me Too: Visual Tooling for Advanced System Analysis 
  &lt;ul&gt; 
   &lt;li&gt;LISA 2017; Suchakrapani Sharma&lt;/li&gt; 
   &lt;li&gt;Video: &lt;a href=&quot;https://www.youtube.com/watch?v=ihauGhgWZgQ&quot;&gt;https://www.youtube.com/watch?v=ihauGhgWZgQ&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Slides (Speaker Deck): &lt;a href=&quot;https://speakerdeck.com/tuxology/visual-tooling-for-advanced-systems-analysis&quot;&gt;https://speakerdeck.com/tuxology/visual-tooling-for-advanced-systems-analysis&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Slides (PDF): &lt;a href=&quot;http://step.polymtl.ca/~suchakra/LISA-Nov2-SF.pdf&quot;&gt;http://step.polymtl.ca/~suchakra/LISA-Nov2-SF.pdf&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;2016&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;Designing Tracing Tools 
  &lt;ul&gt; 
   &lt;li&gt;Sysdig CCWFS 2016; Brendan Gregg&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=uibLwoVKjec&quot;&gt;https://www.youtube.com/watch?v=uibLwoVKjec&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://www.slideshare.net/brendangregg/designing-tracing-tools-67693476&quot;&gt;http://www.slideshare.net/brendangregg/designing-tracing-tools-67693476&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Give me 15 minutes and I&apos;ll change your view of Linux tracing 
  &lt;ul&gt; 
   &lt;li&gt;USENIX/LISA 2016; Brendan Gregg&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=GsMs3n8CB6g&quot;&gt;https://www.youtube.com/watch?v=GsMs3n8CB6g&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Low-Level Tracing for Latency Analysis: From Baremetal to Hardware Tracing Blocks 
  &lt;ul&gt; 
   &lt;li&gt;Tracing Summit 2016&lt;/li&gt; 
   &lt;li&gt;Suchakrapani Datt Sharma (Ecole Polytechnique Montreal)&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=D1nggb9OgD0&quot;&gt;https://www.youtube.com/watch?v=D1nggb9OgD0&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://tracingsummit.org/wiki/TracingSummit2016LowLevelTracing&quot;&gt;http://tracingsummit.org/wiki/TracingSummit2016LowLevelTracing&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://hsdm.dorsal.polymtl.ca/system/files/Suchakra-tracingsummit2016.pdf&quot;&gt;https://hsdm.dorsal.polymtl.ca/system/files/Suchakra-tracingsummit2016.pdf&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Using Linux tracing tools 
  &lt;ul&gt; 
   &lt;li&gt;O&apos;Reilly Velocity Conference 2016; Sasha Goldshtein&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.oreilly.com/learning/using-linux-tracing-tools&quot;&gt;https://www.oreilly.com/learning/using-linux-tracing-tools&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;2014&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;What is That Process Doing? 
  &lt;ul&gt; 
   &lt;li&gt;Greg Price&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://price.mit.edu/tracing-w2014/&quot;&gt;http://price.mit.edu/tracing-w2014/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Open Source Bridge 2013 - &lt;a href=&quot;https://www.youtube.com/watch?v=kYIDMIekgyU&quot;&gt;https://www.youtube.com/watch?v=kYIDMIekgyU&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Software Engineering at Google</title>
      <link>https://tedneward.github.io/Research/reading/development/swe-at-google/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">reading/development/swe-at-google/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book&quot;&gt;Website&lt;/a&gt; | Online-available&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/pr01.html&quot;&gt;Preface&lt;/a&gt;&lt;/p&gt; 
  &lt;ol&gt; 
   &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/pr01.html#programming_over_time&quot;&gt;Programming Over Time&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/pr01.html#googleapostrophes_perspective&quot;&gt;Google’s Perspective&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/pr01.html#what_this_book_isnapostrophet&quot;&gt;What This Book Isn’t&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/pr01.html#parting_remarks&quot;&gt;Parting Remarks&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/pr01.html#_conventions_used_in_this_book&quot;&gt;Conventions Used in This Book&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/pr01.html#_safari_books_online&quot;&gt;O&apos;Reilly Online Learning&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/pr01.html#_how_to_contact_us&quot;&gt;How to Contact Us&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/pr01.html#_acknowledgments&quot;&gt;Acknowledgments&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
  &lt;/ol&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/part1.html&quot;&gt;Thesis&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch01.html&quot;&gt;What Is Software Engineering?&lt;/a&gt;&lt;/p&gt; 
  &lt;ol&gt; 
   &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch01.html#time_and_change&quot;&gt;Time and Change&lt;/a&gt; 
    &lt;ol&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch01.html#hyrumapostrophes_law&quot;&gt;Hyrum’s Law&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch01.html#example_hash_ordering&quot;&gt;Example: Hash Ordering&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch01.html#why_not_just_aim_for_quotation_marknoth&quot;&gt;Why Not Just Aim for “Nothing Changes”?&lt;/a&gt;&lt;/li&gt; 
    &lt;/ol&gt; &lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch01.html#scale_and_efficiency&quot;&gt;Scale and Efficiency&lt;/a&gt; 
    &lt;ol&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch01.html#policies_that_donapostrophet_scale&quot;&gt;Policies That Don’t Scale&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch01.html#policies_that_scale_well&quot;&gt;Policies That Scale Well&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch01.html#example_compiler_upgrade&quot;&gt;Example: Compiler Upgrade&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch01.html#shifting_left&quot;&gt;Shifting Left&lt;/a&gt;&lt;/li&gt; 
    &lt;/ol&gt; &lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch01.html#tradeoffs_and_costs&quot;&gt;Trade-offs and Costs&lt;/a&gt; 
    &lt;ol&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch01.html#example_markers&quot;&gt;Example: Markers&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch01.html#inputs_to_decision_making&quot;&gt;Inputs to Decision Making&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch01.html#example_distributed_builds&quot;&gt;Example: Distributed Builds&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch01.html#example_deciding_between_time_and_scale&quot;&gt;Example: Deciding Between Time and Scale&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch01.html#revisiting_decisionscomma_making_mistak&quot;&gt;Revisiting Decisions, Making Mistakes&lt;/a&gt;&lt;/li&gt; 
    &lt;/ol&gt; &lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch01.html#software_engineering_versus_programming&quot;&gt;Software Engineering Versus Programming&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch01.html#conclusion&quot;&gt;Conclusion&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch01.html#tlsemicolondr&quot;&gt;TL;DRs&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
  &lt;/ol&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/part2.html&quot;&gt;Culture&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch02.html&quot;&gt;How to Work Well on Teams&lt;/a&gt;&lt;/p&gt; 
  &lt;ol&gt; 
   &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch02.html#help_me_hide_my_code&quot;&gt;Help Me Hide My Code&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch02.html#the_genius_myth&quot;&gt;The Genius Myth&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch02.html#hiding_considered_harmful&quot;&gt;Hiding Considered Harmful&lt;/a&gt;&lt;/p&gt; 
    &lt;ol&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch02.html#early_detection&quot;&gt;Early Detection&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch02.html#the_bus_factor&quot;&gt;The Bus Factor&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch02.html#pace_of_progress&quot;&gt;Pace of Progress&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch02.html#in_shortcomma_donapostrophet_hide&quot;&gt;In Short, Don’t Hide&lt;/a&gt;&lt;/li&gt; 
    &lt;/ol&gt; &lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch02.html#itapostrophes_all_about_the_team&quot;&gt;It’s All About the Team&lt;/a&gt; 
    &lt;ol&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch02.html#the_three_pillars_of_social_interaction&quot;&gt;The Three Pillars of Social Interaction&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch02.html#why_do_these_pillars_matterquestion_mar&quot;&gt;Why Do These Pillars Matter?&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch02.html#humilitycomma_respectcomma_and_trust_in&quot;&gt;Humility, Respect, and Trust in Practice&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch02.html#blameless_postmortem_culture&quot;&gt;Blameless Post-Mortem Culture&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch02.html#being_googley&quot;&gt;Being Googley&lt;/a&gt;&lt;/li&gt; 
    &lt;/ol&gt; &lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch02.html#conclusion-id00006&quot;&gt;Conclusion&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch02.html#tlsemicolondr-id00171&quot;&gt;TL;DRs&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
  &lt;/ol&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch03.html&quot;&gt;Knowledge Sharing&lt;/a&gt;&lt;/p&gt; 
  &lt;ol&gt; 
   &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch03.html#challenges_to_learning&quot;&gt;Challenges to Learning&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch03.html#philosophy&quot;&gt;Philosophy&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch03.html#setting_the_stage_psychological_safety&quot;&gt;Setting the Stage: Psychological Safety&lt;/a&gt;&lt;/p&gt; 
    &lt;ol&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch03.html#mentorship&quot;&gt;Mentorship&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch03.html#psychological_safety_in_large_groups&quot;&gt;Psychological Safety in Large Groups&lt;/a&gt;&lt;/li&gt; 
    &lt;/ol&gt; &lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch03.html#growing_your_knowledge&quot;&gt;Growing Your Knowledge&lt;/a&gt; 
    &lt;ol&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch03.html#ask_questions&quot;&gt;Ask Questions&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch03.html#understand_context&quot;&gt;Understand Context&lt;/a&gt;&lt;/li&gt; 
    &lt;/ol&gt; &lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch03.html#scaling_your_questions_ask_the_communit&quot;&gt;Scaling Your Questions: Ask the Community&lt;/a&gt; 
    &lt;ol&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch03.html#group_chats&quot;&gt;Group Chats&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch03.html#mailing_lists&quot;&gt;Mailing Lists&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch03.html#yaqs_question_and_answer_platform&quot;&gt;YAQS: Question-and-Answer Platform&lt;/a&gt;&lt;/li&gt; 
    &lt;/ol&gt; &lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch03.html#scaling_your_knowledge_you_always_have&quot;&gt;Scaling Your Knowledge: You Always Have Something to Teach&lt;/a&gt; 
    &lt;ol&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch03.html#office_hours&quot;&gt;Office Hours&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch03.html#tech_talks_and_classes&quot;&gt;Tech Talks and Classes&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch03.html#documentation-id00039&quot;&gt;Documentation&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch03.html#code&quot;&gt;Code&lt;/a&gt;&lt;/li&gt; 
    &lt;/ol&gt; &lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch03.html#scaling_your_organizationapostrophes_kn&quot;&gt;Scaling Your Organization’s Knowledge&lt;/a&gt; 
    &lt;ol&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch03.html#cultivating_a_knowledge-sharing_culture&quot;&gt;Cultivating a Knowledge-Sharing Culture&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch03.html#establishing_canonical_sources_of_infor&quot;&gt;Establishing Canonical Sources of Information&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch03.html#staying_in_the_loop&quot;&gt;Staying in the Loop&lt;/a&gt;&lt;/li&gt; 
    &lt;/ol&gt; &lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch03.html#readability_standardized_mentorship_thr&quot;&gt;Readability: Standardized Mentorship Through Code Review&lt;/a&gt; 
    &lt;ol&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch03.html#what_is_the_readability_processquestion&quot;&gt;What Is the Readability Process?&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch03.html#why_have_this_processquestion_mark&quot;&gt;Why Have This Process?&lt;/a&gt;&lt;/li&gt; 
    &lt;/ol&gt; &lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch03.html#conclusion-id00007&quot;&gt;Conclusion&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch03.html#tlsemicolondrs-id00101&quot;&gt;TL;DRs&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
  &lt;/ol&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch04.html&quot;&gt;Engineering for Equity&lt;/a&gt;&lt;/p&gt; 
  &lt;ol&gt; 
   &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch04.html#bias_is_the_default&quot;&gt;Bias Is the Default&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch04.html#understanding_the_need_for_diversity&quot;&gt;Understanding the Need for Diversity&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch04.html#building_multicultural_capacity&quot;&gt;Building Multicultural Capacity&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch04.html#making_diversity_actionable&quot;&gt;Making Diversity Actionable&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch04.html#reject_singular_approaches&quot;&gt;Reject Singular Approaches&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch04.html#challenge_established_processes&quot;&gt;Challenge Established Processes&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch04.html#values_versus_outcomes&quot;&gt;Values Versus Outcomes&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch04.html#stay_curiouscomma_push_forward&quot;&gt;Stay Curious, Push Forward&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch04.html#conclusion-id00008&quot;&gt;Conclusion&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch04.html#tlsemicolondrs-id00103&quot;&gt;TL;DRs&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
  &lt;/ol&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch05.html&quot;&gt;How to Lead a Team&lt;/a&gt;&lt;/p&gt; 
  &lt;ol&gt; 
   &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch05.html#managers_and_tech_leads_left_parenthesi&quot;&gt;Managers and Tech Leads (and Both)&lt;/a&gt; 
    &lt;ol&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch05.html#the_engineering_manager&quot;&gt;The Engineering Manager&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch05.html#the_tech_lead&quot;&gt;The Tech Lead&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch05.html#the_tech_lead_manager&quot;&gt;The Tech Lead Manager&lt;/a&gt;&lt;/li&gt; 
    &lt;/ol&gt; &lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch05.html#moving_from_an_individual_contributor_r&quot;&gt;Moving from an Individual Contributor Role to a Leadership Role&lt;/a&gt; 
    &lt;ol&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch05.html#the_only_thing_to_fear_issemicolonwellc&quot;&gt;The Only Thing to Fear Is…Well, Everything&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch05.html#servant_leadership&quot;&gt;Servant Leadership&lt;/a&gt;&lt;/li&gt; 
    &lt;/ol&gt; &lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch05.html#the_engineering_manage&quot;&gt;The Engineering Manager&lt;/a&gt; 
    &lt;ol&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch05.html#manager_is_a_four-letter_word&quot;&gt;Manager Is a Four-Letter Word&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch05.html#todayapostrophes_engineering_manager&quot;&gt;Today’s Engineering Manager&lt;/a&gt;&lt;/li&gt; 
    &lt;/ol&gt; &lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch05.html#antipatterns&quot;&gt;Antipatterns&lt;/a&gt; 
    &lt;ol&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch05.html#antipattern_hire_pushovers&quot;&gt;Antipattern: Hire Pushovers&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch05.html#antipattern_ignore_low_performers&quot;&gt;Antipattern: Ignore Low Performers&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch05.html#antipattern_ignore_human_issues&quot;&gt;Antipattern: Ignore Human Issues&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch05.html#antipattern_be_everyoneapostrophes_frie&quot;&gt;Antipattern: Be Everyone’s Friend&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch05.html#antipattern_compromise_the_hiring_bar&quot;&gt;Antipattern: Compromise the Hiring Bar&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch05.html#antipattern_treat_your_team_like_childr&quot;&gt;Antipattern: Treat Your Team Like Children&lt;/a&gt;&lt;/li&gt; 
    &lt;/ol&gt; &lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch05.html#positive_patterns&quot;&gt;Positive Patterns&lt;/a&gt; 
    &lt;ol&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch05.html#lose_the_ego-id00072&quot;&gt;Lose the Ego&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch05.html#be_a_zen_master&quot;&gt;Be a Zen Master&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch05.html#be_a_catalyst&quot;&gt;Be a Catalyst&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch05.html#remove_roadblocks&quot;&gt;Remove Roadblocks&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch05.html#be_a_teacher_and_a_mentor&quot;&gt;Be a Teacher and a Mentor&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch05.html#set_clear_goals&quot;&gt;Set Clear Goals&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch05.html#be_honest&quot;&gt;Be Honest&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch05.html#track_happiness&quot;&gt;Track Happiness&lt;/a&gt;&lt;/li&gt; 
    &lt;/ol&gt; &lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch05.html#the_unexpected_question&quot;&gt;The Unexpected Question&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch05.html#other_tips_and_tricks&quot;&gt;Other Tips and Tricks&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch05.html#people_are_like_plants&quot;&gt;People Are Like Plants&lt;/a&gt;&lt;/p&gt; 
    &lt;ol&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch05.html#intrinsic_versus_extrinsic_motivation&quot;&gt;Intrinsic Versus Extrinsic Motivation&lt;/a&gt;&lt;/li&gt; 
    &lt;/ol&gt; &lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch05.html#conclusion-id00009&quot;&gt;Conclusion&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch05.html#tlsemicolondrs&quot;&gt;TL;DRs&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
  &lt;/ol&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch06.html&quot;&gt;Leading at Scale&lt;/a&gt;&lt;/p&gt; 
  &lt;ol&gt; 
   &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch06.html#always_be_deciding&quot;&gt;Always Be Deciding&lt;/a&gt; 
    &lt;ol&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch06.html#the_parable_of_the_airplane&quot;&gt;The Parable of the Airplane&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch06.html#identify_the_blinders&quot;&gt;Identify the Blinders&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch06.html#identify_the_key_trade-offs&quot;&gt;Identify the Key Trade-Offs&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch06.html#decidecomma_then_iterate&quot;&gt;Decide, Then Iterate&lt;/a&gt;&lt;/li&gt; 
    &lt;/ol&gt; &lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch06.html#always_be_leaving&quot;&gt;Always Be Leaving&lt;/a&gt; 
    &lt;ol&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch06.html#your_mission_build_a_quotation_markself&quot;&gt;Your Mission: Build a “Self-Driving” Team&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch06.html#dividing_the_problem_space&quot;&gt;Dividing the Problem Space&lt;/a&gt;&lt;/li&gt; 
    &lt;/ol&gt; &lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch06.html#always_be_scaling&quot;&gt;Always Be Scaling&lt;/a&gt; 
    &lt;ol&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch06.html#the_cycle_of_success&quot;&gt;The Cycle of Success&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch06.html#important_versus_urgent&quot;&gt;Important Versus Urgent&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch06.html#learn_to_drop_balls&quot;&gt;Learn to Drop Balls&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch06.html#protecting_your_energy&quot;&gt;Protecting Your Energy&lt;/a&gt;&lt;/li&gt; 
    &lt;/ol&gt; &lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch06.html#conclusion-id00010&quot;&gt;Conclusion&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch06.html#tlsemicolondrs-id00106&quot;&gt;TL;DRs&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
  &lt;/ol&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch07.html&quot;&gt;Measuring Engineering Productivity&lt;/a&gt;&lt;/p&gt; 
  &lt;ol&gt; 
   &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch07.html#why_should_we_measure_engineering_produ&quot;&gt;Why Should We Measure Engineering Productivity?&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch07.html#triage_is_it_even_worth_measuringquesti&quot;&gt;Triage: Is It Even Worth Measuring?&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch07.html#selecting_meaningful_metrics_with_goals&quot;&gt;Selecting Meaningful Metrics with Goals and Signals&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch07.html#goals&quot;&gt;Goals&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch07.html#signals&quot;&gt;Signals&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch07.html#metrics&quot;&gt;Metrics&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch07.html#using_data_to_validate_metrics&quot;&gt;Using Data to Validate Metrics&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch07.html#taking_action_and_tracking_results&quot;&gt;Taking Action and Tracking Results&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch07.html#conclusion-id00011&quot;&gt;Conclusion&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch07.html#tlsemicolondrs-id00108&quot;&gt;TL;DRs&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
  &lt;/ol&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/part3.html&quot;&gt;Processes&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch08.html&quot;&gt;Style Guides and Rules&lt;/a&gt;&lt;/p&gt; 
  &lt;ol&gt; 
   &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch08.html#why_have_rulesquestion_mark&quot;&gt;Why Have Rules?&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch08.html#creating_the_rules&quot;&gt;Creating the Rules&lt;/a&gt;&lt;/p&gt; 
    &lt;ol&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch08.html#guiding_principles&quot;&gt;Guiding Principles&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch08.html#the_style_guide&quot;&gt;The Style Guide&lt;/a&gt;&lt;/li&gt; 
    &lt;/ol&gt; &lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch08.html#changing_the_rules&quot;&gt;Changing the Rules&lt;/a&gt; 
    &lt;ol&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch08.html#the_process&quot;&gt;The Process&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch08.html#the_style_arbiters&quot;&gt;The Style Arbiters&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch08.html#exceptions&quot;&gt;Exceptions&lt;/a&gt;&lt;/li&gt; 
    &lt;/ol&gt; &lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch08.html#guidance&quot;&gt;Guidance&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch08.html#applying_the_rules&quot;&gt;Applying the Rules&lt;/a&gt;&lt;/p&gt; 
    &lt;ol&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch08.html#error_checkers&quot;&gt;Error Checkers&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch08.html#code_formatters&quot;&gt;Code Formatters&lt;/a&gt;&lt;/li&gt; 
    &lt;/ol&gt; &lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch08.html#conclusion-id00012&quot;&gt;Conclusion&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch08.html#tlsemicolondrs-id00109&quot;&gt;TL;DRs&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
  &lt;/ol&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch09.html&quot;&gt;Code Review&lt;/a&gt;&lt;/p&gt; 
  &lt;ol&gt; 
   &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch09.html#code_review_flow-id00005&quot;&gt;Code Review Flow&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch09.html#how_code_review_works_at_google&quot;&gt;How Code Review Works at Google&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch09.html#code_review_benefits&quot;&gt;Code Review Benefits&lt;/a&gt;&lt;/p&gt; 
    &lt;ol&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch09.html#code_correctness&quot;&gt;Code Correctness&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch09.html#comprehension_of_code&quot;&gt;Comprehension of Code&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch09.html#code_consistency&quot;&gt;Code Consistency&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch09.html#psychological_and_cultural_benefits&quot;&gt;Psychological and Cultural Benefits&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch09.html#knowledge_sharing-id00052&quot;&gt;Knowledge Sharing&lt;/a&gt;&lt;/li&gt; 
    &lt;/ol&gt; &lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch09.html#code_review_best_practices&quot;&gt;Code Review Best Practices&lt;/a&gt; 
    &lt;ol&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch09.html#be_polite_and_professional&quot;&gt;Be Polite and Professional&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch09.html#write_small_changes&quot;&gt;Write Small Changes&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch09.html#write_good_change_descriptions&quot;&gt;Write Good Change Descriptions&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch09.html#keep_reviewers_to_a_minimum&quot;&gt;Keep Reviewers to a Minimum&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch09.html#automate_where_possible&quot;&gt;Automate Where Possible&lt;/a&gt;&lt;/li&gt; 
    &lt;/ol&gt; &lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch09.html#types_of_code_reviews&quot;&gt;Types of Code Reviews&lt;/a&gt; 
    &lt;ol&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch09.html#greenfield_code_reviews&quot;&gt;Greenfield Code Reviews&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch09.html#behavioral_changescomma_improvementscom&quot;&gt;Behavioral Changes, Improvements, and Optimizations&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch09.html#bug_fixes_and_rollbacks&quot;&gt;Bug Fixes and Rollbacks&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch09.html#refactorings_and_large-scale_changes&quot;&gt;Refactorings and Large-Scale Changes&lt;/a&gt;&lt;/li&gt; 
    &lt;/ol&gt; &lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch09.html#conclusion-id00013&quot;&gt;Conclusion&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch09.html#tlsemicolondrs-id00110&quot;&gt;TL;DRs&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
  &lt;/ol&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch10.html&quot;&gt;Documentation&lt;/a&gt;&lt;/p&gt; 
  &lt;ol&gt; 
   &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch10.html#what_qualifies_as_documentationquestion&quot;&gt;What Qualifies as Documentation?&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch10.html#why_is_documentation_neededquestion_mar&quot;&gt;Why Is Documentation Needed?&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch10.html#documentation_is_like_code&quot;&gt;Documentation Is Like Code&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch10.html#know_your_audience&quot;&gt;Know Your Audience&lt;/a&gt;&lt;/p&gt; 
    &lt;ol&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch10.html#types_of_audiences&quot;&gt;Types of Audiences&lt;/a&gt;&lt;/li&gt; 
    &lt;/ol&gt; &lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch10.html#documentation_types&quot;&gt;Documentation Types&lt;/a&gt; 
    &lt;ol&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch10.html#reference_documentation&quot;&gt;Reference Documentation&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch10.html#design_docs&quot;&gt;Design Docs&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch10.html#tutorials&quot;&gt;Tutorials&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch10.html#conceptual_documentation&quot;&gt;Conceptual Documentation&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch10.html#landing_pages&quot;&gt;Landing Pages&lt;/a&gt;&lt;/li&gt; 
    &lt;/ol&gt; &lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch10.html#documentation_reviews&quot;&gt;Documentation Reviews&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch10.html#documentation_philosophy&quot;&gt;Documentation Philosophy&lt;/a&gt;&lt;/p&gt; 
    &lt;ol&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch10.html#whocomma_whatcomma_whencomma_wherecomma&quot;&gt;WHO, WHAT, WHEN, WHERE, and WHY&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch10.html#the_beginningcomma_middlecomma_and_end&quot;&gt;The Beginning, Middle, and End&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch10.html#the_parameters_of_good_documentation&quot;&gt;The Parameters of Good Documentation&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch10.html#deprecating_documents&quot;&gt;Deprecating Documents&lt;/a&gt;&lt;/li&gt; 
    &lt;/ol&gt; &lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch10.html#when_do_you_need_technical_writersquest&quot;&gt;When Do You Need Technical Writers?&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch10.html#conclusion-id00014&quot;&gt;Conclusion&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch10.html#tlsemicolondrs-id00112&quot;&gt;TL;DRs&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
  &lt;/ol&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch11.html&quot;&gt;Testing Overview&lt;/a&gt;&lt;/p&gt; 
  &lt;ol&gt; 
   &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch11.html#why_do_we_write_testsquestion_mark&quot;&gt;Why Do We Write Tests?&lt;/a&gt; 
    &lt;ol&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch11.html#the_story_of_google_web_server&quot;&gt;The Story of Google Web Server&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch11.html#testing_at_the_speed_of_modern_developm&quot;&gt;Testing at the Speed of Modern Development&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch11.html#writecomma_runcomma_react&quot;&gt;Write, Run, React&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch11.html#benefits_of_testing_code&quot;&gt;Benefits of Testing Code&lt;/a&gt;&lt;/li&gt; 
    &lt;/ol&gt; &lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch11.html#designing_a_test_suite&quot;&gt;Designing a Test Suite&lt;/a&gt; 
    &lt;ol&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch11.html#test_size&quot;&gt;Test Size&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch11.html#test_scope&quot;&gt;Test Scope&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch11.html#the_beyonceacutesemicolon_rule&quot;&gt;The Beyoncé Rule&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch11.html#a_note_on_code_coverage&quot;&gt;A Note on Code Coverage&lt;/a&gt;&lt;/li&gt; 
    &lt;/ol&gt; &lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch11.html#testing_at_google_scale&quot;&gt;Testing at Google Scale&lt;/a&gt; 
    &lt;ol&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch11.html#the_pitfalls_of_a_large_test_suite&quot;&gt;The Pitfalls of a Large Test Suite&lt;/a&gt;&lt;/li&gt; 
    &lt;/ol&gt; &lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch11.html#history_of_testing_at_google&quot;&gt;History of Testing at Google&lt;/a&gt; 
    &lt;ol&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch11.html#orientation_classes&quot;&gt;Orientation Classes&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch11.html#test_certified&quot;&gt;Test Certified&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch11.html#testing_on_the_toilet&quot;&gt;Testing on the Toilet&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch11.html#testing_culture_today&quot;&gt;Testing Culture Today&lt;/a&gt;&lt;/li&gt; 
    &lt;/ol&gt; &lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch11.html#the_limits_of_automated_testing&quot;&gt;The Limits of Automated Testing&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch11.html#conclusion-id00015&quot;&gt;Conclusion&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch11.html#tlsemicolondrs-id00113&quot;&gt;TL;DRs&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
  &lt;/ol&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch12.html&quot;&gt;Unit Testing&lt;/a&gt;&lt;/p&gt; 
  &lt;ol&gt; 
   &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch12.html#the_importance_of_maintainability&quot;&gt;The Importance of Maintainability&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch12.html#preventing_brittle_tests&quot;&gt;Preventing Brittle Tests&lt;/a&gt;&lt;/p&gt; 
    &lt;ol&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch12.html#strive_for_unchanging_tests&quot;&gt;Strive for Unchanging Tests&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch12.html#test_via_public_apis&quot;&gt;Test via Public APIs&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch12.html#test_statecomma_not_interactions&quot;&gt;Test State, Not Interactions&lt;/a&gt;&lt;/li&gt; 
    &lt;/ol&gt; &lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch12.html#writing_clear_tests&quot;&gt;Writing Clear Tests&lt;/a&gt; 
    &lt;ol&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch12.html#make_your_tests_complete_and_concise&quot;&gt;Make Your Tests Complete and Concise&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch12.html#test_behaviorscomma_not_methods&quot;&gt;Test Behaviors, Not Methods&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch12.html#donapostrophet_put_logic_in_tests&quot;&gt;Don’t Put Logic in Tests&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch12.html#write_clear_failure_messages&quot;&gt;Write Clear Failure Messages&lt;/a&gt;&lt;/li&gt; 
    &lt;/ol&gt; &lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch12.html#tests_and_code_sharing_dampcomma_not_dr&quot;&gt;Tests and Code Sharing: DAMP, Not DRY&lt;/a&gt; 
    &lt;ol&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch12.html#shared_values&quot;&gt;Shared Values&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch12.html#shared_setup&quot;&gt;Shared Setup&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch12.html#shared_helpers_and_validation&quot;&gt;Shared Helpers and Validation&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch12.html#defining_test_infrastructure&quot;&gt;Defining Test Infrastructure&lt;/a&gt;&lt;/li&gt; 
    &lt;/ol&gt; &lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch12.html#conclusion-id00016&quot;&gt;Conclusion&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch12.html#tlsemicolondrs-id00114&quot;&gt;TL;DRs&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
  &lt;/ol&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch13.html&quot;&gt;Test Doubles&lt;/a&gt;&lt;/p&gt; 
  &lt;ol&gt; 
   &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch13.html#the_impact_of_test_doubles_on_software&quot;&gt;The Impact of Test Doubles on Software Development&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch13.html#test_doubles_at_google&quot;&gt;Test Doubles at Google&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch13.html#basic_concepts&quot;&gt;Basic Concepts&lt;/a&gt;&lt;/p&gt; 
    &lt;ol&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch13.html#an_example_test_double&quot;&gt;An Example Test Double&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch13.html#seams&quot;&gt;Seams&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch13.html#mocking_frameworks&quot;&gt;Mocking Frameworks&lt;/a&gt;&lt;/li&gt; 
    &lt;/ol&gt; &lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch13.html#techniques_for_using_test_doubles&quot;&gt;Techniques for Using Test Doubles&lt;/a&gt; 
    &lt;ol&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch13.html#faking-id00042&quot;&gt;Faking&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch13.html#stubbing-id00089&quot;&gt;Stubbing&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch13.html#interaction_testing&quot;&gt;Interaction Testing&lt;/a&gt;&lt;/li&gt; 
    &lt;/ol&gt; &lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch13.html#real_implementations&quot;&gt;Real Implementations&lt;/a&gt; 
    &lt;ol&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch13.html#prefer_realism_over_isolation&quot;&gt;Prefer Realism Over Isolation&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch13.html#how_to_decide_when_to_use_a_real_implem&quot;&gt;How to Decide When to Use a Real Implementation&lt;/a&gt;&lt;/li&gt; 
    &lt;/ol&gt; &lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch13.html#faking-id00043&quot;&gt;Faking&lt;/a&gt; 
    &lt;ol&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch13.html#why_are_fakes_importantquestion_mark&quot;&gt;Why Are Fakes Important?&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch13.html#when_should_fakes_be_writtenquestion_ma&quot;&gt;When Should Fakes Be Written?&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch13.html#the_fidelity_of_fakes&quot;&gt;The Fidelity of Fakes&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch13.html#fakes_should_be_tested&quot;&gt;Fakes Should Be Tested&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch13.html#what_to_do_if_a_fake_is_not_available&quot;&gt;What to Do If a Fake Is Not Available&lt;/a&gt;&lt;/li&gt; 
    &lt;/ol&gt; &lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch13.html#stubbing-id00091&quot;&gt;Stubbing&lt;/a&gt; 
    &lt;ol&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch13.html#the_dangers_of_overusing_stubbing&quot;&gt;The Dangers of Overusing Stubbing&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch13.html#when_is_stubbing_appropriatequestion_ma&quot;&gt;When Is Stubbing Appropriate?&lt;/a&gt;&lt;/li&gt; 
    &lt;/ol&gt; &lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch13.html#interaction_testing-id00047&quot;&gt;Interaction Testing&lt;/a&gt; 
    &lt;ol&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch13.html#prefer_state_testing_over_interaction_t&quot;&gt;Prefer State Testing Over Interaction Testing&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch13.html#when_is_interaction_testing_appropriate&quot;&gt;When Is Interaction Testing Appropriate?&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch13.html#best_practices_for_interaction_testing&quot;&gt;Best Practices for Interaction Testing&lt;/a&gt;&lt;/li&gt; 
    &lt;/ol&gt; &lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch13.html#conclusion-id00017&quot;&gt;Conclusion&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch13.html#tlsemicolondrs-id00116&quot;&gt;TL;DRs&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
  &lt;/ol&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch14.html&quot;&gt;Larger Testing&lt;/a&gt;&lt;/p&gt; 
  &lt;ol&gt; 
   &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch14.html#what_are_larger_testsquestion_mark&quot;&gt;What Are Larger Tests?&lt;/a&gt; 
    &lt;ol&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch14.html#fidelity&quot;&gt;Fidelity&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch14.html#common_gaps_in_unit_tests&quot;&gt;Common Gaps in Unit Tests&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch14.html#why_not_have_larger_testsquestion_mark&quot;&gt;Why Not Have Larger Tests?&lt;/a&gt;&lt;/li&gt; 
    &lt;/ol&gt; &lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch14.html#larger_tests_at_google&quot;&gt;Larger Tests at Google&lt;/a&gt; 
    &lt;ol&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch14.html#larger_tests_and_time&quot;&gt;Larger Tests and Time&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch14.html#larger_tests_at_google_scale&quot;&gt;Larger Tests at Google Scale&lt;/a&gt;&lt;/li&gt; 
    &lt;/ol&gt; &lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch14.html#structure_of_a_large_test&quot;&gt;Structure of a Large Test&lt;/a&gt; 
    &lt;ol&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch14.html#the_system_under_test&quot;&gt;The System Under Test&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch14.html#test_data&quot;&gt;Test Data&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch14.html#verification&quot;&gt;Verification&lt;/a&gt;&lt;/li&gt; 
    &lt;/ol&gt; &lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch14.html#types_of_larger_tests&quot;&gt;Types of Larger Tests&lt;/a&gt; 
    &lt;ol&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch14.html#functional_testing_of_one_or_more_inter&quot;&gt;Functional Testing of One or More Interacting Binaries&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch14.html#browser_and_device_testing&quot;&gt;Browser and Device Testing&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch14.html#performancecomma_loadcomma_and_stress_t&quot;&gt;Performance, Load, and Stress testing&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch14.html#deployment_configuration_testing&quot;&gt;Deployment Configuration Testing&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch14.html#exploratory_testing&quot;&gt;Exploratory Testing&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch14.html#asolidusb_diff_regression_testing&quot;&gt;A/B Diff Regression Testing&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch14.html#uat&quot;&gt;UAT&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch14.html#probers_and_canary_analysis&quot;&gt;Probers and Canary Analysis&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch14.html#disaster_recovery_and_chaos_engineering&quot;&gt;Disaster Recovery and Chaos Engineering&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch14.html#user_evaluation&quot;&gt;User Evaluation&lt;/a&gt;&lt;/li&gt; 
    &lt;/ol&gt; &lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch14.html#large_tests_and_the_developer_workflow&quot;&gt;Large Tests and the Developer Workflow&lt;/a&gt; 
    &lt;ol&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch14.html#authoring_large_tests&quot;&gt;Authoring Large Tests&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch14.html#running_large_tests&quot;&gt;Running Large Tests&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch14.html#owning_large_tests&quot;&gt;Owning Large Tests&lt;/a&gt;&lt;/li&gt; 
    &lt;/ol&gt; &lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch14.html#conclusion-id00018&quot;&gt;Conclusion&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch14.html#tlsemicolondrs-id00118&quot;&gt;TL;DRs&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
  &lt;/ol&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch15.html&quot;&gt;Deprecation&lt;/a&gt;&lt;/p&gt; 
  &lt;ol&gt; 
   &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch15.html#why_deprecatequestion_mark&quot;&gt;Why Deprecate?&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch15.html#why_is_deprecation_so_hardquestion_mark&quot;&gt;Why Is Deprecation So Hard?&lt;/a&gt;&lt;/p&gt; 
    &lt;ol&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch15.html#deprecation_during_design&quot;&gt;Deprecation During Design&lt;/a&gt;&lt;/li&gt; 
    &lt;/ol&gt; &lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch15.html#types_of_deprecation&quot;&gt;Types of Deprecation&lt;/a&gt; 
    &lt;ol&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch15.html#advisory_deprecation&quot;&gt;Advisory Deprecation&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch15.html#compulsory_deprecation&quot;&gt;Compulsory Deprecation&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch15.html#deprecation_warnings&quot;&gt;Deprecation Warnings&lt;/a&gt;&lt;/li&gt; 
    &lt;/ol&gt; &lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch15.html#managing_the_deprecation_process&quot;&gt;Managing the Deprecation Process&lt;/a&gt; 
    &lt;ol&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch15.html#process_owners&quot;&gt;Process Owners&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch15.html#milestones&quot;&gt;Milestones&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch15.html#deprecation_tooling&quot;&gt;Deprecation Tooling&lt;/a&gt;&lt;/li&gt; 
    &lt;/ol&gt; &lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch15.html#conclusion-id00019&quot;&gt;Conclusion&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch15.html#tlsemicolondrs-id00120&quot;&gt;TL;DRs&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
  &lt;/ol&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/part4.html&quot;&gt;Tools&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch16.html&quot;&gt;Version Control and Branch Management&lt;/a&gt;&lt;/p&gt; 
  &lt;ol&gt; 
   &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch16.html#what_is_version_controlquestion_markone&quot;&gt;What Is Version Control?&lt;/a&gt; 
    &lt;ol&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch16.html#why_is_version_control_importantquestio&quot;&gt;Why Is Version Control Important?&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch16.html#centralized_vcs_versus_distributed_vcs&quot;&gt;Centralized VCS Versus Distributed VCS&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch16.html#source_of_truth&quot;&gt;Source of Truth&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch16.html#version_control_versus_dependency_manag&quot;&gt;Version Control Versus Dependency Management&lt;/a&gt;&lt;/li&gt; 
    &lt;/ol&gt; &lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch16.html#branch_management&quot;&gt;Branch Management&lt;/a&gt; 
    &lt;ol&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch16.html#work_in_progress_is_akin_to_a_branch&quot;&gt;Work in Progress Is Akin to a Branch&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch16.html#dev_branches&quot;&gt;Dev Branches&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch16.html#release_branches&quot;&gt;Release Branches&lt;/a&gt;&lt;/li&gt; 
    &lt;/ol&gt; &lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch16.html#version_control_at_google&quot;&gt;Version Control at Google&lt;/a&gt; 
    &lt;ol&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch16.html#one_version&quot;&gt;One Version&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch16.html#scenario_multiple_available_versions&quot;&gt;Scenario: Multiple Available Versions&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch16.html#the_quotation_markone_versionquotation&quot;&gt;The “One-Version” Rule&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch16.html#left_parenthesisnearlyright_parenthesis&quot;&gt;(Nearly) No Long-Lived Branches&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch16.html#what_about_release_branchesquestion_mar&quot;&gt;What About Release Branches?&lt;/a&gt;&lt;/li&gt; 
    &lt;/ol&gt; &lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch16.html#monorepos&quot;&gt;Monorepos&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch16.html#future_of_version_control&quot;&gt;Future of Version Control&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch16.html#conclusion-id00020&quot;&gt;Conclusion&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch16.html#tlsemicolondrs-id00122&quot;&gt;TL;DRs&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
  &lt;/ol&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch17.html&quot;&gt;Code Search&lt;/a&gt;&lt;/p&gt; 
  &lt;ol&gt; 
   &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch17.html#the_code_search_u&quot;&gt;The Code Search UI&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch17.html#how_do_googlers_use_code_searchquestion&quot;&gt;How Do Googlers Use Code Search?&lt;/a&gt;&lt;/p&gt; 
    &lt;ol&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch17.html#wherequestion_mark&quot;&gt;Where?&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch17.html#whatquestion_mark&quot;&gt;What?&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch17.html#howquestion_mark&quot;&gt;How?&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch17.html#whyquestion_mark&quot;&gt;Why?&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch17.html#who_and_whenquestion_mark&quot;&gt;Who and When?&lt;/a&gt;&lt;/li&gt; 
    &lt;/ol&gt; &lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch17.html#why_a_separate_web_toolquestion_mark&quot;&gt;Why a Separate Web Tool?&lt;/a&gt; 
    &lt;ol&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch17.html#scale&quot;&gt;Scale&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch17.html#zero_setup_global_code_view&quot;&gt;Zero Setup Global Code View&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch17.html#specialization&quot;&gt;Specialization&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch17.html#integration_with_other_developer_tools&quot;&gt;Integration with Other Developer Tools&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch17.html#api_exposure&quot;&gt;API Exposure&lt;/a&gt;&lt;/li&gt; 
    &lt;/ol&gt; &lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch17.html#impact_of_scale_on_design&quot;&gt;Impact of Scale on Design&lt;/a&gt; 
    &lt;ol&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch17.html#search_query_latency&quot;&gt;Search Query Latency&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch17.html#index_latency&quot;&gt;Index Latency&lt;/a&gt;&lt;/li&gt; 
    &lt;/ol&gt; &lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch17.html#googleapostrophes_implementation&quot;&gt;Google’s Implementation&lt;/a&gt; 
    &lt;ol&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch17.html#search_index&quot;&gt;Search Index&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch17.html#ranking&quot;&gt;Ranking&lt;/a&gt;&lt;/li&gt; 
    &lt;/ol&gt; &lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch17.html#selected_trade-offs&quot;&gt;Selected Trade-Offs&lt;/a&gt; 
    &lt;ol&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch17.html#completeness_repository_at_head&quot;&gt;Completeness: Repository at Head&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch17.html#completeness_all_versus_most-relevant_r&quot;&gt;Completeness: All Versus Most-Relevant Results&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch17.html#completeness_head_versus_branches_versu&quot;&gt;Completeness: Head Versus Branches Versus All History Versus Workspaces&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch17.html#expressiveness_token_versus_substring_v&quot;&gt;Expressiveness: Token Versus Substring Versus Regex&lt;/a&gt;&lt;/li&gt; 
    &lt;/ol&gt; &lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch17.html#conclusion-id00021&quot;&gt;Conclusion&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch17.html#tlsemicolondrs-id00123&quot;&gt;TL;DRs&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
  &lt;/ol&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch18.html&quot;&gt;Build Systems and Build Philosophy&lt;/a&gt;&lt;/p&gt; 
  &lt;ol&gt; 
   &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch18.html#purpose_of_a_build_system&quot;&gt;Purpose of a Build System&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch18.html#what_happens_without_a_build_systemques&quot;&gt;What Happens Without a Build System?&lt;/a&gt;&lt;/p&gt; 
    &lt;ol&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch18.html#but_all_i_need_is_a_compilerexclamation&quot;&gt;But All I Need Is a Compiler!&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch18.html#shell_scripts_to_the_rescuequestion_mar&quot;&gt;Shell Scripts to the Rescue?&lt;/a&gt;&lt;/li&gt; 
    &lt;/ol&gt; &lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch18.html#modern_build_systems&quot;&gt;Modern Build Systems&lt;/a&gt; 
    &lt;ol&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch18.html#itapostrophes_all_about_dependencies&quot;&gt;It’s All About Dependencies&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch18.html#task-based_build_systems&quot;&gt;Task-Based Build Systems&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch18.html#artifact-based_build_systems&quot;&gt;Artifact-Based Build Systems&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch18.html#distributed_builds&quot;&gt;Distributed Builds&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch18.html#timecomma_scalecomma_trade-offs&quot;&gt;Time, Scale, Trade-Offs&lt;/a&gt;&lt;/li&gt; 
    &lt;/ol&gt; &lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch18.html#dealing_with_modules_and_dependencies&quot;&gt;Dealing with Modules and Dependencies&lt;/a&gt; 
    &lt;ol&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch18.html#using_fine-grained_modules_and_the_oneo&quot;&gt;Using Fine-Grained Modules and the 1:1:1 Rule&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch18.html#minimizing_module_visibility&quot;&gt;Minimizing Module Visibility&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch18.html#managing_dependencies&quot;&gt;Managing Dependencies&lt;/a&gt;&lt;/li&gt; 
    &lt;/ol&gt; &lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch18.html#conclusion-id00022&quot;&gt;Conclusion&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch18.html#tlsemicolondrs-id00124&quot;&gt;TL;DRs&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
  &lt;/ol&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch19.html&quot;&gt;Critique: Google’s Code Review Tool&lt;/a&gt;&lt;/p&gt; 
  &lt;ol&gt; 
   &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch19.html#code_review_tooling_principles&quot;&gt;Code Review Tooling Principles&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch19.html#code_review_flow&quot;&gt;Code Review Flow&lt;/a&gt;&lt;/p&gt; 
    &lt;ol&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch19.html#notifications&quot;&gt;Notifications&lt;/a&gt;&lt;/li&gt; 
    &lt;/ol&gt; &lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch19.html#stage_one_creating_a_change&quot;&gt;Stage 1: Create a Change&lt;/a&gt; 
    &lt;ol&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch19.html#diffing&quot;&gt;Diffing&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch19.html#analysis_results-id00001&quot;&gt;Analysis Results&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch19.html#tight_tool_integration&quot;&gt;Tight Tool Integration&lt;/a&gt;&lt;/li&gt; 
    &lt;/ol&gt; &lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch19.html#stage_two_request_review&quot;&gt;Stage 2: Request Review&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch19.html#stage_three_and_four_understanding_and&quot;&gt;Stages 3 and 4: Understanding and Commenting on a Change&lt;/a&gt;&lt;/p&gt; 
    &lt;ol&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch19.html#commenting&quot;&gt;Commenting&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch19.html#understanding_the_state_of_a_change&quot;&gt;Understanding the State of a Change&lt;/a&gt;&lt;/li&gt; 
    &lt;/ol&gt; &lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch19.html#stage_five_change_approvals_left_parent&quot;&gt;Stage 5: Change Approvals (Scoring a Change)&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch19.html#stage_six_commiting_a_change&quot;&gt;Stage 6: Committing a Change&lt;/a&gt;&lt;/p&gt; 
    &lt;ol&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch19.html#after_commit_tracking_history&quot;&gt;After Commit: Tracking History&lt;/a&gt;&lt;/li&gt; 
    &lt;/ol&gt; &lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch19.html#conclusion-id00023&quot;&gt;Conclusion&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch19.html#tlsemicolondrs-id00125&quot;&gt;TL;DRs&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
  &lt;/ol&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch20.html&quot;&gt;Static Analysis&lt;/a&gt;&lt;/p&gt; 
  &lt;ol&gt; 
   &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch20.html#characteristics_of_effective_static_ana&quot;&gt;Characteristics of Effective Static Analysis&lt;/a&gt; 
    &lt;ol&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch20.html#scalability&quot;&gt;Scalability&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch20.html#usability&quot;&gt;Usability&lt;/a&gt;&lt;/li&gt; 
    &lt;/ol&gt; &lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch20.html#key_lessons_in_making_static_analysis_w&quot;&gt;Key Lessons in Making Static Analysis Work&lt;/a&gt; 
    &lt;ol&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch20.html#focus_on_developer_happiness&quot;&gt;Focus on Developer Happiness&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch20.html#make_static_analysis_a_part_of_the_core&quot;&gt;Make Static Analysis a Part of the Core Developer Workflow&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch20.html#empower_users_to_contribute&quot;&gt;Empower Users to Contribute&lt;/a&gt;&lt;/li&gt; 
    &lt;/ol&gt; &lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch20.html#tricorder_googleapostrophes_static_anal&quot;&gt;Tricorder: Google’s Static Analysis Platform&lt;/a&gt; 
    &lt;ol&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch20.html#integrated_tools&quot;&gt;Integrated Tools&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch20.html#integrated_feedback_channels&quot;&gt;Integrated Feedback Channels&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch20.html#suggested_fixes&quot;&gt;Suggested Fixes&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch20.html#per-project_customization&quot;&gt;Per-Project Customization&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch20.html#presubmits&quot;&gt;Presubmits&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch20.html#compiler_integration&quot;&gt;Compiler Integration&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch20.html#analysis_while_editing_and_browsing_cod&quot;&gt;Analysis While Editing and Browsing Code&lt;/a&gt;&lt;/li&gt; 
    &lt;/ol&gt; &lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch20.html#conclusion-id00024&quot;&gt;Conclusion&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch20.html#tlsemicolondrs-id00126&quot;&gt;TL;DRs&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
  &lt;/ol&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch21.html&quot;&gt;Dependency Management&lt;/a&gt;&lt;/p&gt; 
  &lt;ol&gt; 
   &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch21.html#why_is_dependency_management_so_difficu&quot;&gt;Why Is Dependency Management So Difficult?&lt;/a&gt; 
    &lt;ol&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch21.html#conflicting_requirements_and_diamond_de&quot;&gt;Conflicting Requirements and Diamond Dependencies&lt;/a&gt;&lt;/li&gt; 
    &lt;/ol&gt; &lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch21.html#importing_dependencies&quot;&gt;Importing Dependencies&lt;/a&gt; 
    &lt;ol&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch21.html#compatibility_promises&quot;&gt;Compatibility Promises&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch21.html#considerations_when_importing&quot;&gt;Considerations When Importing&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch21.html#how_google_handles_importing_dependende&quot;&gt;How Google Handles Importing Dependencies&lt;/a&gt;&lt;/li&gt; 
    &lt;/ol&gt; &lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch21.html#dependency_managementcomma_in_theory&quot;&gt;Dependency Management, In Theory&lt;/a&gt; 
    &lt;ol&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch21.html#nothing_changes_left_parenthesisaka_the&quot;&gt;Nothing Changes (aka The Static Dependency Model)&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch21.html#semantic_versioning&quot;&gt;Semantic Versioning&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch21.html#bundled_distribution_models&quot;&gt;Bundled Distribution Models&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch21.html#live_at_head&quot;&gt;Live at Head&lt;/a&gt;&lt;/li&gt; 
    &lt;/ol&gt; &lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch21.html#the_limitations_of_semver&quot;&gt;The Limitations of SemVer&lt;/a&gt; 
    &lt;ol&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch21.html#semver_might_overconstrain&quot;&gt;SemVer Might Overconstrain&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch21.html#semver_might_overpromise&quot;&gt;SemVer Might Overpromise&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch21.html#motivations-id00080&quot;&gt;Motivations&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch21.html#minimum_version_selection&quot;&gt;Minimum Version Selection&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch21.html#socomma_does_semver_workquestion_mark&quot;&gt;So, Does SemVer Work?&lt;/a&gt;&lt;/li&gt; 
    &lt;/ol&gt; &lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch21.html#dependency_management_with_infinite_res&quot;&gt;Dependency Management with Infinite Resources&lt;/a&gt; 
    &lt;ol&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch21.html#exporting_dependencies&quot;&gt;Exporting Dependencies&lt;/a&gt;&lt;/li&gt; 
    &lt;/ol&gt; &lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch21.html#conclusion-id00025&quot;&gt;Conclusion&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch21.html#tlsemicolondrs-id00127&quot;&gt;TL;DRs&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
  &lt;/ol&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch22.html&quot;&gt;Large-Scale Changes&lt;/a&gt;&lt;/p&gt; 
  &lt;ol&gt; 
   &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch22.html#what_is_a_large-scale_changequestion_ma&quot;&gt;What Is a Large-Scale Change?&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch22.html#who_deals_with_lscsquestion_mark&quot;&gt;Who Deals with LSCs?&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch22.html#barriers_to_atomic_changes&quot;&gt;Barriers to Atomic Changes&lt;/a&gt;&lt;/p&gt; 
    &lt;ol&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch22.html#technical_limitations&quot;&gt;Technical Limitations&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch22.html#merge_conflicts&quot;&gt;Merge Conflicts&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch22.html#no_haunted_graveyards&quot;&gt;No Haunted Graveyards&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch22.html#heterogeneity&quot;&gt;Heterogeneity&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch22.html#testing-id00096&quot;&gt;Testing&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch22.html#code_review&quot;&gt;Code Review&lt;/a&gt;&lt;/li&gt; 
    &lt;/ol&gt; &lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch22.html#lsc_infrastructure&quot;&gt;LSC Infrastructure&lt;/a&gt; 
    &lt;ol&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch22.html#policies_and_culture&quot;&gt;Policies and Culture&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch22.html#codebase_insight&quot;&gt;Codebase Insight&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch22.html#change_management&quot;&gt;Change Management&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch22.html#testing&quot;&gt;Testing&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch22.html#language_support&quot;&gt;Language Support&lt;/a&gt;&lt;/li&gt; 
    &lt;/ol&gt; &lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch22.html#the_lsc_process&quot;&gt;The LSC Process&lt;/a&gt; 
    &lt;ol&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch22.html#authorization&quot;&gt;Authorization&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch22.html#change_creation&quot;&gt;Change Creation&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch22.html#sharding_and_submitting&quot;&gt;Sharding and Submitting&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch22.html#cleanup&quot;&gt;Cleanup&lt;/a&gt;&lt;/li&gt; 
    &lt;/ol&gt; &lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch22.html#conclusion-id00026&quot;&gt;Conclusion&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch22.html#tlsemicolondrs-id00128&quot;&gt;TL;DRs&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
  &lt;/ol&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch23.html&quot;&gt;Continuous Integration&lt;/a&gt;&lt;/p&gt; 
  &lt;ol&gt; 
   &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch23.html#ci_concepts&quot;&gt;CI Concepts&lt;/a&gt; 
    &lt;ol&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch23.html#fast_feedback_loops&quot;&gt;Fast Feedback Loops&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch23.html#automation&quot;&gt;Automation&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch23.html#continuous_testing&quot;&gt;Continuous Testing&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch23.html#ci_challenges&quot;&gt;CI Challenges&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch23.html#hermetic_testing&quot;&gt;Hermetic Testing&lt;/a&gt;&lt;/li&gt; 
    &lt;/ol&gt; &lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch23.html#ci_at_google&quot;&gt;CI at Google&lt;/a&gt; 
    &lt;ol&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch23.html#ci_case_study_google_takeout&quot;&gt;CI Case Study: Google Takeout&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch23.html#but_i_canapostrophet_afford_ci&quot;&gt;But I Can’t Afford CI&lt;/a&gt;&lt;/li&gt; 
    &lt;/ol&gt; &lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch23.html#conclusion-id00027&quot;&gt;Conclusion&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch23.html#tlsemicolondrs-id00129&quot;&gt;TL;DRs&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
  &lt;/ol&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch24.html&quot;&gt;Continuous Delivery&lt;/a&gt;&lt;/p&gt; 
  &lt;ol&gt; 
   &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch24.html#idioms_of_continuous_delivery_at_google&quot;&gt;Idioms of Continuous Delivery at Google&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch24.html#velocity_is_a_team_sport_how_to_break_u&quot;&gt;Velocity Is a Team Sport: How to Break Up a Deployment into Manageable Pieces&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch24.html#evaluating_changes_in_isolation_flag-gu&quot;&gt;Evaluating Changes in Isolation: Flag-Guarding Features&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch24.html#striving_for_agility_setting_up_a_relea&quot;&gt;Striving for Agility: Setting Up a Release Train&lt;/a&gt;&lt;/p&gt; 
    &lt;ol&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch24.html#no_binary_is_perfect&quot;&gt;No Binary Is Perfect&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch24.html#meet_your_release_deadline&quot;&gt;Meet Your Release Deadline&lt;/a&gt;&lt;/li&gt; 
    &lt;/ol&gt; &lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch24.html#quality_and_user-focus_ship_only_what_g&quot;&gt;Quality and User-Focus: Ship Only What Gets Used&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch24.html#shifting_left_making_data-driven_decisi&quot;&gt;Shifting Left: Making Data-Driven Decisions Earlier&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch24.html#changing_team_culture_building_discipli&quot;&gt;Changing Team Culture: Building Discipline into Deployment&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch24.html#conclusion-id00029&quot;&gt;Conclusion&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch24.html#tlsemicolondrs-id00130&quot;&gt;TL;DRs&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
  &lt;/ol&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch25.html&quot;&gt;Compute as a Service&lt;/a&gt;&lt;/p&gt; 
  &lt;ol&gt; 
   &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch25.html#taming_the_compute_environment&quot;&gt;Taming the Compute Environment&lt;/a&gt; 
    &lt;ol&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch25.html#automation_of_toil&quot;&gt;Automation of Toil&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch25.html#containerization_and_multitenancy&quot;&gt;Containerization and Multitenancy&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch25.html#summary&quot;&gt;Summary&lt;/a&gt;&lt;/li&gt; 
    &lt;/ol&gt; &lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch25.html#writing_software_for_managed_compute&quot;&gt;Writing Software for Managed Compute&lt;/a&gt; 
    &lt;ol&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch25.html#architecting_for_failure&quot;&gt;Architecting for Failure&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch25.html#batch_versus_serving&quot;&gt;Batch Versus Serving&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch25.html#managing_statetwosixthree&quot;&gt;Managing State&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch25.html#connecting_to_a_service&quot;&gt;Connecting to a Service&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch25.html#one-off_code&quot;&gt;One-Off Code&lt;/a&gt;&lt;/li&gt; 
    &lt;/ol&gt; &lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch25.html#caas_over_time_and_scale&quot;&gt;CaaS Over Time and Scale&lt;/a&gt; 
    &lt;ol&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch25.html#containers_as_an_abstraction&quot;&gt;Containers as an Abstraction&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch25.html#one_service_to_rule_them_all&quot;&gt;One Service to Rule Them All&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch25.html#submitted_configuration&quot;&gt;Submitted Configuration&lt;/a&gt;&lt;/li&gt; 
    &lt;/ol&gt; &lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch25.html#choosing_a_compute_service&quot;&gt;Choosing a Compute Service&lt;/a&gt; 
    &lt;ol&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch25.html#centralization_versus_customization&quot;&gt;Centralization Versus Customization&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch25.html#level_of_abstraction_serverless&quot;&gt;Level of Abstraction: Serverless&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch25.html#public_versus_private&quot;&gt;Public Versus Private&lt;/a&gt;&lt;/li&gt; 
    &lt;/ol&gt; &lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch25.html#conclusion-id00030&quot;&gt;Conclusion&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/ch25.html#tlsemicolondrs-id00131&quot;&gt;TL;DRs&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
  &lt;/ol&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book/html/part5.html&quot;&gt;Conclusion&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Economist: International Relations A to Z</title>
      <link>https://tedneward.github.io/Research/reading/economist-a-z/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">reading/economist-a-z/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.economist.com/international-relations-a-to-z&quot;&gt;Page&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Technical debt</title>
      <link>https://tedneward.github.io/Research/reading/development/technical-debt/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">reading/development/technical-debt/index.html</guid>
      	<description>
	&lt;p&gt;Technical debt is the implied cost of rework caused by choosing an easier, quicker solution now instead of a better approach that would take longer. While it can speed up initial delivery, this &quot;debt&quot; slows down future development, increases costs, and lowers software quality over time, similar to financial debt. It can be incurred intentionally for short-term gains or unintentionally through poor practices, and includes issues like inadequate code, design, or documentation.&lt;/p&gt; 
&lt;p&gt;Causes of technical debt:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Intentional shortcuts: Making a quick decision to meet a deadline, even if a better but longer solution exists.&lt;/li&gt; 
 &lt;li&gt;Unintentional mistakes: Inexperienced developers, poor architectural choices, or insufficient knowledge can lead to debt.&lt;/li&gt; 
 &lt;li&gt;Insufficient documentation: Lack of documentation makes it difficult for others to understand and maintain the code.&lt;/li&gt; 
 &lt;li&gt;Lack of refactoring: Not regularly addressing and improving existing code can lead to it becoming outdated and difficult to manage.&lt;/li&gt; 
 &lt;li&gt;Rapid changes: Unforeseen or last-minute changes to features can introduce bugs and complexities that are not properly addressed.&lt;/li&gt; 
 &lt;li&gt;Pressure to minimize development time/schedule pressure&lt;/li&gt; 
 &lt;li&gt;Unexpected and ill-defined features and changes: The implementation of last-minute specification changes or changes that are insufficiently documented or tested&lt;/li&gt; 
 &lt;li&gt;Gaps in knowledge or skills. May manifest as a lack of process understanding, insufficient knowledge, poor technological leadership, or inadequate mentoring or knowledge sharing practices.&lt;/li&gt; 
 &lt;li&gt;Issues in the development process: Such as sub-optimal solutions, insufficient requirements (from process inefficiencies), conflicting requirements on parallel branches, deferred refactoring, or delayed upstream contributions.&lt;/li&gt; 
 &lt;li&gt;Non-compliance with best practice: Such as insufficient software documentation, poor collaboration practices, lack of ownership, rewrites for outsourced software, inadequate attention to code quality, tightly coupled components, lack of a test suite, or failure to align to standards (including ignoring industry standard frameworks).&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;Fowler&apos;s thoughts:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://martinfowler.com/bliki/TechnicalDebt.html&quot;&gt;Technical Debt&lt;/a&gt; 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://martinfowler.com/bliki/TechnicalDebtQuadrant.html&quot;&gt;Technical Debt Quadrant&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Thoughts&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;Capturing tribal and tacit knowledge - &lt;a href=&quot;https://leaddev.com/software-quality/building-knowledge-transfer-strategy-manage-technical-debt&quot;&gt;https://leaddev.com/software-quality/building-knowledge-transfer-strategy-manage-technical-debt&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://systemic.engineering/on-fragmentation-tech-debt-coherence/&quot;&gt;On Fragmentation: Tech Debt Is a Coherence Problem&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Tools/Tooling&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://dev.to/elshadhu/i-built-a-tool-to-stop-wasting-time-on-toxic-open-source-projects-5h12&quot;&gt;I Built a Tool to Stop Wasting Time on Toxic OSS Projects&lt;/a&gt; &lt;a href=&quot;https://github.com/ElshadHu/repo-health&quot;&gt;Source&lt;/a&gt;: My system uses a Hybrid Approach that combines a deterministic formula grounded in industry standards with a qualitative Language Model Judge to account for real-world context. The Algorithm (0-100 Score) is calculated using a custom weighted average that I designed, inspired by standardized CHAOSS Metrics. I tuned the weights myself based on what I believe indicates a healthy modern project: &lt;pre&gt;&lt;code&gt;Score = (0.3 × Activity) + (0.25 × Maintenance) + (0.2 × Community) + (0.25 × Docs)
&lt;/code&gt;&lt;/pre&gt; &lt;p&gt;Activity (30%): Frequency of commits + Recency of updates + Unique authors.&lt;br&gt; Maintenance (25%): Issue response time + Open issue ratio + Repository age.&lt;br&gt; Community (20%): Logarithmic scale of Stars &amp;amp; Forks.&lt;br&gt; Documentation (25%): Existence of README, LICENSE, and CONTRIBUTING files.&lt;/p&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;High-level categories&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;strong&gt;Requirement Debt:&lt;/strong&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;People Debt:&lt;/strong&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Architectural debt:&lt;/strong&gt; Issues in the software architecture, such as strongly coupled components, non-scalability of the components, and poor performance, are considered architectural debts. These debts mostly result from hurried decisions or lack of foresight.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Design debt:&lt;/strong&gt; Design debt refers to all those UI or UX issues: inconsistency in styling, bad usability, and a lack of accessibility. It usually occurs when design decisions or designs are made hastily and without proper user research.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Process debt:&lt;/strong&gt; stems from poor collaboration, unclear workflows and missing documentation, causing delays in feature delivery and increasing onboarding challenges. Companies that neglect agile methodologies or fail to integrate scrum principles often struggle with backlog accumulation, making it difficult to track and resolve issues efficiently.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Build Debt:&lt;/strong&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Code debt:&lt;/strong&gt; Code debt is the problem in the source code. It includes bad structuring, duplication, or a lack of comments. Common reasons for code debt include rapid developments or not correctly following the best practices for coding.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Testing debt:&lt;/strong&gt; Testing debt means the need for more extensive and automated testing. When a project has testing debt, the software is unreliable, and there will be more manual testing activities. This might be because of rushed development or poor emphasis on testing.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Test Automation Debt:&lt;/strong&gt; &lt;em&gt;(Could be seen as a subcategory of Testing Debt)&lt;/em&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Defect Debt:&lt;/strong&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Documentation debt:&lt;/strong&gt; Missing or outdated documentation is commonly referred to as documentation debt, which makes it hard for a newcomer to the team to understand the codebase. It generally happens when development is rushed or when documentation is not prioritized.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Infrastructure Debt:&lt;/strong&gt; Infrastructure debt refers to problems in the infrastructure itself, such as underpowered servers, unautomated tasks, and a lack of good monitoring. This debt generally results from hurried decisions about infrastructure or from maintaining infrastructure taking a backseat.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Service Debt:&lt;/strong&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Security debt:&lt;/strong&gt; Arises when teams cut corners on encryption, authentication or vulnerability patching, leaving software exposed to cyberthreats and compliance risks. A lack of automated security testing increases the burden on teams, making it more difficult to maintain secure systems. &lt;em&gt;(Could be seen as a subcategory of Infrastructure.)&lt;/em&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Metrics&lt;/h3&gt; 
&lt;p&gt;Tracking technical debt with metrics: Keeping track of technical debt is essential for maintaining the health and sustainability of a software project.&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt; &lt;p&gt;Documentation and record keeping&lt;/p&gt; 
  &lt;ul&gt; 
   &lt;li&gt;Document Technical Debt: Whenever technical debt is incurred, document it. This includes the reasons for the debt, the expected impact, and any plans for resolution.&lt;/li&gt; 
   &lt;li&gt;Maintain a Technical Debt Register: Create a centralized document or tool where all instances of technical debt are recorded and tracked. This should include details like the nature of the debt, associated code or modules, and any deadlines for resolution.&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Code reviews and analysis:&lt;/p&gt; 
  &lt;ul&gt; 
   &lt;li&gt;Regular Code Reviews: Implement a process where code is regularly reviewed by peers. This helps in identifying potential technical debt early.&lt;/li&gt; 
   &lt;li&gt;Static Code Analysis Tools: Use tools that automatically analyze code for potential issues, such as code smells, complexity, duplication, and other indicators of technical debt.&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Integration with Issue Tracking Systems:&lt;/p&gt; 
  &lt;ul&gt; 
   &lt;li&gt;Link Debt to Issues: When technical debt results in bugs or issues, link these in your issue tracking system. This provides a clear connection between the debt and its consequences.&lt;/li&gt; 
   &lt;li&gt;Prioritize Debt Issues: Make sure that technical debt issues are prioritized alongside other work items in your backlog.&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Testing and Coverage Metrics:&lt;/p&gt; 
  &lt;ul&gt; 
   &lt;li&gt;Monitor Test Coverage: Regularly review test coverage metrics to ensure that your codebase is adequately tested. Low test coverage can be an indicator of technical debt.&lt;/li&gt; 
   &lt;li&gt;Automated Testing: Implement automated testing to continuously monitor the health of your codebase and catch issues early.&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Regular Refactoring Sessions:&lt;/p&gt; 
  &lt;ul&gt; 
   &lt;li&gt;Dedicated Refactoring Time: Allocate regular time slots for refactoring and addressing technical debt. This ensures that debt is actively being paid down.&lt;/li&gt; 
   &lt;li&gt;Refactor as You Go: Encourage developers to refactor and improve code as part of their regular development process, not just during dedicated sessions.&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Metrics and Dashboards:&lt;/p&gt; 
  &lt;ul&gt; 
   &lt;li&gt;Use Metrics: Track key metrics to get a quantitative view of your technical debt.&lt;/li&gt; 
   &lt;li&gt;Dashboards: Create dashboards that visualize technical debt metrics. This helps in quickly assessing the health of the project and identifying areas that need attention.&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;hr&gt; 
&lt;h4&gt;Tech Debt Index (TDI)&lt;/h4&gt; 
&lt;p&gt;&lt;em&gt;Measurement: Metric&lt;/em&gt; (Goal will depend on how the metric is calcuated)&lt;/p&gt; 
&lt;p&gt;A composite metric that combines various indicators of technical debt into a single index.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Mechanism:&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;Combining various technical debt metrics (like code complexity, bug count, etc.) into a single index.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Benefits:&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Provides a holistic view of technical debt in the project.&lt;/li&gt; 
 &lt;li&gt;Can be used to track changes in technical debt over time.&lt;/li&gt; 
 &lt;li&gt;Offers a high-level overview of technical debt, useful for management and stakeholder communication.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Risks:&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;The construction of the index can be subjective, depending on which metrics are included.&lt;br&gt; May oversimplify complex aspects of technical debt.&lt;/p&gt; 
&lt;hr&gt; 
&lt;h4&gt;Tech Debt Ratio (TDR)&lt;/h4&gt; 
&lt;p&gt;&lt;em&gt;Goal: Low&lt;/em&gt; &lt;em&gt;Measurement: percentage&lt;/em&gt;&lt;/p&gt; 
&lt;p&gt;TDR is a measure of the cost to fix the technical debt relative to the size of the codebase. Use TDR to assess and communicate the overall health of the codebase to both technical and non-technical stakeholders.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Mechanism:&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt; 
&lt;ol&gt; 
 &lt;li&gt;&lt;strong&gt;Identifying components.&lt;/strong&gt; Decide which parts of the application are to be evaluated for technical debt.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Code analysis.&lt;/strong&gt; Use static code analysis tools suitable for the programming languages and frameworks used in the fintech app (e.g., ESLint for JavaScript, SonarQube for a range of languages).&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Calculating remediation cost.&lt;/strong&gt; Estimate the time required to address the code issues identified. Consider the complexity of the fintech environment, which might require specialized skills. Assume an average cost per developer hour specific to fintech development expertise (e.g., $80/hour). Example: If it takes 15 hours to refactor the complex code and update libraries, the cost is 15 hours * $80/hour = $1,200.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Calculating development cost.&lt;/strong&gt; Estimate the total cost of developing the app or its specific modules, including design, coding, testing, deployment, and any other expenses. Example: The development cost of the investment portfolio manager might be $30,000.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Calculating Technical Debt Ratio.&lt;/strong&gt; Technical Debt Ratio = (Remediation Cost / Development Cost) * 100&lt;br&gt; Calculation: For the investment portfolio manager, the ratio is ($1,200 / $30,000) * 100 = 4%.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Interpretation and action.&lt;/strong&gt; Interpretation: A 4% technical debt ratio indicates a moderate level of debt. Action: Prioritize fixing critical issues, especially those related to security, data integrity, and regulatory compliance.&lt;/li&gt; 
&lt;/ol&gt; 
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Benefits:&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Provides a quick snapshot of the quality of code being produced&lt;/li&gt; 
 &lt;li&gt;Provides a monetary perspective on the impact of technical debt&lt;/li&gt; 
 &lt;li&gt;Helps in prioritizing debt reduction based on cost&lt;/li&gt; 
 &lt;li&gt;A higher ratio suggests a significant portion of development effort goes into addressing technical debt&lt;/li&gt; 
 &lt;li&gt;Can be used to justify investment in reducing technical debt&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Limitations:&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Estimating the cost to fix issues can be subjective.&lt;/li&gt; 
 &lt;li&gt;Doesn&apos;t capture non-code aspects of technical debt (like architectural issues).&lt;/li&gt; 
 &lt;li&gt;Might not reflect the impact of non-quantifiable aspects of debt.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;hr&gt; 
&lt;h4&gt;Defect count&lt;/h4&gt; 
&lt;p&gt;&lt;em&gt;Goal: Low&lt;/em&gt; &lt;em&gt;Measurement: Instances of defects within a system&lt;/em&gt;&lt;/p&gt; 
&lt;p&gt;This metric tracks the number of open bugs. High numbers can indicate underlying quality issues contributing to technical debt.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Mechanism:&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;Use a defect tracker or other system (spreadsheet).&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Benefits:&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Useful as overall guide to health of development.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Risks:&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Bug counts alone don&apos;t give a complete picture of the software&apos;s health.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;hr&gt; 
&lt;h4&gt;Defect age&lt;/h4&gt; 
&lt;p&gt;&lt;em&gt;Goal: Low&lt;/em&gt; &lt;em&gt;Measurement: Time per defect&lt;/em&gt;&lt;/p&gt; 
&lt;p&gt;Bugs that have been open for a long time can indicate that technical debt is being neglected. This can lead to a deteriorating codebase and user experience.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Mechanism:&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;Use a defect tracker or other system (spreadsheet). Timestamps must be present for each defect report.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Benefits:&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Useful for prioritizing bug fixes.&lt;/li&gt; 
 &lt;li&gt;Helps prioritize bug fixes and identify areas needing improvement.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Risks:&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;The severity and impact of bugs vary; not all bugs contribute equally to technical debt.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;hr&gt; 
&lt;h4&gt;Defect growth rate&lt;/h4&gt; 
&lt;p&gt;&lt;em&gt;Goal: Low, preferably negative&lt;/em&gt; &lt;em&gt;Measurement: instance delta (number of new bugs reported versus the number of bugs that have been resolved or closed over a specific period)&lt;/em&gt;&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Mechanism:&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;Track the number of new bugs reported and the number of bugs closed in your issue tracking or project management software over regular intervals (e.g., weekly, monthly).&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Benefits:&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;strong&gt;Balance of Bug Creation and Resolution:&lt;/strong&gt; A high number of new bugs compared to closed ones could indicate growing technical debt, as it suggests issues are being introduced faster than they are being resolved.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Software Stability:&lt;/strong&gt; A sudden spike in new bugs might indicate problems introduced in recent updates, reflecting the impact of rushed development or insufficient testing, both of which can contribute to technical debt.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Project Health Monitoring:&lt;/strong&gt; Regularly comparing new and closed bugs can help in assessing the health and progress of a project. A project with decreasing technical debt should ideally show a trend of decreasing new bugs or an increasing rate of bug closure.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Prioritization and Resource Allocation:&lt;/strong&gt; This metric can help in prioritizing bug fixing and allocating resources effectively, which is crucial for managing and reducing technical debt.&lt;/li&gt; 
 &lt;li&gt;Helps in understanding the dynamics of bug occurrence and resolution in a project.&lt;/li&gt; 
 &lt;li&gt;Can signal when technical debt might be increasing, requiring attention to areas of the codebase that are generating new bugs.&lt;/li&gt; 
 &lt;li&gt;Assists in resource planning for bug fixing and technical debt reduction efforts.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Risks:&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;strong&gt;Not All Bugs are Equal:&lt;/strong&gt; This metric doesn&apos;t account for the severity or complexity of the bugs. Therefore, the raw numbers might be misleading without the context of bug impact.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Quality of Bug Reporting:&lt;/strong&gt; The reliability of this metric depends on the consistency and quality of bug reporting practices. Inconsistent reporting can skew the data.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Does Not Reflect Underlying Causes:&lt;/strong&gt; While this metric can signal potential problems, it doesn&apos;t directly point to the causes of technical debt.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;hr&gt; 
&lt;h4&gt;Defect ratio, Defect density&lt;/h4&gt; 
&lt;p&gt;&lt;em&gt;Goal: Low&lt;/em&gt; &lt;em&gt;Measurement: number of defects in a software system relative to its size&lt;/em&gt;&lt;/p&gt; 
&lt;p&gt;Helps in tracking the quality of the software over time, indicating whether technical debt is causing an increase in defects. Can guide decisions about where to focus development efforts, particularly in identifying areas of the codebase that may be contributing disproportionately to the defect count. Assists in prioritizing technical debt reduction strategies, especially when correlated with other metrics like code complexity or code churn.&lt;/p&gt; 
&lt;p&gt;Applied to whole systems, this is essentially a bug count. Applied to individual files or components, it highlights (heatmaps) the 20% of the code where 80% of the defects live.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Benefits:&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;strong&gt;Quality vs. Debt:&lt;/strong&gt; While a high defect ratio directly points to quality issues, it indirectly suggests technical debt. For instance, rushed features, lack of testing, or poor design decisions can lead to both more defects and more debt.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Actionable Insights:&lt;/strong&gt; Knowing the defect ratio can help teams prioritize refactoring, improve testing strategies, or revise development practices to reduce both defects and technical debt.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Indicator of Software Quality:&lt;/strong&gt; A high defect ratio suggests lower quality, which could be a result of accumulated technical debt due to issues like rushed development or poor design.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Maintenance and Refactoring Needs:&lt;/strong&gt; An increasing defect ratio over time can indicate that the software is becoming more difficult to maintain, suggesting the need for refactoring and addressing technical debt.&lt;br&gt; Project Health Assessment: It provides a quick snapshot of the current state of the project, helping to assess whether technical debt is impacting the software negatively.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Limitations:&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;strong&gt;Not All-Encompassing:&lt;/strong&gt; The defect ratio alone doesn&apos;t capture all aspects of technical debt, such as architectural issues or code complexity.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Quality of Defect Reporting:&lt;/strong&gt; The metric&apos;s accuracy depends on the thoroughness and consistency of defect reporting practices.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Variability in Defect Severity:&lt;/strong&gt; Not all defects have the same impact or require the same effort to fix, which this ratio doesn&apos;t account for.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Mechanism:&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Count the total number of defects (reported bugs or issues) and divide it by a measure of software size (like lines of code, function points, or modules).&lt;/li&gt; 
 &lt;li&gt;Defect Ratio = Size of the Software/Number of Defects​&lt;/li&gt; 
 &lt;li&gt;Number of Defects is the total number of defects found in the software.&lt;/li&gt; 
 &lt;li&gt;Size of the Software could be measured in different units, such as lines of code, function points, or number of modules/components.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;hr&gt; 
&lt;h4&gt;Cycle Time&lt;/h4&gt; 
&lt;p&gt;&lt;em&gt;Goal: Low&lt;/em&gt; &lt;em&gt;Measurement: Time&lt;/em&gt;&lt;/p&gt; 
&lt;p&gt;Measures the time it takes for a unit of work to be completed from start to finish. Unlike throughput, which measures the amount of work completed in a given time period, cycle time focuses on the amount of time. This metric is useful for understanding how long it takes to complete a specific task, and can be useful for identifying bottlenecks or inefficiencies in the development process.&lt;/p&gt; 
&lt;hr&gt; 
&lt;h4&gt;Lead time for changes, Time to Market (TTM)&lt;/h4&gt; 
&lt;p&gt;&lt;em&gt;Goal: Low&lt;/em&gt; &lt;em&gt;Measurement: Time&lt;/em&gt;&lt;/p&gt; 
&lt;p&gt;Lead time for changes is the time it takes to go from code committed to code successfully running in production. TTM is typically customer-facing and at largerscale than a single feature. This metric is important for measuring the speed and agility of your software delivery process. Lead time takes into account the time it takes to plan, prioritize, and start work on a unit of work, as well as the time it takes to complete it. It can be useful for understanding how long it takes to deliver new features or improvements to customers.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Mechanism:&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;Measure the duration from when a feature is planned to when it is available to users.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Benefits:&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Longer lead times can be a symptom of high technical debt, as existing issues slow down new development.&lt;/li&gt; 
 &lt;li&gt;Helps in identifying bottlenecks in the development process.&lt;/li&gt; 
 &lt;li&gt;Longer time to market can indicate inefficiencies and potential technical debt.&lt;/li&gt; 
 &lt;li&gt;Striving for shorter time to market can sometimes lead to accruing more technical debt.&lt;/li&gt; 
 &lt;li&gt;If the team is able to quickly implement new features or fix bugs and get them into production, the organization can respond more quickly to changes in the market or user needs. This can lead to a competitive advantage.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Risks:&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Time to market is influenced by many factors, not just technical debt.&lt;/li&gt; 
 &lt;li&gt;Short time to market isn&apos;t always positive, especially if it leads to lower quality.&lt;/li&gt; 
 &lt;li&gt;Influenced by many factors beyond technical debt, such as team size and resource allocation.&lt;/li&gt; 
 &lt;li&gt;Not all delays are due to technical debt.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;hr&gt; 
&lt;h4&gt;Code Churn&lt;/h4&gt; 
&lt;p&gt;&lt;em&gt;Goal: Low&lt;/em&gt; &lt;em&gt;Measurement: percentage of a developer&apos;s own code that is recently edited (added, modified, deleted) after being written.&lt;/em&gt;&lt;/p&gt; 
&lt;p&gt;Code churn can be indicative of indecision, lack of clarity, or misunderstanding – all of which contribute to technical debt. High code churn, especially late in a development cycle, can be a red flag that code may be less reliable or harder to maintain. High churn may indicate unstable or problematic areas in the codebase. Helps identify features or modules that are frequently changed and might be accumulating debt.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Mechanism:&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Calculate the percentage of lines of code that have been changed, added, or deleted during a specific time frame.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Benefits:&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Identifying areas of frequent changes helps to pinpoint unstable code and prevent potential future issues related to constant modifications.&lt;/li&gt; 
 &lt;li&gt;Analyzing code churn alongside bug count can provide insights into whether the churn is constructive (refactoring, improving code) or destructive (introducing more defects).&lt;/li&gt; 
 &lt;li&gt;It helps in prioritizing areas for refactoring and understanding the impact of changes.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Limitations:&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;High churn isn’t always negative; it can reflect healthy iterative development.&lt;/li&gt; 
 &lt;li&gt;Doesn’t directly measure code quality.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;hr&gt; 
&lt;h4&gt;Development Throughput, Velocity&lt;/h4&gt; 
&lt;p&gt;&lt;em&gt;Goal: High&lt;/em&gt; &lt;em&gt;Measurement: Instances (stories, features, etc) within time&lt;/em&gt;&lt;/p&gt; 
&lt;p&gt;Throughput is a way of measuring how much work your team is able to complete in a specific period of time. It&apos;s a way of tracking progress and understanding how well your processes are working. By keeping an eye on throughput, you can make changes to improve the efficiency of your team’s work. Tracking throughput is like keeping a pulse on the health of the development process.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Mechanism:&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt; 
&lt;ol&gt; 
 &lt;li&gt;&lt;strong&gt;Define the unit of work.&lt;/strong&gt; The first step is to define what constitutes a unit of work in your development process. For example, you may decide that a unit of work is a completed user story, a fixed bug, or a feature that meets acceptance criteria. Whatever you choose, it&apos;s important that the definition of a unit of work is consistent and clear for everyone on the team.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Track progress.&lt;/strong&gt; Next, track how many units of work are being completed in a given time period. For example, you might track the number of completed user stories over the course of a sprint, or the number of fixed bugs over the course of a week.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Calculate the throughput.&lt;/strong&gt; Finally, calculate the throughput by dividing the number of units of work completed by the amount of time it took to complete them. For example, if your team completed 20 user stories in a two-week sprint, the throughput would be 20 user stories / 2 weeks. Important: You can’t measure a weekly throughput by dividing this number by 2. For that, you need to assess a week as a separate entity.&lt;/li&gt; 
&lt;/ol&gt; 
&lt;p&gt;Example: Development team of 5 people completed a total of 20 user stories in 4 weeks. The team&apos;s throughput would be 20 user stories / 4 weeks.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Benefits:&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;strong&gt;Early access to potential efficiency problems.&lt;/strong&gt; Throughput shows you if your process remains efficient. It’s the first indicator of something going wrong. Then, you can get deeper and look for detailed causes of this problem. By that, you’re continuously making sure you’re on the right path to deliver value to your customers in a timely manner and can prioritize tasks accordingly.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Improved processes.&lt;/strong&gt; Measuring throughput helps you to identify problems early on and make changes before they become bigger issues. By tracking this metric, you can identify bottlenecks, optimize the workflow, and prioritize tasks effectively. After that, you can make changes to improve efficiency and reduce waste, which entails working in accordance with lean methodology.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Better resource allocation.&lt;/strong&gt; Throughput helps to determine the amount of work that can be completed in a given time period, which in turn helps to allocate resources effectively.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Enhanced decision-making.&lt;/strong&gt; By tracking this metric, you can make informed decisions that drive continuous improvement and help you meet your goals.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Risks:&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;strong&gt;Oversimplification.&lt;/strong&gt; Focusing solely on throughput can lead to an oversimplification of the complex processes involved in software development. This can result in an incomplete understanding of performance and a failure to identify other key factors that impact development outcomes.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Misinterpretation.&lt;/strong&gt; If not properly understood, throughput metrics can be misinterpreted, leading to incorrect conclusions and misguided decisions. The issue is that throughput metrics on their own only provide a small piece of information about the overall performance of a system. If they&apos;re looked at in isolation, without considering other factors, it&apos;s possible to come to incorrect conclusions. For example, if you see an increase in throughput, it could be due to an increase in the number of resources or an improvement in processes. If you make decisions based solely on this increase, you might be misled into thinking that you&apos;re making progress, when in fact the underlying issues causing problems in the system are still there.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Lack of reference to complexity and size of tasks.&lt;/strong&gt; Throughput doesn’t incorporate two aspects: complexity and size of tasks. That way, a team still can process tasks of various types, and in that case throughput won’t give much insight into your process.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Incentivizing negative behaviors.&lt;/strong&gt; If throughput becomes the primary focus, team members may be incentivized to prioritize speed over quality, leading to decreased productivity and increased errors.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Neglect of important factors.&lt;/strong&gt; Focusing on throughput to the exclusion of other important factors, such as code quality or collaboration, can lead to an unbalanced approach to software development.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Over-reliance on metrics.&lt;/strong&gt; Relying too heavily on throughput metrics can result in a lack of attention to other important indicators of performance, such as customer satisfaction and employee engagement.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Must still be conscious while assessing performance.&lt;/strong&gt; Assessing the performance of individual developers is controversial. Throughput as a single source of truth also isn&apos;t good for that goal since it doesn’t refer to quality and complexity of tasks. That way, developers who complete a lot of small tasks and do it carelessly would have higher results than the ones who deliver the code of the highest quality and work with complex tasks.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;hr&gt; 
&lt;h4&gt;Pull Request Size&lt;/h4&gt; 
&lt;p&gt;&lt;em&gt;Goal: Low&lt;/em&gt; &lt;em&gt;Measurement: bytes, lines of code, # of files&lt;/em&gt;&lt;/p&gt; 
&lt;p&gt;Pull request size refers to the extent of code changes introduced within a single pull request, typically measured by the number of files modified and lines of code added or removed.&lt;/p&gt; 
&lt;p&gt;Measuring pull request size helps streamline code reviews, accelerate feedback cycles, and improve code quality by breaking down changes into manageable units and facilitating efficient collaboration among team members.&lt;/p&gt; 
&lt;hr&gt; 
&lt;h4&gt;Code Duplication&lt;/h4&gt; 
&lt;p&gt;&lt;em&gt;Goal: Low&lt;/em&gt; &lt;em&gt;Measurement: percentage&lt;/em&gt;&lt;/p&gt; 
&lt;p&gt;Code duplication often leads to maintenance challenges. If a bug is found in a piece of duplicated code, it needs to be fixed in all instances. This increases the likelihood of missed defects and future issues.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Mechanism:&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;Analyze the codebase using static code analysis tools to identify and quantify duplicated blocks of code.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Benefits:&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;High duplication indicates poor code quality and higher maintenance costs.&lt;/li&gt; 
 &lt;li&gt;Points to potential areas for code reuse and refactoring.&lt;/li&gt; 
 &lt;li&gt;Reducing code duplication enhances maintainability and reduces the likelihood of introducing inconsistencies during updates.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Risks:&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Some duplication might be necessary or intentional.&lt;/li&gt; 
 &lt;li&gt;Doesn’t measure other quality aspects like code complexity.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;hr&gt; 
&lt;h4&gt;Cyclomatic Complexity&lt;/h4&gt; 
&lt;p&gt;&lt;em&gt;Goal: Low&lt;/em&gt; &lt;em&gt;Measurement: instances of linearly independent paths through a unit of code&lt;/em&gt;&lt;/p&gt; 
&lt;p&gt;High cyclomatic complexity indicates that the code may be harder to test thoroughly and more prone to defects. It can also be harder to read and understand, increasing the likelihood of introducing errors during future changes. ‍Use this metric to identify complex code that may be harder to maintain and more prone to defects. Analyzing cyclomatic complexity at a method, class, and module level can help identify specific areas that may benefit most from refactoring.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Mechanism:&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;‍Use static analysis tools to calculate the number of independent paths through the code.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Benefits:&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Higher complexity often indicates harder-to-maintain code, contributing to technical debt.&lt;/li&gt; 
 &lt;li&gt;Can help identify areas that need refactoring.&lt;/li&gt; 
 &lt;li&gt;Helps in estimating the effort required for testing and maintenance.&lt;/li&gt; 
 &lt;li&gt;Evaluate the intricacy and potential risks associated with modifications. This approach provides a deeper understanding of the impact on code quality and maintainability.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Risks:&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Doesn’t measure code readability or maintainability directly.&lt;/li&gt; 
 &lt;li&gt;Can be misleading for certain code structures.&lt;/li&gt; 
 &lt;li&gt;Some level of duplication might be unavoidable or even preferable in certain cases.&lt;/li&gt; 
 &lt;li&gt;Doesn&apos;t indicate other aspects of code quality.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;hr&gt; 
&lt;h4&gt;Test Coverage&lt;/h4&gt; 
&lt;p&gt;&lt;em&gt;Goal: High&lt;/em&gt; &lt;em&gt;Measurement: percentage over lines of code and/or files&lt;/em&gt;&lt;/p&gt; 
&lt;p&gt;It measures the extent to which the modified code is covered by automated tests. Higher test coverage indicates more confidence in the changes and reduces the risk of regressions. Test coverage analysis helps ensure code quality and stability. While high test coverage is not a guarantee of code quality, inadequate test coverage can mean that the codebase is not well-protected against regressions, making it riskier to address technical debt through refactoring.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Mechanism:&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;Use testing tools and frameworks to calculate the percentage of code executed during testing.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Benefits:&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;High test coverage can reduce the likelihood of bugs and technical debt.&lt;/li&gt; 
 &lt;li&gt;Indicates the robustness of testing practices.&lt;/li&gt; 
 &lt;li&gt;Low test coverage can lead to undiscovered bugs and increase technical debt.&lt;/li&gt; 
 &lt;li&gt;High coverage helps ensure code changes don&apos;t introduce new issues.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Risks:&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;High coverage doesn&apos;t guarantee high-quality tests or code.&lt;/li&gt; 
 &lt;li&gt;Can lead to a false sense of security if tests are not well-designed.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;hr&gt; 
&lt;h4&gt;Deployment Frequency&lt;/h4&gt; 
&lt;p&gt;&lt;em&gt;Goal: High&lt;/em&gt; &lt;em&gt;Measurement: Instances within time&lt;/em&gt;&lt;/p&gt; 
&lt;p&gt;Deployment frequency is the number of times code is deployed to production in a given period of time. This metric is important for measuring the speed and agility of a software delivery process.&lt;/p&gt; 
&lt;p&gt;For example, if your team is able to deploy code to production frequently, it can lead to a faster feedback loop and quicker response to issues or changes. This can lead to a better product and increased user satisfaction.&lt;/p&gt; 
&lt;p&gt;A high deployment frequency indicates that teams are able to deliver changes quickly, responding to the needs of the business.&lt;/p&gt; 
&lt;hr&gt; 
&lt;h4&gt;Changed Failure Rate&lt;/h4&gt; 
&lt;p&gt;&lt;em&gt;Goal: Low&lt;/em&gt; &lt;em&gt;Measurement: percentage (of changes (e.g., deployments or code commits) that fail and require immediate remediation (like a hotfix or rollback))&lt;/em&gt;&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Mechanism:&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;Tracking the success and failure rates of deployments and code changes.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Benefits:&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;A high change failure rate can indicate poor code quality or inadequate testing, contributing to technical debt.&lt;/li&gt; 
 &lt;li&gt;Helps identify the stability and reliability of the development and deployment processes.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Risks:&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Some failures are normal and not indicative of technical debt.&lt;/li&gt; 
 &lt;li&gt;Doesn&apos;t capture the underlying causes of the failures.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;hr&gt; 
&lt;h4&gt;Number of Failed CI/CD Events&lt;/h4&gt; 
&lt;p&gt;&lt;em&gt;Goal: Low&lt;/em&gt; &lt;em&gt;Measurement: instances (number of times continuous integration (CI) or continuous deployment (CD) processes fail.)&lt;/em&gt;&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Mechanism:&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Benefits:&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Frequent CI/CD failures can indicate underlying issues in code quality, testing, or the build process, contributing to technical debt.&lt;/li&gt; 
 &lt;li&gt;Helps in identifying the reliability and efficiency of automated processes.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Risks:&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Some failures might be due to external factors unrelated to technical debt.&lt;/li&gt; 
 &lt;li&gt;Doesn&apos;t provide insights into the nature of the issues causing the failures.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;hr&gt; 
&lt;h4&gt;Mean time to recovery (MTTR)&lt;/h4&gt; 
&lt;p&gt;&lt;em&gt;Goal: Low&lt;/em&gt; &lt;em&gt;Measurement: Time&lt;/em&gt;&lt;/p&gt; 
&lt;p&gt;MTTR is the average time it takes to repair a system after a failure. This metric is important for measuring the reliability and availability of a system.&lt;/p&gt; 
&lt;p&gt;For example, let&apos;s say your company has a web application that experiences a failure. The MTTR is the time it takes for your team to identify the failure and fix the issue. A low MTTR means your team is able to quickly detect and resolve issues, ensuring that your application is available to users.&lt;/p&gt; 
&lt;p&gt;A low MTTR indicates a system that is reliable and easy to recover from failures.&lt;/p&gt; 
&lt;hr&gt; 
&lt;h4&gt;Mean time between failures (MTBF)&lt;/h4&gt; 
&lt;p&gt;&lt;em&gt;Goal: High&lt;/em&gt; &lt;em&gt;Measurement: Time&lt;/em&gt;&lt;/p&gt; 
&lt;p&gt;MTBF is the average time between failures in a system. This metric is important for measuring the reliability and availability of a system.&lt;/p&gt; 
&lt;p&gt;For example, if your web application has a high MTBF, it means that your users will experience fewer issues and downtime due to system failures. This can lead to increased user satisfaction and a better overall experience with your product.&lt;/p&gt; 
&lt;p&gt;A high MTBF indicates a system that is reliable and has fewer failures.&lt;/p&gt; 
&lt;hr&gt; 
&lt;h4&gt;Mean time to detect (MTTD)&lt;/h4&gt; 
&lt;p&gt;&lt;em&gt;Goal: Low&lt;/em&gt; &lt;em&gt;Measurement: Time&lt;/em&gt;&lt;/p&gt; 
&lt;p&gt;MTTD is the average time it takes to detect a failure in a system. This metric is important for measuring the effectiveness of monitoring and alerting systems.&lt;/p&gt; 
&lt;p&gt;For example, if you have a monitoring system set up to detect issues with your web application, the MTTD is the time it takes for your team to receive an alert after a failure occurs. A low MTTD means your team can quickly identify and address issues, minimizing the impact on users.&lt;/p&gt; 
&lt;p&gt;A low MTTD indicates that failures are detected quickly, allowing teams to respond and recover more quickly.&lt;/p&gt; 
&lt;hr&gt; 
&lt;h4&gt;User value and impact&lt;/h4&gt; 
&lt;p&gt;&lt;em&gt;Goal: High&lt;/em&gt; &lt;em&gt;Measurement: opinion/human analysis&lt;/em&gt;&lt;/p&gt; 
&lt;p&gt;It involves considering factors like user feedback, customer requests, or business goals. By prioritizing value-driven changes, your team will ensure that their efforts align with the needs and expectations of stakeholders.&lt;/p&gt; 
&lt;hr&gt; 
&lt;h4&gt;Peer review&lt;/h4&gt; 
&lt;p&gt;&lt;em&gt;Goal: High&lt;/em&gt; &lt;em&gt;Measurement: opinion/human analysis&lt;/em&gt;&lt;/p&gt; 
&lt;p&gt;Instead of relying solely on metrics, emphasize the feedback and insights provided during peer code reviews. Human judgment and expertise play a crucial role in evaluating code changes. Peer reviews provide an opportunity for knowledge sharing, identifying potential issues, and enhancing overall code quality.&lt;/p&gt; 
&lt;hr&gt; 
&lt;h2&gt;Table of Tech Debt ideas&lt;/h2&gt; 
&lt;pre&gt;&lt;code&gt;Metric Name,Description,Category,Primary Source,Probability of Existing,Ease of Collection,Importance (Why track this?)
1. Cyclomatic Complexity,A quantitative measure of the number of linearly independent paths through a program&apos;s source code.,Engineering,SonarQube,High,Easy (Out of box),High complexity increases defect probability and makes testing/refactoring exponentially harder.
2. Cognitive Complexity,&quot;A measure of how difficult a unit of code is to intuitively understand (unlike Cyclomatic, which measures structural logic).&quot;,Engineering,SonarQube,Medium,Easy (Out of box),&quot;Directly correlates to &quot;&quot;time to read&quot;&quot; and onboarding costs for new developers.&quot;
3. Code Coverage,The percentage of code lines executed by automated unit/integration tests.,Engineering,SonarQube / JaCoCo,High,Easy (CI Integration),&quot;Low coverage implies &quot;&quot;Blind Spots&quot;&quot; where regressions can occur without detection.&quot;
4. Code Duplication %,The percentage of code blocks that appear identical or nearly identical in multiple places.,Engineering,SonarQube,High,Easy (Out of box),Violates DRY (Don&apos;t Repeat Yourself); a bug fix in one spot must be manually replicated.
5. SQALE Rating (Debt Ratio),An aggregated rating (A-E) based on the estimated time required to fix all maintainability issues.,Engineering,SonarQube,Medium,Easy (Config needed),&quot;Provides a high-level &quot;&quot;Credit Score&quot;&quot; for codebases that executives can easily understand.&quot;
6. Code Churn,&quot;The volume of lines added, modified, or deleted over a specific time period.&quot;,Engineering,GitHub Ent.,High,Medium (Git mining),&quot;High churn in legacy files often indicates &quot;&quot;Hotspots&quot;&quot; of instability or unclear requirements.&quot;
7. TODO/FIXME Count,The count of code comments explicitly flagged as temporary workarounds or deferred maintenance.,Engineering,SonarQube / Grep,High,Easy (Regex search),&quot;A literal &quot;&quot;IOU&quot;&quot; list developers have left in the code; indicates rushed features.&quot;
8. Deployment Frequency,How often an organization successfully releases to production.,Delivery (DORA),Jenkins / GitHub,Medium,Medium (Log parsing),&quot;Low frequency often implies brittle pipelines, manual gates, or fear of breaking production.&quot;
9. Lead Time for Changes,The amount of time it takes a commit to get into production.,Delivery (DORA),Jira / GitHub,Low,Hard (Correlating tools),&quot;Long lead times indicate pipeline bottlenecks, slow code reviews, or manual testing debt.&quot;
10. Change Failure Rate,The percentage of deployments causing a failure in production.,Delivery (DORA),ServiceNow / Jira,Medium,Hard (Manual tagging),&quot;High failure rates indicate &quot;&quot;Quality Debt&quot;&quot;—lack of automated testing or reliable staging.&quot;
11. Mean Time to Recovery,How long it takes to restore service after a failure.,Delivery (DORA),PagerDuty,High,Medium (Incident tools),&quot;High MTTR suggests &quot;&quot;Observability Debt&quot;&quot;—it takes too long to diagnose and patch issues.&quot;
12. Flaky Test Ratio,The percentage of automated tests that fail and pass without code changes.,Delivery,CI Tool,Low,Hard (Log analysis),&quot;Destroys trust in the CI/CD pipeline, causing developers to ignore red builds.&quot;
13. Build Duration,The time it takes for a full CI/CD pipeline to run.,Delivery,CI Tool,High,Easy (CI Logs),&quot;Slow builds break flow state and discourage frequent commits, leading to larger riskier merges.&quot;
14. Library Freshness,A measurement of how many versions behind the current stable release your dependencies are.,Cyber / Platform,Snyk / Dependabot,Medium,Easy (SaaS Tools),Outdated libraries prevent using new features and eventually become security liabilities.
15. Critical/High CVEs,Count of known security vulnerabilities in code or dependencies.,Cyber,Snyk / Veracode,High,Easy (Scanners),&quot;Immediate risk of breach; represents &quot;&quot;Security Debt&quot;&quot; that must be paid immediately.&quot;
16. Secret Leaks Count,&quot;Number of hardcoded secrets (API keys, passwords) detected in the codebase.&quot;,Cyber,TruffleHog,Low,Medium (Scanners),&quot;Indicates poor security practices and requires immediate, expensive rotation of credentials.&quot;
17. IAM Over-provisioning,Percentage of permissions granted vs. permissions actually used by services.,Cyber,AWS IAM Analyzer,Low,Hard (Cloud audit),&quot;&quot;&quot;Least Privilege&quot;&quot; debt; increases blast radius if a service is compromised.&quot;
18. Infrastructure Drift,The delta between the defined IaC (Terraform) and the actual state of the cloud environment.,Infrastructure,Terraform / Driftctl,Low,Medium (State diffs),&quot;Indicates &quot;&quot;ClickOps&quot;&quot; (manual changes) are happening, making disaster recovery unreliable.&quot;
19. Cloud Asset Utilization,&quot;Measure of provisioned CPU/RAM vs. actual usage (e.g., idle instances).&quot;,Infrastructure,AWS Cost Explorer,High,Easy (Cloud Native),Financial debt; paying for resources that aren&apos;t delivering value due to poor optimization.
20. Legacy OS Instances,Count of servers running on End-of-Life (EOL) Operating Systems.,Infrastructure,CMDB / Console,Medium,Medium (Inventory),High operational risk; EOL systems cannot be patched against new exploits.
21. IaC Coverage %,Percentage of cloud infrastructure managed via code vs. manual console creation.,Infrastructure,Terraform,Low,Hard (Manual Audit),Low coverage means environments cannot be easily replicated or restored.
22. Cyclic Dependencies,&quot;Number of cycles between packages/modules (A depends on B, B depends on A).&quot;,Architecture,SonarQube,Low,Medium (Static Analysis),Makes code tightly coupled; you cannot change one module without breaking the other.
23. God Class Count,&quot;Classes that exceed a high threshold of Lines of Code (e.g., &amp;gt;2000 LOC) or methods.&quot;,Architecture,SonarQube,High,Easy (Static Analysis),&quot;These classes know too much, are hard to test, and usually become the bottleneck for changes.&quot;
24. API Contract Breaking,Frequency of backward-incompatible changes to internal/external APIs.,Architecture,Pact / Swagger,Low,Hard (Diffing specs),High frequency breaks downstream consumers and forces unplanned refactoring work.
25. Afferent/Efferent Coupling,Measures stability (how many rely on you) vs. instability (how many you rely on).,Architecture,ArchUnit,Low,Medium (Tooling req.),High coupling makes the architecture rigid; changing one component ripples through the system.
26. Monolith Size (LOC),Total Lines of Code in a single deployable unit (if microservices strategy is desired).,Architecture,SonarQube / Git,High,Easy (LOC Count),&quot;If the goal is decoupling, a growing monolith represents negative architectural progress.&quot;
27. Bus Factor,The minimum number of developers required to hit by a bus before the project stalls.,Process,Git Analytics,Low,Hard (Algo required),&quot;Low bus factor (e.g., 1) indicates knowledge silos and &quot;&quot;Knowledge Debt.&quot;&quot;&quot;
28. Defect Backlog Age,The average time known non-critical bugs sit in the backlog.,Product,Jira,High,Medium (JQL Query),&quot;Old bugs are rarely fixed; they clutter the view and represent &quot;&quot;Product Debt.&quot;&quot;&quot;
29. Onboarding Time,&quot;Time from &quot;&quot;Day 1&quot;&quot; to &quot;&quot;First PR Merged&quot;&quot; for a new engineer.&quot;,Process,HR + GitHub,Low,Hard (Manual data),Proxy for documentation quality and environment complexity. Long onboarding = high complexity.
30. DB Schema Version Lag,Difference between production schema version and migration scripts.,Data,Flyway,Medium,Medium (DB Tools),Indicates manual DB patches or dangerous divergence between code and database state.
31. Dead Code / Unused Tables,Methods or DB tables that have zero usage references.,Data,Sonar / Logs,Medium,Hard (Usage analysis),Clutter that confuses developers and wastes backup/storage resources.
32. Documentation Staleness,Average age of files in the /docs or Wiki compared to current date.,Process,Confluence,Medium,Medium (API Metadata),Outdated docs are worse than no docs; they mislead engineers and cause outages.
33. PR Review Time,Average time elapsed between a Pull Request being opened and merged/closed.,Process,GitHub,High,Easy (API available),Long review times block value delivery and increase merge conflicts (Process Debt).
34. Branch Lifespan,The duration a feature branch exists before being merged.,Delivery,GitHub / Git,High,Easy (Git logs),&quot;Long-lived branches drift from main, leading to &quot;&quot;Merge Hell&quot;&quot; and integration debt.&quot;
35. Merge Conflict Rate,Percentage of PRs that require manual conflict resolution.,Delivery,GitHub / Git,Low,Medium (Git stats),High rates indicate poor communication or architectural coupling.
36. Test Execution Time,Total time to run the full test suite (local or CI).,Delivery,CI Tool,High,Easy (CI Timestamps),&quot;If tests take 1 hour, devs won&apos;t run them locally, leading to &quot;&quot;Feedback Loop Debt.&quot;&quot;&quot;
37. Environment Parity Gap,Count of configuration differences between Staging and Production.,Infrastructure,Terraform,Low,Hard (Deep diffs),&quot;&quot;&quot;It worked on my machine&quot;&quot; syndrome; parity gaps cause production-only bugs.&quot;
38. Untagged Cloud Assets,Percentage of cloud assets missing cost allocation/owner tags.,Infrastructure,AWS Config,High,Medium (Policy scan),&quot;&quot;&quot;FinOps Debt&quot;&quot;—impossible to attribute costs or identify owners of zombie resources.&quot;
39. Orphaned Storage,Count/Size of EBS volumes or snapshots not attached to any compute instance.,Infrastructure,Cloud Custodian,High,Easy (API Query),Pure waste; paying for storage that is technically disconnected from the application.
40. Container Image Size,Size of the Docker/Container images being deployed.,Platform,Artifactory,High,Easy (Registry API),Bloated images slow down scaling (autoscaling latency) and increase vulnerability surface area.
41. Pod Restart Rate,&quot;Frequency of containers crashing and restarting (OOMKilled, etc.).&quot;,Platform,Prometheus,High,Easy (Metrics),&quot;Indicates instability, memory leaks, or improper resource limits (Configuration Debt).&quot;
42. Serverless Cold Starts,Average latency added when a function scales from zero.,Platform,Datadog,Medium,Medium (APM),High latency here indicates poor optimization of runtimes or dependencies.
43. License Risk,&quot;Count of dependencies with restrictive (e.g., GPL) or unknown licenses.&quot;,Legal,FOSSA,Medium,Easy (Scanners),&quot;&quot;&quot;Legal Debt&quot;&quot;—risk of having to open-source proprietary code or face lawsuits.&quot;
44. TLS Protocol Lag,Percentage of endpoints supporting deprecated protocols (TLS 1.0/1.1).,Cyber,Qualys,Medium,Medium (Net scan),Security compliance debt; modern browsers/clients will eventually reject connections.
45. Missing Security Headers,&quot;Endpoints missing standard headers (HSTS, CSP, X-Frame-Options).&quot;,Cyber,OWASP ZAP,Medium,Easy (Curl/Scan),&quot;Low-hanging fruit for attackers; indicates lack of &quot;&quot;Security by Design.&quot;&quot;&quot;
46. Dependency Tree Depth,The average depth of transitive dependencies in the project.,Architecture,Maven / npm,Low,Medium (Graph analysis),Deep trees make vulnerability patching difficult (you rely on a library that relies on a library...).
47. Layer Violations,&quot;Instances where lower layers call upper layers (e.g., Domain layer calling UI).&quot;,Architecture,ArchUnit,Low,Hard (Custom rules),Breaks separation of concerns; creates spaghetti code that is hard to refactor.
48. Interface Segregation,Classes forced to implement methods they do not use (bloated interfaces).,Architecture,SonarQube,Low,Medium (Static Analysis),Indicates poor abstraction; makes mocking and testing specific behaviors difficult.
49. Slow Query Ratio,Percentage of database queries exceeding a specific latency threshold.,Data,DB Insights,High,Medium (DB Logs),&quot;&quot;&quot;Performance Debt&quot;&quot;—often due to missing indexes or N+1 query problems.&quot;
50. Data Null Rate,Percentage of unexpected nulls or format errors in critical data columns.,Data,dbt,Low,Hard (Data testing),&quot;&quot;&quot;Data Trust Debt&quot;&quot;—if data is dirty, downstream analytics and ML models are worthless.&quot;
51. ETL Failure Rate,Frequency of data pipeline job failures requiring manual retry.,Data,Airflow,High,Easy (Orchestrator),High failure rates indicate fragile data ingestion and lack of idempotency.
52. Core Web Vitals,&quot;Scores for LCP (Loading), FID (Interactivity), CLS (Visual Stability).&quot;,Engineering,Lighthouse,Medium,Easy (CI or Browser),&quot;&quot;&quot;Frontend Debt&quot;&quot;—poor scores hurt SEO and user retention.&quot;
53. Accessibility Violations,&quot;Count of automated accessibility errors (missing alt tags, contrast).&quot;,Engineering,axe-core,Low,Easy (Scanner),Legal and ethical debt; excludes users with disabilities and risks lawsuits.
54. App Binary Size,Total size of the IPA/APK downloaded by users.,Mobile,Store Connect,High,Easy (Store Metadata),&quot;Bloat leads to lower install conversion rates, especially in low-bandwidth markets.&quot;
55. Crash-Free Sessions,Percentage of mobile/web sessions that do not end in a crash.,Mobile,Crashlytics,High,Easy (SDK),The ultimate measure of stability; low rates destroy brand reputation.
56. API 5xx Error Rate,Percentage of server-side errors returned to clients.,Platform,Load Balancer,High,Easy (Logs),Indicates unhandled exceptions and poor error management in backend services.
57. Log Coverage %,Percentage of critical business paths that emit traceable logs.,Platform,Splunk / ELK,Low,Hard (Manual Audit),&quot;&quot;&quot;Observability Debt&quot;&quot;—if you can&apos;t see it, you can&apos;t debug it during an outage.&quot;
58. Mean Time To Detection,Average time between an issue starting and an alert firing.,Delivery,PagerDuty,Low,Hard (Incident Review),&quot;If MTTD is high, your customers are your monitoring system.&quot;
59. Sprint Spillover %,Percentage of story points committed vs. completed in a sprint.,Process,Jira,High,Medium (Jira Reports),&quot;High spillover indicates &quot;&quot;Planning Debt&quot;&quot;—poor estimation or unclear requirements.&quot;
60. Meeting Load,Average hours per day engineers spend in meetings vs. coding blocks.,Process,Calendar API,Low,Medium (API Integration),&quot;&quot;&quot;Focus Debt&quot;&quot;—engineers cannot pay down technical debt if they have no deep work time.&quot;
&lt;/code&gt;&lt;/pre&gt; 
&lt;hr&gt; 
&lt;h2&gt;Reading&lt;/h2&gt; 
&lt;h3&gt;Articles/Blogs/Essays&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt; &lt;p&gt;&quot;Towards an Ontology of Terms on Technical Debt&quot;: &quot;Technical debt is a term that has been used to describe the increased cost of changing or maintaining a system due to shortcuts taken during its development. As technical debt is a recent research area, its different types and their indicators are not organized yet. Therefore, this paper proposes an ontology of terms on technical debt in order to organize a common vocabulary for the area. The organized concepts derived from the results of a systematic literature mapping. The proposed ontology was evaluated in two steps. In the first one, some ontology design quality criteria were used. For the second one, a specialist in the area performed an initial evaluation. This work contributes to evolve the Technical Debt Landscape through the organization of the different types of technical debt and their indicators. We consider this an important contribution for both researchers and practitioners because this information was spread out in the literature hindering their use in research and development activities.&quot; &lt;a href=&quot;https://www.researchgate.net/publication/286010286_Towards_an_Ontology_of_Terms_on_Technical_Debt&quot;&gt;ResearchGate&lt;/a&gt; &lt;a href=&quot;/reading/development/Towards_an_Ontology_of_Terms_on_Technical_Debt.pdf&quot;&gt;PDF&lt;/a&gt; &lt;a href=&quot;https://pdfs.semanticscholar.org/3ab6/bd6fd72110a18f2d9d442cab03369a6017c5.pdf&quot;&gt;slides&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Martin Fowler:&lt;/p&gt; 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://martinfowler.com/bliki/TechnicalDebt.html&quot;&gt;Technical Debt&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://martinfowler.com/bliki/TechnicalDebtQuadrant.html&quot;&gt;Technical Debt Quadrant&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;SQALE (&lt;a href=&quot;https://en.wikipedia.org/wiki/SQALE&quot;&gt;Wikipedia&lt;/a&gt;): (Software Quality Assessment based on Lifecycle Expectations) is a method to support the evaluation of a software application source code. It is a generic method, independent of the language and source code analysis tools. The method is based on 4 main concepts: The quality model; The analysis model; The indices; The indicators. &lt;em&gt;(Website appears down--Wikipedia links go to 404s)&lt;/em&gt;&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;LeadDev:&lt;/p&gt; 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://leaddev.com/technical-direction/what-leaders-wrong-about-latent-cost-technical-debt&quot;&gt;What leaders get wrong about latent cost of technical debt&lt;/a&gt;: &lt;strong&gt;Problem:&lt;/strong&gt; &quot;Accruing technical debt isn’t necessarily a negative issue, and usually starts with good intentions. For instance, you may have made the call to accept a tech debt trade-off with the view to finishing a feature or meeting a deadline. But what happens when this becomes the norm – an ingrained component of the culture? I have seen the process of teams normalizing broken tests, sluggish builds, and tribal knowledge to the point that no one asks questions about it anymore. The longer this debt remains unaddressed, the more it interferes with the velocity of development and cognitive load, demotivating team members.&quot; ... Operational instability: &quot;Technical debt is not always about messy code; it is instability that sneaks into operations. Even the slightest quality problem in a regulated industry can turn into an existential threat. For example, an FAA audit conducted on Boeing found that the airplane company failed 33 out of 89 quality audits of their 737 Max production, because they were not following approved manufacturing processes. What is the cause of most of these failures? Missing documentation, haphazard tooling, and a lack of process; technical debt at scale. Similar to the weak APIs and undocumented programs in our world, these were not merely bugs, but time bombs that had systemic implications. The parallel fragility in software teams is that the &lt;a href=&quot;https://leaddev.com/reporting/solving-mean-time-repair-problem&quot;&gt;mean time to recovery&lt;/a&gt; (MTTR) is slower, and more often, rollbacks or on-call escalations are required. You may not be building planes, but when a service fails and no one understands who owns the fallback logic or how it is tested, you are closer to the risk than you imagine.&quot; ... The silencing effect of accumulated complexity: &quot;Systems are bound to become more complex as they evolve. However, when technical debt accumulates without oversight, such as a &lt;em&gt;lack of documentation&lt;/em&gt;, &lt;em&gt;unclear ownership&lt;/em&gt;, or &lt;em&gt;postponed refactoring&lt;/em&gt;, it accelerates complexity with no structural checks in place. When I was working in a fintech company, we learned that more than 40% of their microservices lacked identifiable owners, alongside the fact that uneven test coverage was rampant. Although the engineering department had grown at a high rate, no one bothered to assess the structural debt being incurred; issues such as tightly coupled services, legacy monoliths with hardcoded integrations, or ownership gaps that made critical systems unmaintainable. These findings illustrated how entrenched silence was in the team culture. Engineers cease to raise issues since this is how things are. New employees do not challenge inconsistencies since they presume it is deliberate. This normalization is what makes technical debt so dangerous; it becomes unseen, but highly influential.&quot; ... Strategic cost isn’t just financial: &quot;In addition to operational anarchy, debt constrains strategic options. It traps teams in unstable architectures, makes experimentation less desirable, and change more expensive. ... The moral is obvious: technical debt minimizes optionality. It denies organizations the flexibility to react to threats or innovate promptly when needed.&quot; &lt;strong&gt;Approach:&lt;/strong&gt; Start with full-scope visibility: &quot;[R]unning engineering surveys, conducting service maturity audits, and analyzing operational metrics. These efforts often revealed debt artifacts like unowned scripts, deprecated libraries, or undocumented APIs – elements that rarely show up in standard project tracking tools. Without a structured inventory like this, teams often focus their efforts on the most obvious pain points, such as slow tests or deployment delays, rather than the most strategically important ones. Full-scope visibility means going beyond surface issues to identify and document what’s genuinely slowing down delivery, scaling, or incident response. A more modern strategy for understanding the scope of your tech debt issue incorporates telemetry-driven scans. These will be able to surface broken pipelines and flaky tests. It’s also important to gather qualitative feedback: developer pain points, support tickets, and onboarding feedback. If new engineers repeatedly encounter setup failures or unclear integration steps with a specific legacy module during onboarding, that module is a visibility gap. It’s not just a one-time inconvenience; it reflects debt that directly affects developer experience and onboarding velocity. These recurring issues should be logged and scored, as they indicate systemic friction with measurable impact.&quot; Score by impact, not just frustration: &quot;Not every debt is alike. An abandoned configuration file is an inconvenience to engineers, but a closely-coupled authentication system that drags every product update has significantly steeper consequences. I suggest a light scoring model that is determined by three factors: &lt;em&gt;Severity&lt;/em&gt;: What is the downstream risk of this debt going unaddressed? &lt;em&gt;Frequency&lt;/em&gt;: How frequently does it create issues? &lt;em&gt;Strategic impact&lt;/em&gt;: Does the debt limit your ability to scale systems, like handling more users, data, or teams? Does it impede your ability to adapt your product direction, e.g., shift to a new architecture, integrate with new services, or launch a different feature? With a simple scoring system (e.g., 1-5), you will have a shared language to compare debts between teams and make decisions on what to work on first. Debt isn&apos;t solved by scope; it&apos;s solved by relevance.&quot; Choose the right fix: Refactor, replace, or bypass: &lt;em&gt;Refactor&lt;/em&gt; when the debt compounds daily costs; things like developer frustration, poor test coverage, or sluggish performance. For instance, in one of our back-end services, a shared utility function was frequently modified and regularly broke downstream dependencies. A simple refactor to isolate concerns reduced change failure rates by over 30% in just two sprints. &lt;em&gt;Replace&lt;/em&gt; when you’re scaling past its original intent, e.g., hardcoded workflows or in-memory stores. At a previous role, our real-time analytics relied on an in-memory store that had no sharding or durability guarantees. It worked at launch, but as our usage scaled 10x, data loss and throttling became common. We replaced it with a distributed store designed for high throughput and persistence. &lt;em&gt;Bypass&lt;/em&gt; when the effort-to-impact ratio is too high, fix only what’s necessary, and document the rest. One team I worked with had a legacy admin portal with hardcoded permissions logic. Rewriting it would have taken months, but it was rarely used. We documented its quirks, added a banner to warn users of limitations, and created a wrapper for the one feature it still supported.&lt;br&gt; The lesson: don’t assume all tech debt deserves your best engineering. Sometimes, clarity and containment are more valuable than cleanup.&quot; Accountability is a team sport: &quot;The ownership of the debt cannot rest with tech leads alone. Teams require incentives and rituals, such as quarterly debt review, shared dashboards, and making ownership based on service health scores. An organization I consulted with tied debt scores directly to performance reviews at the top management level, not as a stick, but as an indication that quality was not a choice. Within two quarters, they saw a 25% increase in resolved debt items and a measurable drop in incident frequency across critical systems, indicating that visibility and ownership alone can drive behavior change.&quot;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://brainhub.eu/library&quot;&gt;BrainHub&lt;/a&gt;:&lt;/p&gt; 
  &lt;ul&gt; 
   &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://brainhub.eu/library/tech-debt-puzzle&quot;&gt;Solving the Tech Debt Puzzle&lt;/a&gt;: A case study (Express/JS). &quot;Approach:&lt;/p&gt; 
    &lt;ul&gt; 
     &lt;li&gt;Performing a tech audit to highlight the problems, risks, and start to raise awareness.&lt;/li&gt; 
     &lt;li&gt;Connecting the technical challenges with business priorities.&lt;/li&gt; 
     &lt;li&gt;Establishing a testing strategy (unit tests didn’t fit, Testing Trophy was a solution).&lt;/li&gt; 
     &lt;li&gt;Adopting a structured approach that leverages testing, refactoring, and careful planning.&lt;/li&gt; 
     &lt;li&gt;Encapsulating legacy code within the existing system and developing new features in the Nest framework.&lt;/li&gt; 
     &lt;li&gt;Making incremental improvements through minor rewrites.&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://brainhub.eu/library/cost-of-technical-debt&quot;&gt;Business Costs of Technical Debt&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://brainhub.eu/library/refactoring-legacy-code-strategy&quot;&gt;Refactoring Legacy Code&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://brainhub.eu/library/refactoring-best-practices&quot;&gt;Top 7 Refactoring Techniques&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://brainhub.eu/library/technical-debt-in-microservices&quot;&gt;Technical Debt in Microservices&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://brainhub.eu/library/prioritizing-technical-debt-repayment&quot;&gt;Technical Debt Repayment&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://brainhub.eu/library/avoid-technical-bankruptcy-tips&quot;&gt;How to Avoid Technical Bankruptcy&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://brainhub.eu/library/technical-debt-metrics&quot;&gt;Tech Debt Metrics&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://brainhub.eu/library/technical-debt-ratio&quot;&gt;Tech Debt Ratio&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://brainhub.eu/library/how-to-deal-with-technical-debt&quot;&gt;Managing Tech Debt&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://brainhub.eu/library/tools-to-measure-technical-debt&quot;&gt;Tools to Measure Tech Debt&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://brainhub.eu/library/technical-debt-examples&quot;&gt;Examples&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://brainhub.eu/library/application-modernization-challenges&quot;&gt;Application Modernization Challenges&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://brainhub.eu/library/legacy-app-modernization-roadmap&quot;&gt;Legacy Application Modernization Roadmap - a Step-by-Step Guide&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://brainhub.eu/library/legacy-systems-examples&quot;&gt;Legacy Systems Examples&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://brainhub.eu/library/legacy-application-migration-to-cloud&quot;&gt;Legacy Application Migration to Cloud&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://brainhub.eu/library/cost-of-technical-debt&quot;&gt;Business Costs of Technical Debt&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://brainhub.eu/library/red-green-refactor-legacy-systems&quot;&gt;Red Green Refactor&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://brainhub.eu/library/strangler-pattern-legacy-modernization&quot;&gt;The Strangler Pattern for Legacy Modernization&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://brainhub.eu/library/monolith-to-microservices-using-strangler-pattern&quot;&gt;Monolith to Microservices Using Strangler Pattern&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://brainhub.eu/library/big-bang-migration-vs-trickle-migration&quot;&gt;Big Bang Migration vs Trickle Migration&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://brainhub.eu/library/top-data-migration-tools&quot;&gt;Top 15 Data Migration Tools&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://brainhub.eu/library/data-migration-challenges-risks-legacy-modernization&quot;&gt;Data Migration Challenges&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://brainhub.eu/library/data-migration-strategy-legacy-app&quot;&gt;Data Migration Strategy for a Legacy App&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://brainhub.eu/library/microservices-vs-monolith-which-to-use-when&quot;&gt;Microservices vs Monolith&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://brainhub.eu/library/monolith-better-than-microservices&quot;&gt;When Monolith Is Better Than Microservices&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://brainhub.eu/library/modular-monolith-architecture&quot;&gt;Modular Monolith – When to Choose It&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://brainhub.eu/library/master-data-management-strategy&quot;&gt;Master Data Management Strategy&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://brainhub.eu/library/cloud-migration-challenges&quot;&gt;Cloud Migration Challenges&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://brainhub.eu/library/mean-time-between-failures-mtbf&quot;&gt;Mean Time Between Failures&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://brainhub.eu/library/how-to-measure-lead-time-for-changes&quot;&gt;Lead Time for Changes&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://brainhub.eu/library/improve-software-delivery-speed&quot;&gt;Software Delivery Speed&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://brainhub.eu/library/how-to-measure-deployment-frequency&quot;&gt;How to Measure and Improve Deployment Frequency&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://brainhub.eu/library/change-failure-rate-best-practices&quot;&gt;Change Failure Rate&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://brainhub.eu/library/mean-time-to-detect-mttd-explained&quot;&gt;Mean Time to Detect (MTTD)&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://brainhub.eu/library/pull-request-size-best-practices&quot;&gt;Pull Request Size&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://fastwonderblog.com/2025/10/23/assessing-the-viability-of-open-source-projects/&quot;&gt;Assessing the Viability of Open Source Projects&lt;/a&gt;: &quot;Open source software is found in almost every codebase, but some open source projects are more viable than others over the long term. Many companies don’t have a rigorous process for selecting the most viable dependencies. Often product teams, or even individual software developers, select open source projects because they fill a particular technical need without any assessment of the viability of the project or the risks they might be taking by using it. Assessing the viability of open source projects, especially ones that have the potential to impact your business, is a good first step toward managing risk and reducing the chances of potential business disruptions.&quot;&lt;/p&gt; &lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>How to Read a Book</title>
      <link>https://tedneward.github.io/Research/reading/how-to-read-a-book/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">reading/how-to-read-a-book/index.html</guid>
      	<description>
	&lt;p&gt;&lt;em&gt;Some notes derived from &lt;a href=&quot;https://fs.blog/how-to-read-a-book/&quot;&gt;https://fs.blog/how-to-read-a-book/&lt;/a&gt;&lt;/em&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://www.amazon.com/How-Read-Book-Classic-Intelligent/dp/0671212095&quot;&gt;Book (Amazon)&lt;/a&gt;&lt;/p&gt; 
&lt;h3&gt;The Four Levels of Reading&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;Elementary Reading (reading to entertain) - elementary school&lt;/li&gt; 
 &lt;li&gt;Inspectional Reading (reading to inform) - high school/college&lt;/li&gt; 
 &lt;li&gt;Analytical Reading (reading to understand)&lt;/li&gt; 
 &lt;li&gt;Syntopical Reading (reading to master)&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;If you don’t learn the last two levels, you’ll go through life like a one-legged man in an ass-kicking contest.&lt;/p&gt; 
&lt;p&gt;This doesn’t mean that everything should be read the same way. It shouldn’t. Why you are reading should match how you are reading. Your level of effort needs to match the importance of the material. If you read a romance novel and legal document the same way, you’re in for a life of misery.&lt;/p&gt; 
&lt;h3&gt;Reading to Entertain&lt;/h3&gt; 
&lt;p&gt;This is the level of reading taught in our elementary schools. If you’re reading this website, you already know how.&lt;/p&gt; 
&lt;h3&gt;Reading to Inform&lt;/h3&gt; 
&lt;p&gt;Some people think skimming and reading quickly is a bad idea. It’s not. The point of a quick skim is to determine if the book is worth reading deeply in the first place. Most are not.&lt;/p&gt; 
&lt;p&gt;There are two kinds of inspectional reading:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Systematic skimming: Quickly skim the book. Read the introduction, table of contents, index, and inside cover. This shows you the key chapters and ideas. Jump in and out, reading a paragraph here and there.&lt;/li&gt; 
 &lt;li&gt;Superficial reading: This is a quick read. Don’t stop to think deeply. Don’t write things in the margin. Don’t look things up; keep going if you don’t understand something. Read most of the book, but read it quickly.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;At this point, you have the main idea. Often, that’s enough. Think about all the pop-psychology books. Simply skimming the introduction gives you 90% of the value.&lt;/p&gt; 
&lt;p&gt;Inspectional reading gives you the structure and an overview of the author’s arguments and opinions. Because you didn’t read deeply, you won’t understand all the nuances, but you’ll get the gist. Most times, you can stop right here. Put the book down and go on to the next one. But sometimes, you’ll want to know more about the book.&lt;/p&gt; 
&lt;h3&gt;Reading to Understand&lt;/h3&gt; 
&lt;p&gt;Francis Bacon once remarked, “some books are to be tasted, others to be swallowed, and some few to be chewed and digested.” You can think of analytical reading as doing that chewing and digesting. This is the real work of reading. If inspectional reading is the best you can do quickly, analytical reading is the best you can do with time. At this point, you start to engage your mind and do the work required to understand what’s being said. I recommend writing in your book and using our Blank Sheet notetaking method.&lt;/p&gt; 
&lt;p&gt;There are four rules to Analytical Reading&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Classify the book according to its kind and subject matter&lt;/li&gt; 
 &lt;li&gt;State what the whole book is about with the utmost brevity&lt;/li&gt; 
 &lt;li&gt;Enumerate its major parts in their order and relation, and outline these parts&lt;/li&gt; 
 &lt;li&gt;Define the problem or problems the author is trying to solve&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;You’ll probably notice that while those sound pretty easy, they involve a lot of work. Luckily, the inspectional reading you did earlier has primed you for this and made it easier. If you are reading to understand, you need to integrate the ideas into your head. You do the work of digesting the material and making it your own. Done correctly, this helps you understand the book. That does not mean, however, that you understand the broader subject. You can’t simply read one book or article and claim to be an expert. If you really want to master the subject, you need to dive into the subject entirely reading multiple books and comparing and contrasting them. That’s where syntopical reading comes in.&lt;/p&gt; 
&lt;h3&gt;Reading to Master&lt;/h3&gt; 
&lt;p&gt;Syntopical reading is the most demanding and challenging reading of all. Reading to master something involves reading many books on the same subject and comparing and contrasting ideas, vocabulary, and arguments. To do this, you must identify relevant passages, translate terminology, define the issues, explore issues through multiple lenses, and frame questions that need answering. The goal is not to achieve an overall understanding of any particular book but rather to understand the broader subject and develop deep fluency. Doing this means identifying and filling in your blind spots about the subject,&lt;/p&gt; 
&lt;p&gt;When reading to master something, there are four keys to keep in mind&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Identify the relevant passages: Find the right books and the key passages. You can’t simply outsource this to others. If you want to address your blind spots, you must do the work yourself.&lt;/li&gt; 
 &lt;li&gt;Translate and synthesize: Instead of using the author’s language, establish your own terms. This exercise in translation bridges different authors’ concepts and arguments.&lt;/li&gt; 
 &lt;li&gt;Formulate Your Questions: Focus on what you want to know, not just the author’s problems. Frame questions that multiple authors can answer. Be prepared: some questions might remain unanswered if authors didn’t consider them.&lt;/li&gt; 
 &lt;li&gt;Define the Issues and Analyze the Discussion: When a question has multiple answers, you’ve defined an issue that needs further work. &lt;a href=&quot;https://fs.blog/the-work-required-to-have-an-opinion/&quot;&gt;Understanding various perspectives helps form an intelligent opinion.&lt;/a&gt; &lt;strong&gt;&lt;em&gt;Don’t expect unchallenged truths; your answer lies in the conflict of opposing views.&lt;/em&gt;&lt;/strong&gt; The value lies in your informed dialogue with these authors and yourself.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Effective Note-Taking for Better Reading&lt;/h3&gt; 
&lt;p&gt;To enhance your reading, Adler recommends various note-taking techniques:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Underline major points&lt;/li&gt; 
 &lt;li&gt;Use vertical lines in the margin for longer passages&lt;/li&gt; 
 &lt;li&gt;Mark important statements with stars or asterisks&lt;/li&gt; 
 &lt;li&gt;Number sequences of points in an argument&lt;/li&gt; 
 &lt;li&gt;Cross-reference related ideas with page numbers&lt;/li&gt; 
 &lt;li&gt;Circle keywords or phrases&lt;/li&gt; 
 &lt;li&gt;Write questions and answers in the margins&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;The Demanding Reader&lt;/h3&gt; 
&lt;p&gt;The demanding reader asks the right questions and seeks answers.&lt;/p&gt; 
&lt;p&gt;There are four main questions you need to ask of every book:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;What is this book about?&lt;/li&gt; 
 &lt;li&gt;What is being said in detail, and how?&lt;/li&gt; 
 &lt;li&gt;Is this book true — in whole or in part?&lt;/li&gt; 
 &lt;li&gt;What of it?&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Software Foundations</title>
      <link>https://tedneward.github.io/Research/reading/development/software-foundations/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">reading/development/software-foundations/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://softwarefoundations.cis.upenn.edu/&quot;&gt;Website&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;The principal novelty of the series is that every detail is one hundred percent formalized and machine-checked: the entire text of each volume, including the exercises, is literally a &quot;proof script&quot; for the Coq proof assistant.&lt;/p&gt; 
&lt;p&gt;The exposition is intended for a broad range of readers, from advanced undergraduates to PhD students and researchers. No specific background in logic or programming languages is assumed, though a degree of mathematical maturity is helpful. A one-semester course can expect to cover Logical Foundations plus most of Programming Language Foundations or Verified Functional Algorithms, or selections from both.&lt;/p&gt; 
&lt;p&gt;Six parts:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://softwarefoundations.cis.upenn.edu/lf-current/index.html&quot;&gt;Logical Foundations (Vol 1)&lt;/a&gt; (&lt;a href=&quot;https://softwarefoundations.cis.upenn.edu/lf-current/lf.tgz&quot;&gt;Download&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://softwarefoundations.cis.upenn.edu/plf-current/index.html&quot;&gt;Programming Language Foundations (Vol 2)&lt;/a&gt; (&lt;a href=&quot;https://softwarefoundations.cis.upenn.edu/plf-current/plf.tgz&quot;&gt;Download&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://softwarefoundations.cis.upenn.edu/qc-current/index.html&quot;&gt;QuickChick: Property-Based Testing in Coq (Vol 3)&lt;/a&gt; (&lt;a href=&quot;https://softwarefoundations.cis.upenn.edu/qc-current/qc.tgz&quot;&gt;Download&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://softwarefoundations.cis.upenn.edu/vc-current/index.html&quot;&gt;Verifiable C (Vol 4)&lt;/a&gt; (&lt;a href=&quot;https://softwarefoundations.cis.upenn.edu/vc-current/vc.tgz&quot;&gt;Download&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://softwarefoundations.cis.upenn.edu/slf-current/index.html&quot;&gt;Separation Logic Foundations (Vol 5)&lt;/a&gt; (&lt;a href=&quot;https://softwarefoundations.cis.upenn.edu/slf-current/slf.tgz&quot;&gt;Download&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://softwarefoundations.cis.upenn.edu/vfa-current/index.html&quot;&gt;Verified Functional Algorithms&lt;/a&gt; (&lt;a href=&quot;https://softwarefoundations.cis.upenn.edu/vfa-current/vfa.tgz&quot;&gt;Download&lt;/a&gt;)&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>State Machine (FSM)</title>
      <link>https://tedneward.github.io/Research/reading/development/state-machine/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">reading/development/state-machine/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;http://en.wikipedia.org/wiki/Finite-state_machine&quot;&gt;Wikipedia&lt;/a&gt; | &lt;a href=&quot;https://www.reddit.com/r/statemachines/&quot;&gt;r/statemachines&lt;/a&gt;&lt;/p&gt; 
&lt;h2&gt;Overview&lt;/h2&gt; 
&lt;h3&gt;An introduction&lt;/h3&gt; 
&lt;p&gt;From &lt;a href=&quot;https://excalidraw.com/&quot;&gt;here&lt;/a&gt; there is a really nice summary of FSMs:&lt;/p&gt; 
&lt;ol&gt; 
 &lt;li&gt; &lt;p&gt;What is a state machine?&lt;/p&gt; &lt;p&gt;A state machine is an abstract concept that describes&lt;/p&gt; 
  &lt;ul&gt; 
   &lt;li&gt;being in only one &apos;finite state&apos; at any time&lt;/li&gt; 
   &lt;li&gt;where there is an &quot;initial state&quot;&lt;/li&gt; 
   &lt;li&gt;and &quot;transitions&quot; between states triggered by &quot;events&quot;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;States: A finite state describes some &quot;mode&quot; or &quot;status&quot; that a system (e.g., an app or component) is in. State machines always start in an initial state. Final states mark that a machine is &quot;done&quot;. Extended state describes contextual data that is not finite, but relevant to the machine. Don&apos;t confuse finite (&quot;countable&quot;) states with extended (&quot;infinite&quot;) states!&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Events &amp;amp; Transitions: An event is a &quot;signal&quot; that something happened. Events can trigger &quot;transitions&quot; between states. Transitions are always zero-time; they happen instantaneously. (Promises &amp;amp; async can still be modeled as a state machine. Just think of &quot;awaiting&quot; as a finite state.) Events are distinguished by a finite set of types and sometimes carry extra data.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Actions: Actions are side-effects that are executed due to events. Transition (&quot;do&quot;) actions are executed due to transitions. (These are characterisitic of Mealy machines). Entry actions are executed whenever a state is entered. Exit actions are executed whenever a state is exited. (These are characteristic of Moore machines.)&lt;/p&gt; &lt;/li&gt; 
&lt;/ol&gt; 
&lt;h3&gt;Another introduction&lt;/h3&gt; 
&lt;p&gt;Finite state machines are a computation model, it consists of a machine with a finite number of states. A finite state machine has a finite number of events, to move from one state to another we have something called transitions. These transitions are triggered after a specific event, each transition expects an input, after its triggered, it will change to a specific state depending on the current state and the event.&lt;/p&gt; 
&lt;p&gt;We can simplify a finite state machine in 4 parts:&lt;/p&gt; 
&lt;ol&gt; 
 &lt;li&gt;A finite number of states.&lt;/li&gt; 
 &lt;li&gt;A finite number of events.&lt;/li&gt; 
 &lt;li&gt;An initial state.&lt;/li&gt; 
 &lt;li&gt;A transition will be triggered after a specific event and will change to a specific state depending on the current state and the event.&lt;/li&gt; 
&lt;/ol&gt; 
&lt;p&gt;Finite state machines can be used to simulate sequential logic, let&apos;s take as an example of a traffic light.&lt;/p&gt; 
&lt;p&gt;We know that a traffic light has only 3 possible states: green, yellow, and red. To change from one state to another, we will use it as an input integer representing seconds. When the input is 60, the machine will trigger an event and transition to another state depending on the current state and the event, in our case, the seconds.&lt;/p&gt; 
&lt;p&gt;We can observe finite state machines not only inside the software development but in our real world as well. You can think about almost anything and use finite state machines for it. By having a finite number of states, it reduces drastically the possibility of having unexpected side-effects in your application, your application will get more consistent, well-written, and maintainable.&lt;/p&gt; 
&lt;h3&gt;Further Reading&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Finite-state_machine&quot;&gt;Finite-state_machine&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://stackabuse.com/theory-of-computation-finite-state-machines/&quot;&gt;Theory of Computation - Finite State Machines&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.i-programmer.info/babbages-bag/223-finite-state-machines.html&quot;&gt;Finite State Machines&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://link.springer.com/chapter/10.1007/978-3-319-62533-1_4&quot;&gt;Elements of Robotics - Finite State Machines&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.inf.ufsc.br/~joao.dovicchi/pos-ed/pos/exerc/machines2.pdf&quot;&gt;Finite State Machines&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.smashingmagazine.com/2018/01/rise-state-machines/&quot;&gt;The Rise Of The State Machines&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Concepts&lt;/h2&gt; 
&lt;p&gt;In the finite state machine model, we have a few different concepts that it’s very important to learn about. There are two types of finite state machines: deterministic state automaton and non-deterministic state automaton. There are a few differences between those two types.&lt;/p&gt; 
&lt;p&gt;A deterministic state automaton is a finite state machine with a finite number of states and input symbols. A transition is defined in every state for every input symbol. Each input symbol will determine which state the machine will move. A deterministic finite automaton machine can only be in one state at a time, and transition to one state at a time.&lt;/p&gt; 
&lt;p&gt;A non-deterministic finite automaton has a finite number of states and a finite number of input symbols. In a nondeterministic finite automaton, for each state and input symbol, it can be one or more output states. NFAs can be in one or more states at once.&lt;/p&gt; 
&lt;p&gt;If you’re wondering, an automaton is the plural of automata. Finite state machines are also known as finite-state automata or finite-state automaton.&lt;/p&gt; 
&lt;h3&gt;Deterministic Finite Automaton (DFAs)&lt;/h3&gt; 
&lt;p&gt;A deterministic finite automaton finite state machine with a finite number of inputs symbols. For each input symbol, it will determine which state the machine will move.&lt;br&gt; A deterministic finite automaton machine can only be in one state at a time, and transition to one state at a time.&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Deterministic_finite_automaton&quot;&gt;Deterministic finite automaton&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://lambda.uta.edu/cse5317/notes/node8.html&quot;&gt;Deterministic Finite Automata (DFAs)&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.cs.uic.edu/~ajayk/c301/CS301-UIC/Lecture-02-DFA.pdf&quot;&gt;Deterministic Finite Automata (DFAs)&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.cs.wcupa.edu/rkline/fcs/dfas.html&quot;&gt;Deterministic Finite Automata (DFA)&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.tutorialspoint.com/automata_theory/deterministic_finite_automaton.htm&quot;&gt;Deterministic Finite Automaton&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.cse.chalmers.se/~coquand/AUTOMATA/o2.pdf&quot;&gt;Deterministic Finite Automata&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://web.cs.ucdavis.edu/~rogaway/classes/120/spring13/eric-dfa.pdf&quot;&gt;Applications of Deterministic Finite Automata&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://cseweb.ucsd.edu/classes/sp15/cse191-e/lec1.html&quot;&gt;Deterministic Finite Automata (DFA)&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Non-deterministic Finite Automaton (NFAs)&lt;/h3&gt; 
&lt;p&gt;A nondeterministic finite automaton has a finite number of states and a finite number of input symbols. In a nondeterministic finite automaton, for each state and input symbol, it can be one or more output states. NFAs can be in one or more states at once.&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Nondeterministic_finite_automaton&quot;&gt;Nondeterministic finite automaton&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://cs.ru.nl/~jrot/TnA2017/lecture3.pdf&quot;&gt;Non-deterministic Finite Automata&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://courses.engr.illinois.edu/cs374/sp2017/notes/models/NFAnotes.pdf&quot;&gt;Nondeterministic Finite Automata&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.tutorialspoint.com/automata_theory/non_deterministic_finite_automaton.htm&quot;&gt;Non-deterministic Finite Automaton&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://cs.uwaterloo.ca/~watrous/CS360/Lectures/03.pdf&quot;&gt;Nondeterministic finite automata&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://people.seas.harvard.edu/~cs125/fall16/lec12.pdf&quot;&gt;Nondeterministic Finite Automata&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.inf.ed.ac.uk/teaching/courses/inf1/cl/notes/Comp3.pdf&quot;&gt;Non-deterministic Finite State Machines&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://people.cs.clemson.edu/~goddard/texts/theoryOfComputation/3a.pdf&quot;&gt;Nondeterministic Finite Automata&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.javatpoint.com/non-deterministic-finite-automata&quot;&gt;NFA (Non-Deterministic finite automata)&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Mealy Machine&lt;/h3&gt; 
&lt;p&gt;A mealy machine is a machine where the output value is determined by the input and the current state. For each input and state in a Mealy machine, one transition is possible.&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Mealy_machine&quot;&gt;Mealy machine&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.javatpoint.com/automata-mealy-machine&quot;&gt;Mealy Machine&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://ncatlab.org/nlab/show/Mealy+machine&quot;&gt;Mealy machine&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://xlinux.nist.gov/dads/HTML/mealyMachine.html&quot;&gt;Mealy machine&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.slideshare.net/arifsiyal7/mealy-state-machine&quot;&gt;Mealy state machine&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://link.springer.com/chapter/10.1007/978-3-642-05089-3_14&quot;&gt;Inferring Mealy Machines&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.tutorialspoint.com/automata_theory/moore_and_mealy_machines.htm&quot;&gt;Moore and Mealy Machines&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.geeksforgeeks.org/mealy-and-moore-machines-in-toc/&quot;&gt;Mealy and Moore Machines in TOC&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Moore Machine&lt;/h3&gt; 
&lt;p&gt;A Moore machine is a machine where the output is determined by only its current state. The output depends only on the present state and it&apos;s the same output every time the machine enters that state.&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Moore_machine&quot;&gt;Moore machine&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.javatpoint.com/automata-moore-machine&quot;&gt;Moore Machine&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://xlinux.nist.gov/dads/HTML/mooreMachine.html&quot;&gt;Moore Machine&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.electronics-tutorial.net/finite-state-machines/State-Machine-Fundamentals/Moore-Finite-State-Machine/&quot;&gt;Moore Finite State Machine&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www2.elo.utfsm.cl/~lsb/elo211/aplicaciones/katz/chapter8/chapter08.doc4.html&quot;&gt;Moore and Mealy Machine Design Procedure&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Reading&lt;/h2&gt; 
&lt;h3&gt;Articles/Blogs/Essays&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;http://blog.manuvra.com/modeling-a-simple-ai-behavior-using-a-finite-state-machine/&quot;&gt;Modeling AI&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Books&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://link.springer.com/book/10.1007/978-3-031-43973-5&quot;&gt;Programming-Based Formal Languages and Automata Theory&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Formal representation&lt;/h2&gt; 
&lt;h3&gt;SMC&lt;/h3&gt; 
&lt;p&gt;&lt;a href=&quot;/languages/smc&quot;&gt;State Machine Compiler&lt;/a&gt;&lt;/p&gt; 
&lt;h3&gt;SCXML&lt;/h3&gt; 
&lt;p&gt;&lt;a href=&quot;/formats/scxml&quot;&gt;State Machine notation for control abstraction specification&lt;/a&gt;.&lt;/p&gt; 
&lt;h3&gt;Statecharts&lt;/h3&gt; 
&lt;p&gt;Sometimes we need something more sophisticated and complex, and that&apos;s when a finite state machine cannot help us.&lt;/p&gt; 
&lt;p&gt;Statecharts are an extension of traditional finite state machines, the main difference of statecharts is that it can have a hierarchical state, states can contain nested state inside them. The reason for this is simple, not all applications in the world can be described as flat multi numbers of states, sometimes we need to have nested states.&lt;/p&gt; 
&lt;p&gt;Statecharts also bring us a few extra features such as actions, entry and exit actions, guard conditions, deferred events, etc.&lt;/p&gt; 
&lt;h4&gt;Further Reading&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://statecharts.github.io/&quot;&gt;Welcome to Statecharts&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.inf.ed.ac.uk/teaching/courses/seoc/2005_2006/resources/statecharts.pdf&quot;&gt;Statecharts: A Visual Formalism for Complex Systems&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://help.anylogic.com/index.jsp?topic=%2Fcom.anylogic.help%2Fhtml%2Fstatecharts%2FStatecharts.html&quot;&gt;Statecharts&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://homepage.cs.uiowa.edu/~fleck/181content/statecharts.pdf&quot;&gt;The Statecharts Perspective&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Languages&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://states-language.net/&quot;&gt;states-language&lt;/a&gt;: Amazon States Language. A JSON-based language used to describe state machines declaratively. The state machines thus defined may be executed by software. In this document, the software is referred to as &quot;the interpreter&quot;.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;/languages/dotnet/coyote&quot;&gt;Coyote&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/morazanm/fsm&quot;&gt;fsm&lt;/a&gt;: A DSL for the Automata Theory Classroom&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;/languages/p&quot;&gt;P&lt;/a&gt; and/or &lt;a href=&quot;/languages/dotnet/psharp&quot;&gt;P#&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;/languages/plaid&quot;&gt;Plaid&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;/languages/ragel&quot;&gt;Ragel&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;Archived &lt;a href=&quot;https://web.archive.org/web/20120722084226/http://www-fp.cs.st-andrews.ac.uk/hume/index.shtml&quot;&gt;Hume&lt;/a&gt;: Hume combines functional programming ideas with ideas from finite state automata. Automata are used to structure communicating programs into a series of &quot;boxes&quot;, where each box maps inputs to outputs in a purely functional way using high-level pattern-matching. It is structured as a series of levels, each of which exposes different machine properties.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Libraries&lt;/h2&gt; 
&lt;h3&gt;C++&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/erikzenker/hsm&quot;&gt;hsm&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.boost.org/doc/libs/1_73_0/libs/msm/doc/HTML/index.html&quot;&gt;msm&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://boost-experimental.github.io/sml/index.html&quot;&gt;sml&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.boost.org/doc/libs/1_73_0/libs/statechart/doc/index.html&quot;&gt;Statechart&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Go&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/looplab/fsm&quot;&gt;fsm&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/qor/transition&quot;&gt;transition&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/qmuntal/stateless&quot;&gt;stateless&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/ryanfaerman/fsm&quot;&gt;fsm&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/bykof/stateful&quot;&gt;stateful&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/aglyzov/ws-machine&quot;&gt;ws-machine&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/dyrkin/fsm&quot;&gt;fsm&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/Gurpartap/statemachine-go&quot;&gt;statemachine-go&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/calebwin/go-sm&quot;&gt;go-sm&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/theckman/go-fsm&quot;&gt;go-fsm&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/igorrius/go-fsm&quot;&gt;go-fsm&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Java&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/hekailiang/squirrel&quot;&gt;squirrel-foundation&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/spring-projects/spring-statemachine&quot;&gt;Spring Statemachine&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/stateless4j/stateless4j&quot;&gt;stateless4j&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/Beh01der/EasyFlow&quot;&gt;EasyFlow&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/statefulj/statefulj&quot;&gt;StatefulJ&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/j-easy/easy-states&quot;&gt;Easy States&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/UnquietCode/JState&quot;&gt;JState&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/doridori/Engine&quot;&gt;Engine&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/thehiflyer/Fettle&quot;&gt;Fettle&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/camelot-framework/yatomata&quot;&gt;Yatomata&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/zevada/stateful&quot;&gt;stateful&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/davidmoten/state-machine&quot;&gt;state-machine&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;JavaScript&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/davidkpiano/xstate&quot;&gt;XState&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/nickuraltsev/finity&quot;&gt;finity&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/vstirbu/fsm-as-promised&quot;&gt;fsm-as-promised&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/StoneCypher/jssm&quot;&gt;jssm&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/jakesgordon/javascript-state-machine&quot;&gt;JavaScript State Machine&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/brucou/kingly&quot;&gt;kingly&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/ifandelse/machina.js&quot;&gt;Machina&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/tomas2387/maquinaria&quot;&gt;maquinaria&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/bredele/mood&quot;&gt;mood&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/choojs/nanostate&quot;&gt;nanostate&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/MicheleBertoli/react-automata&quot;&gt;React Automata&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/matthewp/robot&quot;&gt;Robot&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/ericelliott/redux-dsm&quot;&gt;redux-dsm&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/mheiber/redux-machine&quot;&gt;redux-machine&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/steelbreeze/state&quot;&gt;state&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/davestewart/javascript-state-machine&quot;&gt;State Machine&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/shuckster/statebot&quot;&gt;Statebot&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/fschaefer/Stately.js&quot;&gt;Stately&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/krasimir/stent&quot;&gt;Stent&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Kotlin&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/KStateMachine/kstatemachine&quot;&gt;KStateMachine&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://open.jumpco.io/projects/kfsm.html&quot;&gt;https://open.jumpco.io/projects/kfsm.html&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Python&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/pytransitions/transitions&quot;&gt;transitions&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/DLR-RM/RAFCON&quot;&gt;RAFCON&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/viewflow/django-fsm&quot;&gt;django-fsm&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/glyph/automat&quot;&gt;automat&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/jtushman/state_machine&quot;&gt;state_machine&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/rbarrois/xworkflows&quot;&gt;xworkflows&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/vikingco/django-states2&quot;&gt;django-states2&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/fgmacedo/python-statemachine&quot;&gt;python-statemachine&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/ScatterHQ/machinist&quot;&gt;machinist&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/nsi-iff/fluidity&quot;&gt;fluidity&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/openstack/automaton&quot;&gt;automaton&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/pgularski/pysm&quot;&gt;pysm&lt;/a&gt; &lt;a href=&quot;https://pysm.readthedocs.io/en/latest/&quot;&gt;Docs&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/thomasquintana/declarative-fsm&quot;&gt;declarative-fsm&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/nazavode/automaton&quot;&gt;automaton&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Ruby&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/aasm/aasm&quot;&gt;aasm&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/pluginaweek/state_machine&quot;&gt;state_machine&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/gocardless/statesman&quot;&gt;statesman&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/piotrmurach/finite_machine&quot;&gt;finite_machine&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/state-machines/state_machines&quot;&gt;state_machines&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/troessner/transitions&quot;&gt;transitions&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/amatsuda/stateful_enum&quot;&gt;stateful_enum&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/soveran/micromachine&quot;&gt;micromachine&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/ryan-allen/workflow&quot;&gt;workflow&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/rtwomey/stately&quot;&gt;stately&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/opyh/motion-state-machine&quot;&gt;motion-state-machine&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/emancu/aquam&quot;&gt;aquam&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Shell&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/shuckster/statebot-sh&quot;&gt;Statebot-sh&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Swift&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/sergebouts/hsm&quot;&gt;hsm&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Static analysis tools - benchmarking</title>
      <link>https://tedneward.github.io/Research/reading/development/static-analysis-benchmarking/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">reading/development/static-analysis-benchmarking/index.html</guid>
      	<description>
	&lt;ul&gt; 
 &lt;li&gt;A Comparison of Static Analysis Tools for Vulnerability Detection in C/C++ Code 
  &lt;ul&gt; 
   &lt;li&gt;SYNASC 2017&lt;/li&gt; 
   &lt;li&gt;Andrei Arusoaie, Ștefan Ciobâcă, Vlad Crăciun, Dragoș Gavriluț, Dorel Lucanu&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://profs.info.uaic.ro/~stefan.ciobaca/synasc2017.pdf&quot;&gt;https://profs.info.uaic.ro/~stefan.ciobaca/synasc2017.pdf&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Analyzing the State of Static Analysis: A Large-Scale Evaluation in Open Source Software 
  &lt;ul&gt; 
   &lt;li&gt;Software Analysis, Evolution, and Reengineering (SANER) 2016&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://ieeexplore.ieee.org/document/7476667/&quot;&gt;http://ieeexplore.ieee.org/document/7476667/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.slideshare.net/inventitech/analyzing-the-state-of-static-analysis-a-largescale-evaluation-in-open-source-software-60473247&quot;&gt;https://www.slideshare.net/inventitech/analyzing-the-state-of-static-analysis-a-largescale-evaluation-in-open-source-software-60473247&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;2015 Master’s Thesis: &lt;a href=&quot;https://repository.tudelft.nl/islandora/object/uuid:3d834130-8dd7-420a-9af9-6e77761cdad6/&quot;&gt;https://repository.tudelft.nl/islandora/object/uuid:3d834130-8dd7-420a-9af9-6e77761cdad6/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Automated Customized Bug-Benchmark Generation 
  &lt;ul&gt; 
   &lt;li&gt;IEEE SCAM 2019&lt;/li&gt; 
   &lt;li&gt;Vineeth Kashyap, Jason Ruchti, Lucja Kot, Emma Turetsky, Rebecca Swords, David Melski, Eric Schulte&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://arxiv.org/abs/1901.02819&quot;&gt;https://arxiv.org/abs/1901.02819&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.dropbox.com/sh/f3p1wbomv93fz78/AABzXcLzqp5zkx75nQym6gJPa&quot;&gt;https://www.dropbox.com/sh/f3p1wbomv93fz78/AABzXcLzqp5zkx75nQym6gJPa&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Benchmark Software for Evaluation of Software Analysis Tools 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/Toyota-ITC-SSD/Software-Analysis-Benchmark&quot;&gt;https://github.com/Toyota-ITC-SSD/Software-Analysis-Benchmark&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Static analysis benchmarks from Toyota ITC - &lt;a href=&quot;https://github.com/regehr/itc-benchmarks&quot;&gt;https://github.com/regehr/itc-benchmarks&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;How Toyota Picks Software Tools 
  &lt;ul&gt; 
   &lt;li&gt;EETimes, August 11, 2015; Bernard Cole&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.eetimes.com/author.asp?section_id=36&amp;amp;doc_id=1327387&quot;&gt;https://www.eetimes.com/author.asp?section_id=36&amp;amp;doc_id=1327387&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://web.archive.org/web/20150815120014/http://www.eetimes.com/author.asp?section_id=36&amp;amp;doc_id=1327387&quot;&gt;http://web.archive.org/web/20150815120014/http://www.eetimes.com/author.asp?section_id=36&amp;amp;doc_id=1327387&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Quantitative Evaluation of Static Analysis Tools 
  &lt;ul&gt; 
   &lt;li&gt;Software Reliability Engineering Workshops (ISSREW) 2014&lt;/li&gt; 
   &lt;li&gt;Shinichi Shiraishi, Veena Mohan, Hemalatha Marimuthu&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://dl.acm.org/citation.cfm?id=2706360&quot;&gt;https://dl.acm.org/citation.cfm?id=2706360&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Software Assurance Reference Dataset (SARD) 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://samate.nist.gov/SARD/&quot;&gt;https://samate.nist.gov/SARD/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Test Suites - &lt;a href=&quot;https://samate.nist.gov/SRD/testsuite.php&quot;&gt;https://samate.nist.gov/SRD/testsuite.php&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Static Analysis Benchmarks 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://blog.regehr.org/archives/1217&quot;&gt;https://blog.regehr.org/archives/1217&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Test Suites for Benchmarks of Static Analysis Tools 
  &lt;ul&gt; 
   &lt;li&gt;IEEE International Symposium on Software Reliability Engineering (ISSRE) 2015&lt;/li&gt; 
   &lt;li&gt;Shinichi Shiraishi, Veena Mohan, and Hemalatha Marimuthu&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.researchgate.net/publication/283548090_Test_Suites_for_Benchmarks_of_Static_Analysis_Tools&quot;&gt;https://www.researchgate.net/publication/283548090_Test_Suites_for_Benchmarks_of_Static_Analysis_Tools&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Towards Automatically Generating a Sound and Complete Dataset for Evaluating Static Analysis Tools 
  &lt;ul&gt; 
   &lt;li&gt;NDSS Workshop on Binary Analysis Research (BAR) 2019&lt;/li&gt; 
   &lt;li&gt;Aravind Machiry, Nilo Redini, Eric Gustafson, Hojjat Aghakhani, Christopher Kruegel, Giovanni Vigna&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://ruoyuwang.me/bar2019/pdfs/bar2019-final90.pdf&quot;&gt;https://ruoyuwang.me/bar2019/pdfs/bar2019-final90.pdf&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/ucsb-seclab/autofacts&quot;&gt;https://github.com/ucsb-seclab/autofacts&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Toyota ITC Benchmark 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://runtimeverification.com/match/1.0-SNAPSHOT/docs/benchmark/&quot;&gt;https://runtimeverification.com/match/1.0-SNAPSHOT/docs/benchmark/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Using Benchmarks to Assess Static Analysis Tools 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;http://blogs.grammatech.com/using-benchmarks-to-assess-static-analysis-tools&quot;&gt;http://blogs.grammatech.com/using-benchmarks-to-assess-static-analysis-tools&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Differentially testing soundness and precision of program analyzers 
  &lt;ul&gt; 
   &lt;li&gt;International Symposium on Software Testing and Analysis 2019&lt;/li&gt; 
   &lt;li&gt;Christian Klinger, Maria Christakis, Valentin Wüstholz&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://arxiv.org/abs/1812.05033&quot;&gt;https://arxiv.org/abs/1812.05033&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Quickchecking Static Analysis Properties 
  &lt;ul&gt; 
   &lt;li&gt;Testing, Verification and Reliability 27(6) 2017&lt;/li&gt; 
   &lt;li&gt;Jan Midtgaard, Anders Møller&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://janmidtgaard.dk/papers/Midtgaard-Moeller%3aSTVR17.pdf&quot;&gt;http://janmidtgaard.dk/papers/Midtgaard-Moeller%3aSTVR17.pdf&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Test suites for benchmarks of static analysis tools 
  &lt;ul&gt; 
   &lt;li&gt;Software Reliability Engineering Workshops (ISSREW) 2015&lt;/li&gt; 
   &lt;li&gt;Shinichi Shiraishi, Veena Mohan, Hemalatha Marimuthu&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://ieeexplore.ieee.org/document/7392027/&quot;&gt;http://ieeexplore.ieee.org/document/7392027/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Testing Static Analyses for Precision and Soundness 
  &lt;ul&gt; 
   &lt;li&gt;CGO 2020&lt;/li&gt; 
   &lt;li&gt;Jubi Taneja, Zhengyang Liu, and John Regehr&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://doi.org/10.1145/3368826.3377927&quot;&gt;https://doi.org/10.1145/3368826.3377927&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Testing Static Analyzers with Randomly Generated Programs 
  &lt;ul&gt; 
   &lt;li&gt;NFM 2012: NASA Formal Methods&lt;/li&gt; 
   &lt;li&gt;Pascal Cuoq, Benjamin Monate, Anne Pacalet, Virgile Prevosto, John Regehr, Boris Yakobowski, Xuejun Yang&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://blog.frama-c.com/public/csmith.pdf&quot;&gt;http://blog.frama-c.com/public/csmith.pdf&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Towards Scalable Translation Validation of Static Analyzers 
  &lt;ul&gt; 
   &lt;li&gt;ROSAEC Technical Report ROSAEC-2014-003, Nov 2014&lt;/li&gt; 
   &lt;li&gt;Jeehoon Kang, Sungkeun Cho, Joonwon Choi, Chung-Kil Hur, Kwangkeun Yi&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://sf.snu.ac.kr/gil.hur/publications/ROSAEC_2014_003.pdf&quot;&gt;http://sf.snu.ac.kr/gil.hur/publications/ROSAEC_2014_003.pdf&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Systematic Approaches for Increasing Soundness and Precision of Static Analyzers 
  &lt;ul&gt; 
   &lt;li&gt;State Of the Art in Program Analysis (SOAP) 2017&lt;/li&gt; 
   &lt;li&gt;Esben Sparre Andreasen, Anders Møller, Benjamin Barslev Nielsen&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://pldi17.sigplan.org/event/soap-2017-papers-systematic-approaches-for-increasing-soundness-and-precision-of-static-analyzers&quot;&gt;https://pldi17.sigplan.org/event/soap-2017-papers-systematic-approaches-for-increasing-soundness-and-precision-of-static-analyzers&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://cs.au.dk/~amoeller/papers/tajsexperience/paper.pdf&quot;&gt;https://cs.au.dk/~amoeller/papers/tajsexperience/paper.pdf&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Verasco, a formally verified C static analyzer 
  &lt;ul&gt; 
   &lt;li&gt;A Formally-Verified C Static Analyzer 
    &lt;ul&gt; 
     &lt;li&gt;POPL 2015&lt;/li&gt; 
     &lt;li&gt;Jacques-Henri Jourdan, Vincent Laporte, Sandrine Blazy, Xavier Leroy, David Pichardie&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://hal.inria.fr/hal-01078386&quot;&gt;https://hal.inria.fr/hal-01078386&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://xavierleroy.org/publi/verasco-popl2015.pdf&quot;&gt;https://xavierleroy.org/publi/verasco-popl2015.pdf&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;Microsoft Research 2016; Jacques Henri Jourdan 
    &lt;ul&gt; 
     &lt;li&gt;&quot;the design and soundness proof of Verasco, a formally verified static analyzer for most of the ISO C99 language (excluding recursion and dynamic allocation), developed using the Coq proof assistant.&quot;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=0pUueg3Dslo&quot;&gt;https://www.youtube.com/watch?v=0pUueg3Dslo&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;Checking a Checker - Verasco: a Formally Verified C Static Analyzer 
    &lt;ul&gt; 
     &lt;li&gt;2016 PhD Dissertation; Jacques-Henri Jourdan&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://jhjourdan.mketjh.fr/thesis_jhjourdan.pdf&quot;&gt;https://jhjourdan.mketjh.fr/thesis_jhjourdan.pdf&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Verified Translation Validation of Static Analyses 
  &lt;ul&gt; 
   &lt;li&gt;Computer Security Foundations Symposium 2017&lt;/li&gt; 
   &lt;li&gt;Gilles Barthe, Sandrine Blazy, Vincent Laporte, David Pichardie, Alix Trieu&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://hal.inria.fr/hal-01588422/&quot;&gt;https://hal.inria.fr/hal-01588422/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Readings on operating systems</title>
      <link>https://tedneward.github.io/Research/reading/development/operating-systems/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">reading/development/operating-systems/index.html</guid>
      	<description>
	&lt;h2&gt;General&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;http://markburgess.org/os/os.pdf&quot;&gt;A short introduction to operating systems (2001)&lt;/a&gt; - Mark Burgess (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.bottomupcs.com&quot;&gt;Computer Science from the Bottom Up&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/SamyPesse/How-to-Make-a-Computer-Operating-System&quot;&gt;How to Make a Computer Operating System&lt;/a&gt; (:construction: &lt;em&gt;in process&lt;/em&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://mikeos.sourceforge.net/write-your-own-os.html&quot;&gt;How to write a simple operating system in assembly language&lt;/a&gt; - Mike Saunders (HTML)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.digitalocean.com/community/books/sysadmin-ebook-making-servers-work&quot;&gt;Making Servers Work: A Practical Guide to Linux System Administration&lt;/a&gt; - Jamon Camisso (PDF, EPUB)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://gustavus.edu/mcs/max/os-book/&quot;&gt;Operating Systems and Middleware&lt;/a&gt; (PDF and LaTeX)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://pages.cs.wisc.edu/~remzi/OSTEP/&quot;&gt;Operating Systems: Three Easy Pieces&lt;/a&gt; (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.nobius.org/~dbg/practical-file-system-design.pdf&quot;&gt;Practical File System Design: The Be File System&lt;/a&gt; - Dominic Giampaolo (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://people.inf.ethz.ch/wirth/ProjectOberon/index.html&quot;&gt;Project Oberon: The Design of an Operating System, a Compiler, and a Computer&lt;/a&gt; - Niklaus Wirth &amp;amp; Jürg Gutknecht (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://catb.org/esr/writings/taoup/html/&quot;&gt;The Art of Unix Programming&lt;/a&gt; - Eric S. Raymond&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.fixup.fi/misc/rumpkernel-book/&quot;&gt;The Design and Implementation of the Anykernel and Rump Kernels&lt;/a&gt; - Antti Kantee&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://littleosbook.github.io&quot;&gt;The little book about OS development&lt;/a&gt; (&lt;a href=&quot;https://littleosbook.github.io/book.pdf&quot;&gt;PDF&lt;/a&gt;)- Erik Helin, Adam Renberg - This is not your typical dry academic textbook. It’s a hands-on, step-by-step guide aimed at hackers, tinkerers, and developers who want to demystify kernel programming. The book walks you through setting up your environment, bootstrapping your OS, handling interrupts, implementing virtual memory, and even tackling system calls and multitasking. It provides just enough detail to get you started but leaves room for exploration – because, let’s be honest, half the fun is in figuring things out yourself.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://greenteapress.com/semaphores/&quot;&gt;The Little Book of Semaphores&lt;/a&gt; - Allen B. Downey&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.greenteapress.com/thinkos/index.html&quot;&gt;Think OS: A Brief Introduction to Operating Systems&lt;/a&gt; - Allen B. Downey (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.compsci.hunter.cuny.edu/~sweiss/course_materials/unix_lecture_notes.php&quot;&gt;UNIX Application and System Programming, lecture notes&lt;/a&gt; - Prof. Stewart Weiss (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.cs.bham.ac.uk/~exr/lectures/opsys/10_11/lectures/os-dev.pdf&quot;&gt;Writing a Simple Operating System from Scratch&lt;/a&gt; - Nick Blundell (PDF)&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Linux&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.linuxfromscratch.org/lfs/view/stable/&quot;&gt;Linux From Scratch&lt;/a&gt; - Gerard Beekmans, Bruce Dubbs, Ken Moffat, Pierre Labastie et al. (HTML, &lt;a href=&quot;https://www.linuxfromscratch.org/lfs/downloads/stable/&quot;&gt;PDF, downloads...&lt;/a&gt;)&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Pragmatic Programmer</title>
      <link>https://tedneward.github.io/Research/reading/development/pragmatic-programmer/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">reading/development/pragmatic-programmer/index.html</guid>
      	<description>
	&lt;p&gt;&lt;em&gt;(by Andy Hunt, Dave Thomas (Addison-Wesley) )&lt;/em&gt;&lt;/p&gt; 
&lt;h1&gt;Checklists&lt;/h1&gt; 
&lt;h2&gt;The WISDOM acrostic&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;What:&amp;nbsp;What do you want them to learn?&lt;/li&gt; 
 &lt;li&gt;Interest:&amp;nbsp;What is their interest in what you&apos;ve got to say?&lt;/li&gt; 
 &lt;li&gt;Sophistication:&amp;nbsp;How sophisticated are they?&lt;/li&gt; 
 &lt;li&gt;Detail:&amp;nbsp;How much detail do they want?&lt;/li&gt; 
 &lt;li&gt;Own:&amp;nbsp;Whom do you want to own the information?&lt;/li&gt; 
 &lt;li&gt;Motivate:&amp;nbsp;How can you motivate them to listen to you?&amp;nbsp;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;How to maintain orthogonality&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;Design independent, well-defined components.&lt;/li&gt; 
 &lt;li&gt;Keep your code decoupled.&lt;/li&gt; 
 &lt;li&gt;Avoid global data.&lt;/li&gt; 
 &lt;li&gt;Refactor similar functions.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Things to prototype&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;Architecture&lt;/li&gt; 
 &lt;li&gt;New functionality in an existing system&lt;/li&gt; 
 &lt;li&gt;Structure or contents of external data&lt;/li&gt; 
 &lt;li&gt;Third-party tools or components&lt;/li&gt; 
 &lt;li&gt;Performance issues&lt;/li&gt; 
 &lt;li&gt;User interface design&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Architectural questions&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;Are responsibilities well defined?&lt;/li&gt; 
 &lt;li&gt;Are the collaborations well defined?&lt;/li&gt; 
 &lt;li&gt;Is coupling minimized?&lt;/li&gt; 
 &lt;li&gt;Can you identify potential duplication?&lt;/li&gt; 
 &lt;li&gt;Are interface definitions and constrains acceptable?&lt;/li&gt; 
 &lt;li&gt;Can modules access needed data--when needed?&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Debugging&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;Is the problem being reported a direct result of the underlying bug, or merely a symptom?&lt;/li&gt; 
 &lt;li&gt;Is the bug really in the compiler? Is it in the OS? Or is it in your code?&lt;/li&gt; 
 &lt;li&gt;If you explained this problem in detail to a coworker, what would you say?&lt;/li&gt; 
 &lt;li&gt;If the suspect code passes its unit tests, are the tests complete enough? What happens if you run the unit test with &quot;this&quot; data?&lt;/li&gt; 
 &lt;li&gt;Do the conditions that caused this bug exist anywhere else in the system?&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Law of Demeter for functions&lt;/h2&gt; 
&lt;p&gt;An object&apos;s method should call only methods belonging to:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Itself&lt;/li&gt; 
 &lt;li&gt;Any parameters passed in&lt;/li&gt; 
 &lt;li&gt;Objects it creates&lt;/li&gt; 
 &lt;li&gt;Component objects&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;How to Program Deliberately&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;Stay aware of what you&apos;re doing&lt;/li&gt; 
 &lt;li&gt;Don&apos;t code blindfolded&lt;/li&gt; 
 &lt;li&gt;Proceed from a plan&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Rely only on reliable things&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;Document your assumptions&lt;/li&gt; 
 &lt;li&gt;Test assumptions as well as code&lt;/li&gt; 
 &lt;li&gt;Prioritize your effort&lt;/li&gt; 
 &lt;li&gt;Don&apos;t be a slave to history&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;When to Refactor&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;You discover a violation of DRY&lt;/li&gt; 
 &lt;li&gt;You find things that could be more orthogonal&lt;/li&gt; 
 &lt;li&gt;Your knowledge improves&lt;/li&gt; 
 &lt;li&gt;The requirements evolve&lt;/li&gt; 
 &lt;li&gt;You need to improve performance&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Cutting the Gordian Knot&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;Is there an easier way?&lt;/li&gt; 
 &lt;li&gt;Am I solving the right problem?&lt;/li&gt; 
 &lt;li&gt;Why is this a problem?&lt;/li&gt; 
 &lt;li&gt;What makes it hard?&lt;/li&gt; 
 &lt;li&gt;Do I have to do it this way?&lt;/li&gt; 
 &lt;li&gt;Does it have to be done at all?&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Aspects of Testing&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;Unit testing&lt;/li&gt; 
 &lt;li&gt;Integration testing&lt;/li&gt; 
 &lt;li&gt;Validation and verification&lt;/li&gt; 
 &lt;li&gt;Resource exhaustion, errors and recovery&lt;/li&gt; 
 &lt;li&gt;Performance testing&lt;/li&gt; 
 &lt;li&gt;Usability testing&lt;/li&gt; 
 &lt;li&gt;Testing the tests themselves&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h1&gt;Principles&lt;/h1&gt; 
&lt;ol&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Care About Your Craft.&lt;/strong&gt; Why spend your life developing software unless you care about doing it well?&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Think! About Your Work.&lt;/strong&gt;&amp;nbsp;Turn off the autopilot and take control. Constantly critique and appraise your work.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Provide Options, Don&apos;t Make Lame Excuses.&lt;/strong&gt;&amp;nbsp;Instead of excuses, provide options. Don&apos;t say it can&apos;t be done; say what can be done.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Don&apos;t Live with Broken Windows.&lt;/strong&gt;&amp;nbsp;Fix bad designs, wrong decisions, and poor code when you see them.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Be a Catalyst for Change.&lt;/strong&gt;&amp;nbsp;You can&apos;t force change on people. Instead, show them how the future might be and help them participate in creating it.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Remember the Big Picture.&lt;/strong&gt;&amp;nbsp;Don&apos;t get so engrossed in the details that you forget to check what&apos;s happening around you.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Make Quality a Requirements Issue.&lt;/strong&gt;&amp;nbsp;Involve your users in determining the project&apos;s real quality requirements.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Invest Regularly in your Knowledge Portfolio.&lt;/strong&gt;&amp;nbsp;Make learning a habit.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Critically Analyze What You Read and Hear.&lt;/strong&gt;&amp;nbsp;Don&apos;t be swayed by vendors, media hype or dogma. Analyze information in terms of you and your project.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;It&apos;s Both What You Say and How You Say It.&lt;/strong&gt;&amp;nbsp;There&apos;s no point in having great ideas if you don&apos;t communicate them effectively.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;DRY--Don&apos;t Repeat Yourself.&lt;/strong&gt;&amp;nbsp;Every piece of knowledge must have a single, unambiguous, authoritative representation within a system.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Make It Easy to Reuse.&lt;/strong&gt;&amp;nbsp;If it&apos;s easy to reuse, people will. Create an environment that supports reuse.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Eliminate Effects Between Unrelated Things.&lt;/strong&gt;&amp;nbsp;Design components that are self-contained, independent, and have a single, well-defined purpose.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;There Are No Final Decisions.&lt;/strong&gt;&amp;nbsp;No decision is cast in stone. Instead, consider each as being written in the sand at the beach, and plan for change.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Use Tracer Bullets to Find the Target.&lt;/strong&gt;&amp;nbsp;Tracer bullets let you home in on your target by trying things and seeing how close they land.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Prototype to Learn.&lt;/strong&gt;&amp;nbsp;Prototyping is a learning experience. Its value lies not in the code you produce, but in the lessons you learn.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Program Close to the Problem Domain.&lt;/strong&gt;&amp;nbsp;Design and code in your user&apos;s language.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Estimate to Avoid Surprises.&lt;/strong&gt;&amp;nbsp;Estimate before you start. You&apos;ll spot potential problems up front.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Iterate the Schedule with the Code.&lt;/strong&gt;&amp;nbsp;Use experience you gain as you implement to refine the project time scales.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Keep Knowledge in Plain Text.&lt;/strong&gt;&amp;nbsp;Plain text won&apos;t become obsolete. It helps leverage your work and simplifies debugging and testing.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Use the Power of Command Shells.&lt;/strong&gt;&amp;nbsp;Use the shell when GUIs don&apos;t cut it.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Use a Single Editor Well.&lt;/strong&gt;&amp;nbsp;The editor should be an extension of your fingertips. make sue your editor is configurable, extensible, and programmable.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Always use Source Code Control.&lt;/strong&gt;&amp;nbsp;Source code control is a time machine for your work--you can go back.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Fix the Problem, Not the Blame.&lt;/strong&gt;&amp;nbsp;It doesn&apos;t really matter whether the bug is your fault or someone else&apos;s--it is still your problem, and it still needs to be fixed.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Don&apos;t Panic When Debugging.&lt;/strong&gt;&amp;nbsp;Take a deep breath and THINK! about what could be causing the bug.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;&quot;select&quot; Isn&apos;t Broken.&lt;/strong&gt;&amp;nbsp;It is rare to find a bug in the OS or the compiler, or even a third-party product or library. The bug is most likely in the application.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Don&apos;t Assume It--Prove It.&lt;/strong&gt;&amp;nbsp;Prove your assumptions in the actual environment--with real data and boundary conditions.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Learn a Text Manipulation Language.&lt;/strong&gt;&amp;nbsp;You spend a large part of each day working with text. Why not have the computer do some of it for you?&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Write Code That Writes Code.&lt;/strong&gt;&amp;nbsp;Code generators increase your productivity and help avoid duplication.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;You Can&apos;t Write Perfect Software.&lt;/strong&gt;&amp;nbsp;Software can&apos;t be perfect. Protect your code and users from the inevitable errors.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Design With Contracts.&lt;/strong&gt;&amp;nbsp;Use contracts to document and verify that code does no more and no less than it claims to do.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Crash Early.&lt;/strong&gt;&amp;nbsp;A dead program normally does a lot less damage than a crippled one.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Use Assertions to Prevent the Impossible.&lt;/strong&gt;&amp;nbsp;Assertions validate your assumptions. Use them to protect your code from an uncertain world.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Use Exceptions for Exceptional Problems.&lt;/strong&gt;&amp;nbsp;Exceptions can suffer from all the readability and maintainability problems of classic spaghetti code. Reserve exceptions for exceptional things.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Finish What You Start.&lt;/strong&gt;&amp;nbsp;Where possible, the routine or object that allocates a resource should be responsible for deallocating it.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Minimize Coupling Between Modules.&lt;/strong&gt;&amp;nbsp;Avoid coupling by writing &quot;shy&quot; code and applying the Law of Demeter.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Configure, Don&apos;t Integrate.&lt;/strong&gt;&amp;nbsp;Implement technology choices for an application as configuration options, not through integration or engineering.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Put Abstractions in Code, Details in Metadata.&lt;/strong&gt;&amp;nbsp;Program for the general case, and put the specifics outside the compiled code base.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Analyze Workflow to Improve Concurrency.&lt;/strong&gt;&amp;nbsp;Exploit concurrency in your users&apos; workflow.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Design Using Services.&lt;/strong&gt;&amp;nbsp;Design in terms of services--independent, concurrent objects behind well-defined, consistent interfaces.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Always Design for Concurrency.&lt;/strong&gt;&amp;nbsp;Allow for concurrency, and you&apos;ll design cleaner interfaces with fewer assumptions.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Separate Views from Models.&lt;/strong&gt;&amp;nbsp;Gain flexibility at low cost by designing your application in terms of models and views.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Use Blackboards to Coordinate Workflow.&lt;/strong&gt;&amp;nbsp;Use blackboards to coordinate disparate facts and agents, while maintaining independence and isolation among participants.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Don&apos;t Program by Coincidence.&lt;/strong&gt;&amp;nbsp;Rely only on reliable things. Beware of accidental complexity, and don&apos;t confuse a happy coincidence with a purposeful plan.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Estimate the Order of your Algorithms.&lt;/strong&gt;&amp;nbsp;Get a feel for how long things are likely to take before you write code.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Test Your Estimates.&lt;/strong&gt;&amp;nbsp;Mathematical analysis of algorithms doesn&apos;t tell you everything. Try timing your code in its target environment.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Refactor Early, Refactor Often.&lt;/strong&gt;&amp;nbsp;Just as you might weed and rearrange a garden, rewrite, rework, and re-architect code when it needs it. Fix the root of the problem.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Design to Test.&lt;/strong&gt;&amp;nbsp;Start thinking about testing before you write a line of code.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Test Your Software, or Your Users Will.&lt;/strong&gt;&amp;nbsp;Test ruthlessly. Don&apos;t make your users find bugs for you.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Don&apos;t Use Wizard Code You Don&apos;t Understand.&lt;/strong&gt;&amp;nbsp;Wizards can generate reams of code. Make sur eyou understand all of it before you incorporate it into your project.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Don&apos;t Gather Requirements--Dig for Them.&lt;/strong&gt;&amp;nbsp;Requirements rarely lie on the surface. They&apos;re buried deep beneath layers of assumptions, misconceptions, and politics.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Work With a User to Think Like a User.&lt;/strong&gt;&amp;nbsp;It&apos;s the best way to gain insight into how the system will really be used.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Abstractions Live Longer Than Details.&lt;/strong&gt;&amp;nbsp;Invest in the abstraction, not the implementation. Abstractions can survive the barrage of changes from different implementations and new technologies.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Use a Project Glossary.&lt;/strong&gt;&amp;nbsp;Create and maintain a single source of all the specific terms and vocabulary for the project.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Don&apos;t Think Outside the Box--Find the Box.&lt;/strong&gt;&amp;nbsp;When faced with an impossible problem, identify the real constraints. Ask yourself: &quot;Does it have to be done this way? Does it have to be done at all?&quot;&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Start When You&apos;re Ready.&lt;/strong&gt;&amp;nbsp;You&apos;ve been building experience all your life. Don&apos;t ignore niggling doubts.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Some Things Are Better Done Than Described.&lt;/strong&gt;&amp;nbsp;Don&apos;t fall into the specification spiral--at some point you need to start coding.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Don&apos;t Be a Slave to Formal Methods.&lt;/strong&gt;&amp;nbsp;Don&apos;t blindly adopt any technique without putting it into the context of your development practices and capabilities.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Costly Tools Don&apos;t Produce Better Designs.&lt;/strong&gt;&amp;nbsp;Beware of vendor hype, industry dogma, and the aura of the price tag. Judge tools on their merits.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Organize Teams Around Functionality.&lt;/strong&gt;&amp;nbsp;Don&apos;t separate designers from coders, testers from data modelers. Build teams the way you build code.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Don&apos;t Use Manual Procedures.&lt;/strong&gt;&amp;nbsp;A shell script or batch file will execute the same instructions, in the same order, time after time.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Test Early, Test Often, Test Automatically.&lt;/strong&gt;&amp;nbsp;Tests that run with every build are much more effective than test plans that will sit on a shelf.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Coding Ain&apos;t Done &apos;Till All The Tests Run.&lt;/strong&gt;&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Use Saboteurs to Test Your Testing.&lt;/strong&gt;&amp;nbsp;Introduce bugs on purpose in a separate copy of the source to verify that unit testing will catch them.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Test State Coverage, Not Code Coverage.&lt;/strong&gt;&amp;nbsp;Identify and test significant program states. Just testing lines of code isn&apos;t enough.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Find Bugs Once.&lt;/strong&gt;&amp;nbsp;Once a human tester finds a bug, it should be the last time a human tester finds that bug. Automatic tests should check for it from then on.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;English is Just a Programming Language.&lt;/strong&gt;&amp;nbsp;Write documents as you would write code: honor the DRY principle, use metadata, MVC, automatic generation, and so on.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Build Documentation In, Don&apos;t Bolt It On.&lt;/strong&gt;&amp;nbsp;Documentation created separately from code is less likely to be correct and up to date.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Gently Exceed Your Users&apos; Expectations.&lt;/strong&gt;&amp;nbsp;Come to understand your users&apos; expectations, then deliver just that little bit more.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Sign Your Work.&lt;/strong&gt;&amp;nbsp;Craftsmen of an earlier age were proud to sign their work. You should be, too.&lt;/p&gt; &lt;/li&gt; 
&lt;/ol&gt;
	</description>
    </item>
    <item>
      <title>Structure and Interpretation of Computer Programs (SICP)</title>
      <link>https://tedneward.github.io/Research/reading/development/sicp/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">reading/development/sicp/index.html</guid>
      	<description>
	&lt;p&gt;&lt;em&gt;(by Abelman, Sussman, and Sussman)&lt;/em&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://mitpress.mit.edu/sites/default/files/sicp/full-text/book/book.html&quot;&gt;Book (HTML)&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://web.mit.edu/6.001/6.037/sicp.pdf&quot;&gt;PDF&lt;/a&gt; | &lt;a href=&quot;https://github.com/sarabander/sicp-pdf&quot;&gt;GitHub PDF?&lt;/a&gt; (I&apos;m not sure if this is an &quot;official&quot; site or a fan&apos;s port) | &lt;a href=&quot;https://github.com/sarabander/sicp&quot;&gt;GitHub HTML&lt;/a&gt; (sister project to the PDF)&lt;/p&gt; 
&lt;h1&gt;Notes&lt;/h1&gt; 
&lt;h2&gt;1: Building Abstractions with Procedures&lt;/h2&gt; 
&lt;h2&gt;2: Building Abstractions with Data&lt;/h2&gt; 
&lt;h2&gt;3: Modularity, Objects, and State&lt;/h2&gt; 
&lt;h2&gt;4: Metalinguistic Abstraction&lt;/h2&gt; 
&lt;h2&gt;5: Computing with Register Machines&lt;/h2&gt;
	</description>
    </item>
    <item>
      <title>Papers We Love</title>
      <link>https://tedneward.github.io/Research/reading/development/papers-we-love/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">reading/development/papers-we-love/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://paperswelove.org/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/papers-we-love/papers-we-love&quot;&gt;GitHub&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>The Reactive Manifesto</title>
      <link>https://tedneward.github.io/Research/reading/development/reactivemanifesto/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">reading/development/reactivemanifesto/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.reactivemanifesto.org/&quot;&gt;Website&lt;/a&gt;&lt;/p&gt; 
&lt;h2&gt;Portions lifted from the site (so that I may put notes in italics within or near the prose), visit there for full body.&lt;/h2&gt; 
&lt;p&gt;Organisations working in disparate domains are independently discovering patterns for building software that look the same. These systems are more robust, more resilient, more flexible and better positioned to meet modern demands. &lt;em&gt;(I&apos;m not 100% sure this is any more true than when we said the exact same thing about object-oriented systems thirty years ago.)&lt;/em&gt;&lt;/p&gt; 
&lt;p&gt;These changes are happening because application requirements have changed dramatically in recent years. Only a few years ago a large application had tens of servers, seconds of response time, hours of offline maintenance and gigabytes of data. Today applications are deployed on everything from mobile devices to cloud-based clusters running thousands of multi-core processors. Users expect millisecond response times and 100% uptime. Data is measured in Petabytes. Today&apos;s demands are simply not met by yesterday’s software architectures. &lt;em&gt;(This is probably true, though I think there&apos;s some generalization going on here.)&lt;/em&gt;&lt;/p&gt; 
&lt;p&gt;We believe that a coherent approach to systems architecture is needed, and we believe that all necessary aspects are already recognised individually: we want systems that are Responsive, Resilient, Elastic and Message Driven. We call these Reactive Systems. &lt;em&gt;(This is good, but there&apos;s other qualities we want out of a system, too, and I&apos;m not sure the authors aren&apos;t skating quickly across some thin ice here in their effort to promote reactivity.)&lt;/em&gt;&lt;/p&gt; 
&lt;p&gt;Systems built as Reactive Systems are more flexible, loosely-coupled and scalable. &lt;em&gt;(I&apos;m not 100% sure this is 100% true 100% of the time. They can be, but that doesn&apos;t mean they will be.)&lt;/em&gt; This makes them easier to develop and amenable to change. They are significantly more tolerant of failure and when failure does occur they meet it with elegance rather than disaster. Reactive Systems are highly responsive, giving users effective interactive feedback.&lt;/p&gt; 
&lt;p&gt;Reactive Systems are:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Responsive&lt;/strong&gt;: The system responds in a timely manner if at all possible. Responsiveness is the cornerstone of usability and utility, but more than that, responsiveness means that problems may be detected quickly and dealt with effectively. Responsive systems focus on providing rapid and consistent response times, establishing reliable upper bounds so they deliver a consistent quality of service. This consistent behaviour in turn simplifies error handling, builds end user confidence, and encourages further interaction.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Resilient&lt;/strong&gt;: The system stays responsive in the face of failure. This applies not only to highly-available, mission-critical systems — any system that is not resilient will be unresponsive after a failure. Resilience is achieved by replication, containment, isolation and delegation. Failures are contained within each component, isolating components from each other and thereby ensuring that parts of the system can fail and recover without compromising the system as a whole. Recovery of each component is delegated to another (external) component and high-availability is ensured by replication where necessary. The client of a component is not burdened with handling its failures.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Elastic&lt;/strong&gt;: The system stays responsive under varying workload. Reactive Systems can react to changes in the input rate by increasing or decreasing the resources allocated to service these inputs. This implies designs that have no contention points or central bottlenecks, resulting in the ability to shard or replicate components and distribute inputs among them. Reactive Systems support predictive, as well as Reactive, scaling algorithms by providing relevant live performance measures. They achieve elasticity in a cost-effective way on commodity hardware and software platforms.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Message Driven&lt;/strong&gt;: Reactive Systems rely on asynchronous message-passing to establish a boundary between components that ensures loose coupling, isolation and location transparency. This boundary also provides the means to delegate failures as messages. Employing explicit message-passing enables load management, elasticity, and flow control by shaping and monitoring the message queues in the system and applying back-pressure when necessary. Location transparent messaging as a means of communication makes it possible for the management of failure to work with the same constructs and semantics across a cluster or within a single host. Non-blocking communication allows recipients to only consume resources while active, leading to less system overhead.&lt;/p&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;Large systems are composed of smaller ones and therefore depend on the Reactive properties of their constituents. This means that Reactive Systems apply design principles so these properties apply at all levels of scale, making them composable. The largest systems in the world rely upon architectures based on these properties and serve the needs of billions of people daily. It is time to apply these design principles consciously from the start instead of rediscovering them each time.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>The Passionate Programmer</title>
      <link>https://tedneward.github.io/Research/reading/development/passionate-programmer/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">reading/development/passionate-programmer/index.html</guid>
      	<description>
	&lt;p&gt;&lt;em&gt;(by Chad Fowler)&lt;/em&gt;&lt;/p&gt; 
&lt;h3&gt;Introduction&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;According to the U.S. Bureau of Labor Statistics, the average American spends half their waking time at work.&lt;/li&gt; 
 &lt;li&gt;If your life is primarily consumed by your work, then loving your work is one of the most important keys to loving your life.&lt;/li&gt; 
 &lt;li&gt;Once we have basic human needs like food and shelter taken care of, most of our goals are geared toward finding happiness.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Failure Is Off The Radar!&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;A person who wants to be great is far more likely to become great than someone who just wants to do their job.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;You Own It&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;To excel at a company, you have to understand how you fit into the business&apos;s plan to make money.&lt;/li&gt; 
 &lt;li&gt;Your company is investing in you. Your challenge is to become an obviously good investment, and to judge your own performance in terms of the value you bring to the business.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Part 1: Choosing Your Market&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;Many of us just float down the stream of our careers, letting the current take us where it may.&lt;/li&gt; 
 &lt;li&gt;If you think of your career as a business (which it is), then your &quot;product&quot; is made up of the services you have to offer.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Tip 1: Lead or Bleed?&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;The risk-reward trade-off is an important part of making intentional choices about which technologies and domains to invest in.&lt;/li&gt; 
 &lt;li&gt;Picking a stable technology that&apos;s already widely used in production is safer, but potentially less rewarding, than picking a flashy new technology not yet deployed.&lt;/li&gt; 
 &lt;li&gt;Old systems don&apos;t just die, but are replaced. As a &lt;em&gt;technology hospice&lt;/em&gt;, you are the last one left to support still-critical systems, and can pretty much call the shots.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Tip 2: Supply and Demand&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;The supply-and-demand model predicts how price changes will affect the number of people willing to sell and purchase a product or service.&lt;/li&gt; 
 &lt;li&gt;Offshore companies do work that is in high demand. So by focusing on niche technologies, you might change the focus of the competition from price (which you cannot compete on) to ability.&lt;/li&gt; 
 &lt;li&gt;The lower price of offshore programmers drives down the overall price, thereby increasing overall demand&amp;nbsp;– including a higher bracket of developers.&lt;/li&gt; 
 &lt;li&gt;The most important lesson from the supply and demand model is that with increased demand comes increased price competition.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Tip 3: Coding Don&apos;t Cut It Anymore&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;If you want to stay relevant, you must dive into the domain of the business you&apos;re in.&lt;/li&gt; 
 &lt;li&gt;You might be &quot;just a programmer,&quot; but being able to speak to your business clients in the language of their business domain is a critical skill.&lt;/li&gt; 
 &lt;li&gt;Business domains can become hot, just like technologies. Put the same care into selecting which industry to serve as you put into which technologies to master.&lt;/li&gt; 
 &lt;li&gt;Find industry web sites you can monitor, and think about how current trends affect your company, your division, your team, and your work.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Tip 4: Be the Worst&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;Being the worst guy in the band means always playing with people who are better than you.&lt;/li&gt; 
 &lt;li&gt;Similarly, being the worst guy or gal on the team has the same effect as being the worst guy or gal in the band. You find that you inexplicably get smarter.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Tip 5: Invest in Your Intelligence&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;Good people seek out diversity, either because they love to learn new things, or being forced into alien experiences creates more mature and well-rounded software developers.&lt;/li&gt; 
 &lt;li&gt;Exposure to fringe technologies makes you deeper, better, smarter, and more creative.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Tip 6: Don&apos;t Listen to Your Parents&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;Your parents will give you fear-driven advice that optimizes for &lt;em&gt;not losing&lt;/em&gt;. But winners take risks.&lt;/li&gt; 
 &lt;li&gt;If your job isn&apos;t fun, then you won&apos;t do a fantastic job at it. Because passion leads to excellence, and without fun there won&apos;t be passion.&lt;/li&gt; 
 &lt;li&gt;The more domains you&apos;ve seen and technical architectures you&apos;ve slogged through, the more prepared you are to make the right decisions on tougher projects.&lt;/li&gt; 
 &lt;li&gt;Take calculated risks in your career, and don&apos;t let fear consume you.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Tip 7: Be a Generalist&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;Things change in a business, and businesspeople know that software is malleable and can be changed to meet changing requirements.&lt;/li&gt; 
 &lt;li&gt;In such a rapidly changing environment, flexible people that can solve any problem that arises will excel.&lt;/li&gt; 
 &lt;li&gt;If the programmers don&apos;t understand what a system is supposed to do, then they won&apos;t be able to create a good implementation of it – regardless of any requirements, architecture, or design documents.&lt;/li&gt; 
 &lt;li&gt;If you want to be the last person standing after layoffs, then you had better make yourself generally useful.&lt;/li&gt; 
 &lt;li&gt;If you want to stand out and be remarkable, then wrapping your head around The Big Picture is where it&apos;s at.&lt;/li&gt; 
 &lt;li&gt;When it comes to hierarchical boundary crossing, it&apos;s most often not reluctance that stops people from doing it –&amp;nbsp;it&apos;s ability.&lt;/li&gt; 
 &lt;li&gt;Longevity requires that you are platform neutral in the workplace. We all have our preferences, but leave your ideals at home.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Tip 8: Be a Specialist&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;The software industry has churned out a lot of shallow specialists, who use the term &lt;em&gt;specialist&lt;/em&gt; as an excuse for only knowing one thing.&lt;/li&gt; 
 &lt;li&gt;Strive to be a specialist with a deep understanding of some specific area in the software field.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Tip 9: Don&apos;t Put All Your Eggs in Someone Else&apos;s Basket&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;We fool ourselves into thinking &lt;em&gt;market leader&lt;/em&gt; is the same thing as &lt;em&gt;standard&lt;/em&gt;. This helps us rationalize making another company&apos;s product part of our identity.&lt;/li&gt; 
 &lt;li&gt;You can build a business that exists as a parasite of another, but it&apos;s risky for an individual. You don&apos;t have the bandwidth or surplus of cash to suddenly change career direction or focus like a company would.&lt;/li&gt; 
 &lt;li&gt;The &lt;em&gt;professional services barrier&lt;/em&gt; is the artificial barrier that a company erects between you and the solution to a problem you may have so that it can profit from selling you support services.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Tip 10: Love It or Leave It&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;You have to be passionate about your work if you want to be great at your work. If you don&apos;t care, it will show.&lt;/li&gt; 
 &lt;li&gt;Many people have no idea why they are in the IT field, and their performance on the job reflects it.&lt;/li&gt; 
 &lt;li&gt;Natural talent plays a big role in ability, but we can all take a big step away from mediocrity by finding work that we are passionate about.&lt;/li&gt; 
 &lt;li&gt;You can fake it for a while, but a lack of passion will catch up with you and your work.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Part 2: Investing in Your Product&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;To have a great product to sell on the job market, you must invest in that product.&lt;/li&gt; 
 &lt;li&gt;In business, ideas and even talent are a dime a dozen. It&apos;s the blood, sweat, tears, and money you pour into a product that makes it really worth something.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Tip 11: Learn to Fish&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;Education requires both a teacher and a student, and many of us are too often reluctant to be a student.&lt;/li&gt; 
 &lt;li&gt;Don&apos;t be at the mercy of others for expertise in tools or technology. Don&apos;t take expertise of these things for granted.&lt;/li&gt; 
 &lt;li&gt;Someone ignorant of their business domain lets mistakes slip through that should be easily caught, and will be slower than someone who understands the business.&lt;/li&gt; 
 &lt;li&gt;Ask yourself &quot;How does this work?&quot; and &quot;Why does this happen?&quot; to learn about things. Moreover this puts you in a new frame of mind and generates a higher level of awareness about your work environment.&lt;/li&gt; 
 &lt;li&gt;Pick a critical tool you use, and then allot yourself time each day to learn one new thing about it that will make you more productive.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Tip 12: Learn How Businesses Really Work&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;The basics of business finance is one body of knowledge that is neither technical nor domain-specific and won&apos;t be outdated anytime soon.&lt;/li&gt; 
 &lt;li&gt;You work for a business, and your job is to contribute to either making or saving money for that business.&lt;/li&gt; 
 &lt;li&gt;You cannot creatively help a business be profitable if you don&apos;t even understand how the business works.&lt;/li&gt; 
 &lt;li&gt;Understand whether your organization is a cost center or a profit center.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Tip 13: Find a Mentor&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;The first and most important purpose that a mentor serves is that of a role model.&lt;/li&gt; 
 &lt;li&gt;A role model sets the standard for what &quot;good&quot; means. Without a role model, there&apos;s no incentive to get better.&lt;/li&gt; 
 &lt;li&gt;A mentor can give structure to your learning process, helping you take some of the choice out of what to focus your energies on.&lt;/li&gt; 
 &lt;li&gt;A mentor is someone you can trust enough to ask &quot;What should be different about me as a professional?&quot; because they&apos;ll not only criticize you, but help you improve.&lt;/li&gt; 
 &lt;li&gt;As a mentor, your role is to help someone, and so you become invested in that person&apos;s success. Their success is your success as well.&lt;/li&gt; 
 &lt;li&gt;A mentor becomes a positively reinforced connection from you to his or her network, because it&apos;s not what you know, but whom you know.&lt;/li&gt; 
 &lt;li&gt;Find a role model, and define the ten most important attributes of them. Devise concrete tasks to improve on attributes you perceive as very important but you are unskilled at.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Tip 14: Be a Mentor&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;There is no better way to crystallize your understanding of something than to make it understandable and teachable to someone else.&lt;/li&gt; 
 &lt;li&gt;When you teach, you have to answer questions that may never have occurred to you.&lt;/li&gt; 
 &lt;li&gt;You find a mentee not by proclaiming yourself a guru but by being knowledgeable and willing to patiently share that knowledge.&lt;/li&gt; 
 &lt;li&gt;Mentoring is about people, and so an online mentoring relationship can never compare to one that happens between two people in the same place.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Tip 15: Practice, Practice, Practice&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;In the computer industry, it&apos;s common to find developers stretched to their limits.&lt;/li&gt; 
 &lt;li&gt;Our industry tends to practice on the job, but like many professionals, we need to make time for practice.&lt;/li&gt; 
 &lt;li&gt;If we&apos;re going to compete based on quality, we have to stop treating our jobs as a practice session. We have to invest the time in our craft.&lt;/li&gt; 
 &lt;li&gt;If you sit down to practice coding and nothing elegant comes out, you&apos;re probably not near the edges of your capabilities, where a good practice session should place you.&lt;/li&gt; 
 &lt;li&gt;To sight read code would mean to understand what you&apos;re looking at as quickly as possible.&lt;/li&gt; 
 &lt;li&gt;To sharpen your mind and improve your improvisational coding skills is to pick a program, and to write it with self-imposed constraints.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Tip 16: The Way That You Do It&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;Take your eye off the process of developing software, and you risk delivering late, delivering the wrong thing, or not delivering at all.&lt;/li&gt; 
 &lt;li&gt;For a software process to have any chance of being implemented successfully, it has to be embraced by the people who are using the process.&lt;/li&gt; 
 &lt;li&gt;The best way to feel ownership of processes is to help implement them.&lt;/li&gt; 
 &lt;li&gt;The methodology world is full of buzzwords, but you can always learn &lt;em&gt;something&lt;/em&gt; from the study of a software process –&amp;nbsp;even if it&apos;s what not to do.&lt;/li&gt; 
 &lt;li&gt;The best process to follow is the one that makes your team most productive and results in the best products.&lt;/li&gt; 
 &lt;li&gt;Study the available options, pick out the pieces that make sense to you and your team, and continuously refine them based on real experience.&lt;/li&gt; 
 &lt;li&gt;It&apos;s much easier to find someone who can make software work than it is to find someone who can make the &lt;em&gt;making of&lt;/em&gt; software work.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Tip 17: On the Shoulders of Giants&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;Studying the work of masters is an essential part of becoming a master.&lt;/li&gt; 
 &lt;li&gt;Even more important than finding solutions to specific problems is the use of existing code as a magnifying mirror to inspect our own style and capabilities.&lt;/li&gt; 
 &lt;li&gt;By looking at the code of others with a critical eye, you will start to develop your own tastes, just as you would for music, art, or literature.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Tip 18: Automate Yourself into a Job&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;To increase software development throughput, you can get faster people to do the work, get more people to do the work, or automate the work.&lt;/li&gt; 
 &lt;li&gt;To provably make better software faster and cheaper than your offshore competition, automate your work.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Part 3: Executing&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;You likely work for an institution that tries to make money. Your job is to do something to help the organization meet that goal.&lt;/li&gt; 
 &lt;li&gt;To be successful, raw ability will only get you so far. The final stretch is populated by closers –&amp;nbsp;people who finish things.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Tip 19: Right Now&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;Parkinson&apos;s law states that &quot;Work expands so as to fill the time available for its completion.&quot;&lt;/li&gt; 
 &lt;li&gt;Even a manufactured sense of urgency allows you to double or triple your productivity. You get it done instead of talking about getting it done.&lt;/li&gt; 
 &lt;li&gt;Always be the one to ask &quot;But what can we do &lt;em&gt;right now&lt;/em&gt;?&quot;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Tip 20: Mind Reader&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;Doing what your customers ask for will satisfy them. But doing more than they ask for, or doing things before they even ask it, will delight them.&lt;/li&gt; 
 &lt;li&gt;To hedge, only do the guesswork that you can fit in between the cracks of your normal job so the impact is little to none.&lt;/li&gt; 
 &lt;li&gt;People who can keep a project moving in the right direction without given much guidance are highly valued and appreciated by their overworked managers and customers.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Tip 21: Daily Hit&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;Becoming a standout performer is more likely with some specific and intentional work. Ask how you can increase the &lt;em&gt;visible&lt;/em&gt; instances of this behavior.&lt;/li&gt; 
 &lt;li&gt;When you start to search for outstanding accomplishments, you naturally evaluate and prioritize your activities based on their business value.&lt;/li&gt; 
 &lt;li&gt;Tracking hits, or accomplishments, at a reasonably high frequency will ensure that you don&apos;t get stuck. Moreover you get addicted to achieving them daily.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Tip 22: Remember Who You Work For&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;It&apos;s hard to align your work with the goals of the business when you&apos;re buried under so many organizational layers that you hardly know what your business is.&lt;/li&gt; 
 &lt;li&gt;Start by aligning your team, which is small and focused enough that you can conceptually wrap yourself around it.&lt;/li&gt; 
 &lt;li&gt;Or else ask your manager: In a well-structured environment, your manager&apos;s goals are your team&apos;s goals, and so solving your manager&apos;s problems solves your team&apos;s problems.&lt;/li&gt; 
 &lt;li&gt;Your manager&apos;s goals are also his or her manager&apos;s goals, and so on up to the CEO –&amp;nbsp;and so doing your small part helps fulfill the company&apos;s goals.&lt;/li&gt; 
 &lt;li&gt;A job well done by the team is a job well done by the manager. Your manager may share credit for your work, but he or she reciprocates with performance reviews, raises, and promotions.&lt;/li&gt; 
 &lt;li&gt;Understand your manager&apos;s goals for the team over the coming month, quarter, and year. Prioritize your work based on these goals.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Tip 23: Be Where You&apos;re At&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;If you spend your time mentally living in your next role or your next job, you&apos;re usually doing a mediocre job in your current role.&lt;/li&gt; 
 &lt;li&gt;If you&apos;re a mediocre performer with a bad attitude and you&apos;re convinced you have &quot;high potential,&quot; beware:&amp;nbsp;Your company doesn&apos;t make money because of potential.&lt;/li&gt; 
 &lt;li&gt;Furthermore, your attitude makes your managers want to stop investing in you.&lt;/li&gt; 
 &lt;li&gt;Even if you finally land that promotion you&apos;ve been dreaming about, you&apos;ll quickly grow tired and realize that it&apos;s not this job you were meant for –&amp;nbsp;but the &lt;em&gt;next&lt;/em&gt; one.&lt;/li&gt; 
 &lt;li&gt;Keeping your mind focused on the present gets you further toward your goals than keeping your mind focused on the goal itself.&lt;/li&gt; 
 &lt;li&gt;Focusing on the present allows you to enjoy the small victories of daily work life.&lt;/li&gt; 
 &lt;li&gt;By focusing on the present you&apos;ll feel better, those around you will feel it as well, and it will show in your work.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Tip 24: How Good a Job Can I Do Today?&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;Boring work is usually boring for two reasons: It isn&apos;t a creative outlet, and it&apos;s not challenging.&lt;/li&gt; 
 &lt;li&gt;To make boring work both creative and challenging, make it a goal to do the boring stuff &lt;em&gt;perfectly&lt;/em&gt;.&lt;/li&gt; 
 &lt;li&gt;Look at your workday and ask yourself &quot;How good a job can I do today?&quot;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Tip 25: How Much Are You Worth?&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;Assuming you cost your employer twice your salary, ask whether your positive impact on the company&apos;s bottom line is bigger than that number.&lt;/li&gt; 
 &lt;li&gt;You work for a business, and unless you provide some real value, you are a waste of money. Salary increases are not an entitlement.&lt;/li&gt; 
 &lt;li&gt;To make how much value you add concrete, ask your manager about how to best quantify it.&lt;/li&gt; 
 &lt;li&gt;The &lt;em&gt;time value of money&lt;/em&gt; says that a dollar today is worth more than a dollar next year, because the dollar today can be used to make more dollars.&lt;/li&gt; 
 &lt;li&gt;Many investments have to yield an agreed-upon percentage in an agreed-upon period of time, or they aren&apos;t made. This is called the &lt;em&gt;hurdle rate&lt;/em&gt;.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Tip 26: A Pebble in a Bucket of Water&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;In few cases does a company feel a significant impact from an employee&apos;s departure. Even in critical positions, the effect is surprisingly low.&lt;/li&gt; 
 &lt;li&gt;If you left tomorrow, the difference would be (on the average) no more or no less impactful than if any of your co-workers left.&lt;/li&gt; 
 &lt;li&gt;The more successful you are, the more likely you are to make a fatal mistake. You become arrogant, and with arrogance you develop blind spots.&lt;/li&gt; 
 &lt;li&gt;Attempting to be irreplaceable is a defensive maneuver that creates a hostile relationship with your employer where one may not have already existed.&lt;/li&gt; 
 &lt;li&gt;For any code or task where the team depends completely on you, document, automate, or refactor it so that it can be easily understood by anyone on your team.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Tip 27: Learn to Love Maintenance&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;We crave &quot;project work&quot; over &quot;maintenance work&quot; because we believe it allows us to be creative and is a chance to make steps toward a promotion.&lt;/li&gt; 
 &lt;li&gt;When we don&apos;t have the constraints of legacy code and lack of funding to deal with, our managers and customers expect more from us.&lt;/li&gt; 
 &lt;li&gt;If you don&apos;t deliver on project work, you&apos;ve failed, and suddenly your every move is dictated from above.&lt;/li&gt; 
 &lt;li&gt;With maintenance work, you&apos;re only expected to keep the software running smoothly and for as little money as possible.&lt;/li&gt; 
 &lt;li&gt;As long as you&apos;re keeping things running and responding to user requests in a timely fashion, maintenance mode is a place of freedom and creativity.&lt;/li&gt; 
 &lt;li&gt;In maintenance mode you can interact directly with customers. So you can build a larger base of advocates in your business, and learn the inner workings of your business.&lt;/li&gt; 
 &lt;li&gt;Moreover project work is maintenance: As soon as you&apos;ve written your first line of code, each additional feature is grafted onto an existing code base.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Tip 28: Eight-Hour Burn&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;Rebranding &quot;forty-hour workweek&quot; to &quot;eight-hour burn&quot; conveys that you should work so relentlessly that there is no way you could work longer than eight hours.&lt;/li&gt; 
 &lt;li&gt;When we&apos;re tired, we can&apos;t think as effectively as when we&apos;re rested. We&apos;re not as creative and the quality of our work decreases dramatically.&lt;/li&gt; 
 &lt;li&gt;When you have too much time to work, your work time reduces significantly in perceived value. In a longer work week, each hour is less precious.&lt;/li&gt; 
 &lt;li&gt;With strict barriers on start and end times to your work, you naturally start to organize your tasks more effectively.&lt;/li&gt; 
 &lt;li&gt;If you work intensely every day and set boundaries, you&apos;ll find that your work doesn&apos;t follow you home.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Tip 29: Learn How to Fail&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;A craftsperson is really put to the test when errors arise, but learning to deal with mistakes is a skill that is both highly valuable and difficult to teach.&lt;/li&gt; 
 &lt;li&gt;We all make mistakes, so within reason, we don&apos;t judge each other on the mistakes we make. We judge each other on how we respond to mistakes.&lt;/li&gt; 
 &lt;li&gt;When a mistake happens, follow these rules:&lt;/li&gt; 
 &lt;li&gt;Raise the issue as early as you know it. The earlier you expose what you&apos;ve done, the smaller the negative impact.&lt;/li&gt; 
 &lt;li&gt;Take the blame. A problem needs a resolution, and lingering on who&apos;s fault it is only prolongs the issue.&lt;/li&gt; 
 &lt;li&gt;Offer a solution. Even small and immaterial concrete and attainable goals move things from bad to good, and help rebuild credibility.&lt;/li&gt; 
 &lt;li&gt;Ask for help. Your team members, management, and customers will look at you more positively if you can maintain a healthy attitude and set your ego aside.&lt;/li&gt; 
 &lt;li&gt;A mistake handled well might make us more loyal customers than we would have been had we never experienced a service problem.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Tip 30: Say &quot;No&quot;&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;The quickest path to missing your commitments is to make commitments that you know you can&apos;t meet.&lt;/li&gt; 
 &lt;li&gt;A &lt;em&gt;can-do&lt;/em&gt; attitude is different from misrepresenting one&apos;s abilities: The latter causes problems for both you and your stakeholders.&lt;/li&gt; 
 &lt;li&gt;We are programmed to want to always succeed, and saying we can&apos;t do something makes it feel like we failed.&lt;/li&gt; 
 &lt;li&gt;We know it to be true, but fail to internalize, that &quot;yes&quot; is not always the right answer, and &quot;no&quot; is seldom the wrong answer.&lt;/li&gt; 
 &lt;li&gt;If someone has the strength to say &quot;no&quot; when that&apos;s the truth, then you know that when they say &quot;yes,&quot; they really mean it.&lt;/li&gt; 
 &lt;li&gt;A guru in a subject area is never afraid to admit when they don&apos;t know something, because &quot;I don&apos;t know&quot; is not a phrase for the insecure.&lt;/li&gt; 
 &lt;li&gt;The same courage is useful when dealing with decision from above, as people who speak up and offer better suggestions become trusted lieutenants.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Tip 31: Don&apos;t Panic&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;If you look back on every &quot;disaster,&quot; you&apos;ll likely find that not a single one has made a lasting or noticeable impact on you or your career.&lt;/li&gt; 
 &lt;li&gt;Panicking creates an inability to perform at your best at the times when you really need to be performing at your best.&lt;/li&gt; 
 &lt;li&gt;When something is going wrong, we focus all of our attention on the problem. This makes the problem, no matter how small, seem more important than it is.&lt;/li&gt; 
 &lt;li&gt;To reduce panic when something bad happens, analyze the situation from a third-person perspective, and try to laugh at yourself.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Tip 32: Say It, Do It, Show It&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;When you have too much to do, a plan can make the difference between confused ambiguity and clear-headed confidence at the start of a workday.&lt;/li&gt; 
 &lt;li&gt;A simple plan that allows you to answer the question &quot;What am I going to do today?&quot; at the start of the day is a great first step.&lt;/li&gt; 
 &lt;li&gt;To create such a plan, take time in the afternoon to list in priority order everything you want to get done on the next workday.&lt;/li&gt; 
 &lt;li&gt;The larger the time span you&apos;re planning for, the higher level your plan should be.&lt;/li&gt; 
 &lt;li&gt;Start communicating your plans to management after executing one cycle of the plan. And start doing it before they ask you to do it.&lt;/li&gt; 
 &lt;li&gt;Every item in your plan must be completed, delayed, removed, or replaced. No items should go unaccounted for.&lt;/li&gt; 
 &lt;li&gt;If items show up on a plan and are never mentioned again, people will stop trusting your plans, thereby counteracting the effectiveness of planning.&lt;/li&gt; 
 &lt;li&gt;We all make mistakes. Differentiate yourself by addressing your mistakes or inabilities publicly and ask for help resolving them.&lt;/li&gt; 
 &lt;li&gt;Creating and executing plans shows that you are not just a robot typing code, but a &lt;em&gt;leader&lt;/em&gt;.&lt;/li&gt; 
 &lt;li&gt;If you say what you&apos;re going to do and then you do it and show that it&apos;s done, you develop a reputation as a &lt;em&gt;doer&lt;/em&gt;, and with credibility comes influence.&lt;/li&gt; 
 &lt;li&gt;Your leaders want you to have independence and ownership. Making, executing, and communicating plans will help you attain both.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Part 4: Executing&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;A leader must develop teams that deliver maximum value to a company. A leader can&apos;t do that without knowing who is capable of doing what kind of work.&lt;/li&gt; 
 &lt;li&gt;Manager&apos;s don&apos;t have time to keep close tabs on what each employee is doing every day. They instead focus on the big picture.&lt;/li&gt; 
 &lt;li&gt;Don&apos;t assume management knows who you are, or that just because a leader knows your name he or she has the faintest understanding of your capabilities.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Tip 33: Perceptions, Perschmeptions&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;You should care about what other people think of you. Perception is reality.&lt;/li&gt; 
 &lt;li&gt;There&apos;s no way to objectively measure the quality of a knowledge worker or the quality of their work, so you&apos;ll always be measured based on someone else&apos;s &lt;em&gt;perception&lt;/em&gt; of you.&lt;/li&gt; 
 &lt;li&gt;People in different roles and relationships to you build their perceptions based on the qualities most important to making &lt;em&gt;that particular&lt;/em&gt; relationship work well.&lt;/li&gt; 
 &lt;li&gt;Managing perception is practical: When you explicitly take note of the factors that drive other people&apos;s perceptions of you, you more firmly discover how to make them happy customers.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Tip 34: Adventure Tour Guide&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;It&apos;s obvious, but the most important aspect of getting the word out in the workplace is your ability to communicate.&lt;/li&gt; 
 &lt;li&gt;Customers (or managers) are looking to you to make them comfortable about the project they&apos;re working on.&lt;/li&gt; 
 &lt;li&gt;You must be your customer&apos;s tour guide through the unforgiving terrain of the information technology world. You will make your customers comfortable while guiding them through an unfamiliar place.&lt;/li&gt; 
 &lt;li&gt;When promotion and staffing decisions are being made, the best advocate for you is a customer who can&apos;t live without you.&lt;/li&gt; 
 &lt;li&gt;Don&apos;t forget that your customer represents the needs of the business, and you are paid to provide for those needs.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Tip 35: Me Rite Reel Nice&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;In one report, more than half of responding companies consider writing skills when making hiring and promotion decisions.&lt;/li&gt; 
 &lt;li&gt;Forty percent of surveyed companies in the service sector said that a third or fewer of their new hires had the writing skills they desired.&lt;/li&gt; 
 &lt;li&gt;Even if you&apos;re a great coder, you won&apos;t be very effective in a distributed team if you can&apos;t express yourself in words.&lt;/li&gt; 
 &lt;li&gt;Communication, especially through writing, is the bottleneck through which all your wonderful ideas must pass. You are what you can explain.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Tip 36: Being Present&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;Being face to face with your leaders and your customers is an advantage. Don&apos;t squander it.&lt;/li&gt; 
 &lt;li&gt;We not only see greater productivity and enhanced communication from face-to-face interactions, but we also form tighter bonds.&lt;/li&gt; 
 &lt;li&gt;In the majority of cases, the relationship built in a remote work environment will remain strictly centered around accomplishing tasks.&lt;/li&gt; 
 &lt;li&gt;The human tendency is to want to work with other humans –&amp;nbsp;not voicemail, email, or instant messaging but actual people.&lt;/li&gt; 
 &lt;li&gt;In a distributed environment, if making regular trips for face-to-face meetings is impractical, pick up the phone and call your bosses and co-workers instead.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Tip 37: Suit Speak&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;People who run businesses are interested in business &lt;em&gt;results&lt;/em&gt;, so marketing your accomplishments in any language other than the language of the business is ineffective.&lt;/li&gt; 
 &lt;li&gt;To sell a product to an audience, you must speak to that audience in a language they can both understand and relate to.&lt;/li&gt; 
 &lt;li&gt;As a software developer, that means framing your accomplishments in the context of the business you work for.&lt;/li&gt; 
 &lt;li&gt;To put this into practice, make a list of your recent accomplishments and write the business benefit of each.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Tip 38: Change the World&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;When you come to work without a mission, you do only what people tell you to do. And so the only ones who know what you&apos;ve done are the ones who asked you to do it.&lt;/li&gt; 
 &lt;li&gt;You must have a mission to be a good software developer in a high-cost country. You must effect visible change through your team, organization, or company.&lt;/li&gt; 
 &lt;li&gt;You must do things you&apos;re internally &lt;em&gt;driven&lt;/em&gt; to do. It&apos;s because you know things could be better, and so you &lt;em&gt;have&lt;/em&gt; to change them.&lt;/li&gt; 
 &lt;li&gt;If you don&apos;t know what your crusade is, you probably don&apos;t have one.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Tip 39: Let Your Voice Be Heard&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;Don&apos;t think of yourself as a programmer at a specific company, but as a participating member of an industry. You are a craftsperson or an artist.&lt;/li&gt; 
 &lt;li&gt;No objective system exists for rating and employing software developers. Being good is important, but doesn&apos;t get you all the way there.&lt;/li&gt; 
 &lt;li&gt;Publishing and public speaking are the best ways for your name to be propagated and your voice to be heard.&lt;/li&gt; 
 &lt;li&gt;Write on the web as if you were writing a feature column for your favorite magazine.&lt;/li&gt; 
 &lt;li&gt;More writing leads to more writing opportunities. And all of these lead to the opportunity to speak at conferences.&lt;/li&gt; 
 &lt;li&gt;Start sooner than you think you&apos;re ready: Most people undersell themselves, and you definitely have something to teach!&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Tip 40: Build Your Brand&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;Brand building has two parts: Making your mark so that people will recognize it, and then ensuring it&apos;s associated with positive traits.&lt;/li&gt; 
 &lt;li&gt;The most potentially destructive force for your brand, or that recognition and respect, is yourself.&lt;/li&gt; 
 &lt;li&gt;The things you choose to do and associate with yourself will have a lasting impact on what your name means to people. And Google never forgets.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Tip 41: Release Your Code&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;Open source developers are building a name for themselves, a reputation in the industry, and are marketing themselves in the process.&lt;/li&gt; 
 &lt;li&gt;It takes skills in leadership, release management, documentation, and product and community support to foster a community around your efforts.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Tip 42: Remarkability&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;Traditional marketing curricula refer to the four &lt;em&gt;p&lt;/em&gt;&apos;s of marketing: product, price, promotion, and placement.&lt;/li&gt; 
 &lt;li&gt;The goal of marketing is to create a connection between producers and consumers of a product or service.&lt;/li&gt; 
 &lt;li&gt;To be remarkable means that something is worthy of attention. You will not become a remarkable software developer by simply being better than all the other software developers you know.&lt;/li&gt; 
 &lt;li&gt;To be remarkable, you must be significantly different from those around you.&lt;/li&gt; 
 &lt;li&gt;You might be the smartest or the fastest software developer, but just &lt;em&gt;being&lt;/em&gt; isn&apos;t good enough. You have to be &lt;em&gt;doing something&lt;/em&gt;.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Tip 43: Making the Hang&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;Really good people won&apos;t mind if you want to know them, because such people like to be appreciated and like to talk about the topics they&apos;re passionate about.&lt;/li&gt; 
 &lt;li&gt;Most of us are afraid to try and associate with smart, well-connected people who can teach you things or find work – even thought its&apos; best for you.&lt;/li&gt; 
 &lt;li&gt;The gurus are the supernodes in the social and professional network, and connecting with them just takes a little less humility.&lt;/li&gt; 
 &lt;li&gt;Some of the most influential minds in software development are readily accessible via email or real-time chat.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Part 5: Maintaining Your Edge&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;In your career you must research, invest, execute, market, repeat. Spending too much time in any iteration of the loop puts you at risk of becoming obsolete.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Tip 44: Already Obsolete&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;The more successful your business, the more comfortable you are with your business model, leaving you vulnerable to others with radical ideas.&lt;/li&gt; 
 &lt;li&gt;The more mainstream your knowledge, the greater risk you have of being left in the technology stone age.&lt;/li&gt; 
 &lt;li&gt;If you&apos;re on the bleeding edge of today&apos;s wave, you&apos;re probably behind on the next one. Start thinking &lt;em&gt;ahead&lt;/em&gt; with your study.&lt;/li&gt; 
 &lt;li&gt;Learn something on the bleeding edge. Worst case you learn something enriching but not applicable later. Best case you remain ahead of the curve.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Tip 45: You&apos;ve Already Lost Your Job&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;If your surroundings are changing and the context of your work is constantly moving, clinging to your work creates an unhealthy dissonance that infects your work.&lt;/li&gt; 
 &lt;li&gt;Have ambition but don&apos;t buy too heavily into a long, imagined future. You cannot afford tunnel vision with something too far off.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Tip 46: Path with No Destination&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;We are a goal-oriented society, obsessed with the &lt;em&gt;outcome&lt;/em&gt; of a process. But we spend all our time &lt;em&gt;doing&lt;/em&gt; things and little time actually reaching goals.&lt;/li&gt; 
 &lt;li&gt;The meat of your career is not promotions and salary advances, but the time you spend working &lt;em&gt;regardless&lt;/em&gt; of the advances.&lt;/li&gt; 
 &lt;li&gt;If this is the core of your work life – the actual work – then you&apos;ve already arrived at your destination.&lt;/li&gt; 
 &lt;li&gt;A goal-oriented mindset leads only from one goal to the next. It has no logical end, and what most of us fail to realize is that &lt;em&gt;the path&lt;/em&gt; is the end.&lt;/li&gt; 
 &lt;li&gt;Focusing on the ending makes you forget to make the process good. And bad processes create bad products.&lt;/li&gt; 
 &lt;li&gt;Bad products also make bad processes: Once you have one of these products that is messy inside, your processes wrap around it.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Tip 47: Make Yourself a Map&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;Create a road map for your career like for a product, or &quot;your personal product road map.&quot; Use it to tell whether or not you&apos;ve moved in your career.&lt;/li&gt; 
 &lt;li&gt;Throw out some markers you can see in the distance, so you&apos;ll know that you&apos;ve moved when you get to them. Your product &quot;features&quot; are these markers.&lt;/li&gt; 
 &lt;li&gt;Think of each new set of knowledge or capability as a single feature in an application. An application with one feature isn&apos;t much of an application.&lt;/li&gt; 
 &lt;li&gt;Moreover, an application with a bunch of features that aren&apos;t cohesive is going to confuse its users.&lt;/li&gt; 
 &lt;li&gt;Although it&apos;s okay to learn diverse skills&amp;nbsp;– it expands your thinking –&amp;nbsp;it&apos;s also a good idea to think about the story your skill set tells.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Tip 48: Watch the Market&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;As the conditions of the market change, not paying attention could result in money lost or money that &lt;em&gt;could&lt;/em&gt; have been earned missed.&lt;/li&gt; 
 &lt;li&gt;The same holds true for your knowledge investments.&lt;/li&gt; 
 &lt;li&gt;If you are comfortable in your current job with your current set of skills, you might remain blissfully ignorant of the Next Big Thing as it rolls in.&lt;/li&gt; 
 &lt;li&gt;Monitor the alpha geeks, or those super-nerds who are always on the bloodiest tip of the bleeding edge&amp;nbsp;– at least in their hobby activities.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Tip 49: That Fat Man in the Mirror&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;If you&apos;re constantly exposed to something, it&apos;s hard to see it changing unless change happens rapidly.&lt;/li&gt; 
 &lt;li&gt;There is no objective, universal scale for measuring your marketability or skill as a software developer, so you&apos;ll have to develop your own.&lt;/li&gt; 
 &lt;li&gt;An easy way to measure your progress is to use a trusted third party, such as a mentor or a close colleague.&lt;/li&gt; 
 &lt;li&gt;The most important thing is to ferret out your blind spots. You don&apos;t have to fix all of them, but you must know where they are.&lt;/li&gt; 
 &lt;li&gt;Schedule time for reviews, as you won&apos;t reflect unless you make the reflection time explicit.&lt;/li&gt; 
 &lt;li&gt;Once you have a system and have scheduled time for reviews, capture the results in writing to concretize them. Review and revise the evaluation often.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Tip 50: The South Indian Monkey Trap&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;Value rigidity is when you believe in the value of something so strongly that you can no longer objectively question it.&lt;/li&gt; 
 &lt;li&gt;Not all rigidly held values are good ones. And many times something that is good in one set of circumstances is not good in another.&lt;/li&gt; 
 &lt;li&gt;Since we live every day in our careers, it&apos;s easy to develop value rigidity in our career choices: We know what has worked, and we keep doing it.&lt;/li&gt; 
 &lt;li&gt;Beware of value rigidity leading you to make poor choices in the direction your career is taking or the technologies you advocate and invest in.&lt;/li&gt; 
 &lt;li&gt;Do a project in the technology you hate most. Best case you&apos;ll learn it isn&apos;t that bad, and worst case you&apos;ll have better fodder for your arguments.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Tip 51: Avoid Waterfall Career Planning&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;The larger and more complex a project is, the less likely it is to imagine every feature in detail well enough to create a specification.&lt;/li&gt; 
 &lt;li&gt;Changing your direction from management to programming, or vice versa, isn&apos;t hard. Neither is finding a new company to work for, or moving to a different city.&lt;/li&gt; 
 &lt;li&gt;Change is not only possible in your career, but necessary.&lt;/li&gt; 
 &lt;li&gt;Set big goals, but make constant corrections along the way. Learn from the experience, and change the goals as you go.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Tip 52: Better Than Yesterday&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;We become demotivated by the complexity of bigger issues and instead turn our attention to things that are easier to measure and easier to quickly fix. This is why we procrastinate.&lt;/li&gt; 
 &lt;li&gt;Focus on making whatever it is you&apos;re trying to improve better today than it was yesterday. This is an easier goal.&lt;/li&gt; 
 &lt;li&gt;Making one small improvement is motivating: You can clearly see the difference in that &lt;em&gt;one thing&lt;/em&gt; you&apos;ve fixed as soon as the change is made.&lt;/li&gt; 
 &lt;li&gt;For big, difficult goals, individual improvements won&apos;t often lead directly to tangible results. So don&apos;t think about &lt;em&gt;getting closer&lt;/em&gt; to the goal each day, but &lt;em&gt;doing better&lt;/em&gt; in your efforts each day.&lt;/li&gt; 
 &lt;li&gt;Make your improvements small but daily. Small improvements also decrease the cost of failure: If you miss a day, you have a new baseline for tomorrow.&lt;/li&gt; 
 &lt;li&gt;You can apply this approach to very tactical goals, or you can apply it to the very highest level of goals that you have.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Tip 53: Go Independent&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;The safety blanket of corporate hierarchy slows you down: When you can hide behind the shield of mediocrity in a corporate division, there is less incentive to excel.&lt;/li&gt; 
 &lt;li&gt;Becoming an independent contractor is an ultimate test: It&apos;s only you, your expertise, and your ability to execute.&lt;/li&gt; 
 &lt;li&gt;Going independent also forces you to learn how to market yourself and at the same time tests your choices in domain and technology to focus on.&lt;/li&gt; 
 &lt;li&gt;A startup gives you a full-time salary and the challenge of being pitted directly against the unfiltered problems of your business.&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Reversing/reverse engineering</title>
      <link>https://tedneward.github.io/Research/reading/development/reversing/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">reading/development/reversing/index.html</guid>
      	<description>
	&lt;h2&gt;Books&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://beginners.re/&quot;&gt;Reverse Engineering for Beginners&lt;/a&gt; (&lt;a href=&quot;https://beginners.re/RE4B-EN.pdf&quot;&gt;Book PDF&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/iosre/iOSAppReverseEngineering&quot;&gt;iOS App Reverse Engineering&lt;/a&gt; (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://bioshacking.blogspot.co.uk/2012/02/bios-disassembly-ninjutsu-uncovered-1st.html&quot;&gt;BIOS Disassembly Ninjutsu Uncovered 1st Edition&lt;/a&gt; - Darmawan Salihun (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.nostarch.com/xboxfree/&quot;&gt;Hacking the Xbox: An Introduction to Reverse Engineering&lt;/a&gt; - Andrew &quot;bunnie&quot; Huang&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Articles&lt;/h2&gt;
	</description>
    </item>
    <item>
      <title>Open Source (concepts)</title>
      <link>https://tedneward.github.io/Research/reading/development/open-source/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">reading/development/open-source/index.html</guid>
      	<description>
	&lt;h2&gt;Licenses&lt;/h2&gt; 
&lt;h2&gt;Places&lt;/h2&gt; 
&lt;p&gt;Places that focus on the topic of OSS itself in a variety of ways.&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://chaoss.community/&quot;&gt;CHAOSS&lt;/a&gt; (Community Health Analytics in Open Source Software): CHAOSS is a Linux Foundation project focused on creating metrics, metrics models, and software to better understand open source community health on a global scale. CHAOSS is an acronym for Community Health Analytics in Open Source Software. Open source software is critically important for both individuals and organizations. This importance raises questions about how we understand the health of the open-source projects we rely on. Unhealthy projects can have negative impacts on the community involved in the project as well as organizations that rely on such projects.&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://chaoss.community/about-chaoss-practitioner-guides/&quot;&gt;Practitioner Guides&lt;/a&gt;:&lt;/p&gt; 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://chaoss.community/practitioner-guide-introduction/&quot;&gt;Introduction - Things to Think about When Interpreting Metrics&lt;/a&gt; &amp;lt;- Please start here&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://chaoss.community/practitioner-guide-contributor-sustainability/&quot;&gt;Getting Started with Contributor Sustainability&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://chaoss.community/practitioner-guide-responsiveness/&quot;&gt;Getting Started with Responsiveness&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://chaoss.community/practitioner-guide-organizational-participation/&quot;&gt;Getting Started with Organizational Participation&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://chaoss.community/practitioner-guide-security/&quot;&gt;Getting Started with Security&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://chaoss.community/practitioner-guide-sunset&quot;&gt;Getting Started with Sunsetting an Open Source Project&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://chaoss.community/practitioner-guide-diverse-leadership&quot;&gt;Getting Started with Building Diverse Leadership&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://chaoss.community/practitioner-guide-demonstrating-org-value&quot;&gt;Demonstrating Organizational Value&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://chaoss.community/practitioner-guide-viability&quot;&gt;Assessing Viability&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://chaoss.community/kb-metrics-and-metrics-models/&quot;&gt;Metrics and Models&lt;/a&gt;:&lt;/p&gt; 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://chaoss.community/kb/metrics-model-development-responsiveness/&quot;&gt;Metrics Model: Development Responsiveness&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://chaoss.community/kb/metrics-model-collaboration-development-index/&quot;&gt;Metrics Model: Collaboration Development Index&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://chaoss.community/kb/metrics-model-dei-event-badging/&quot;&gt;Metrics Model: DEI Event Badging&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://chaoss.community/kb/metrics-model-community-service-and-support/&quot;&gt;Metrics Model: Community Service and Support&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://chaoss.community/kb/metrics-model-project-engagement/&quot;&gt;Metrics Model: Project Engagement&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://chaoss.community/kb/metrics-model-funding/&quot;&gt;Metrics Model: Funding&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://chaoss.community/kb/metrics-model-project-awareness/&quot;&gt;Metrics Model: Project Awareness&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://chaoss.community/kb/metrics-model-starter-project-health/&quot;&gt;Metrics Model: Starter Project Health&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://chaoss.community/kb/metrics-model-community-activity/&quot;&gt;Metrics Model: Community Activity&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://chaoss.community/kb/metrics-model-business-readiness-of-an-open-source-project/&quot;&gt;Metrics Model: Business Readiness of an Open Source Project&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://chaoss.community/kb/metrics-model-oss-project-viability-compliance-security/&quot;&gt;Metrics Model: OSS Project Viability: Compliance + Security&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://chaoss.community/kb/metrics-model-oss-project-viability-governance/&quot;&gt;Metrics Model: OSS Project Viability: Governance&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://chaoss.community/kb/metrics-model-oss-project-viability-community/&quot;&gt;Metrics Model: OSS Project Viability: Community&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://chaoss.community/kb/metrics-model-oss-project-viability-strategy/&quot;&gt;Metrics Model: OSS Project Viability: Strategy&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://chaoss.community/kb/metrics-model-project-viability-starter/&quot;&gt;Metrics Model: Project Viability Starter&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://chaoss.community/kb/metrics-model-community-welcomingness/&quot;&gt;Metrics Model: Community Welcomingness&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://chaoss.community/kb/metrics-model-safety/&quot;&gt;Metrics Model: Safety&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://chaoss.community/kb/metric-conversion-rate/&quot;&gt;Metric: Conversion Rate&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://chaoss.community/kb/metric-meeting-attendee-count/&quot;&gt;Metric: Meeting Attendee Count&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://chaoss.community/kb/metric-chat-platform-inclusivity/&quot;&gt;Metric: Chat Platform Inclusivity&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://chaoss.community/kb/metric-issue-label-inclusivity/&quot;&gt;Metric: Issue Label Inclusivity&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://chaoss.community/kb/metric-self-merge-rates/&quot;&gt;Metric: Self-Merge Rates&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://chaoss.community/kb/metric-collaboration-platform-activity/&quot;&gt;Metric: Collaboration Platform Activity&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://chaoss.community/kb/metric-open-source-security-foundation-openssf-best-practices-badge/&quot;&gt;Metric: Open Source Security Foundation (OpenSSF) Best Practices Badge&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://chaoss.community/kb/metric-test-coverage/&quot;&gt;Metric: Test Coverage&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://chaoss.community/kb/metric-libyears/&quot;&gt;Metric: Libyears&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://chaoss.community/kb/metric-programming-language-distribution/&quot;&gt;Metric: Programming Language Distribution&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://chaoss.community/kb/metric-activity-dates-and-times/&quot;&gt;Metric: Activity Dates and Times&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://chaoss.community/kb/metric-time-to-first-response/&quot;&gt;Metric: Time to First Response&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://chaoss.community/kb/metric-review-cycle-duration-within-a-change-request/&quot;&gt;Metric: Review Cycle Duration within a Change Request&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://chaoss.community/kb/metric-branch-lifecycle/&quot;&gt;Metric: Branch Lifecycle&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://chaoss.community/kb/metric-change-requests/&quot;&gt;Metric: Change Requests&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://chaoss.community/kb/metric-change-requests-accepted/&quot;&gt;Metric: Change Requests Accepted&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://chaoss.community/kb/metric-occasional-contributors/&quot;&gt;Metric: Occasional Contributors&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://chaoss.community/kb/metric-event-locations/&quot;&gt;Metric: Event Locations&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://chaoss.community/kb/metric-licenses-declared/&quot;&gt;Metric: Licenses Declared&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://chaoss.community/kb/metric-bot-activity/&quot;&gt;Metric: Bot Activity&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://chaoss.community/kb/metric-time-to-close/&quot;&gt;Metric: Time to Close&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://chaoss.community/kb/metric-sponsorship/&quot;&gt;Metric: Sponsorship&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://chaoss.community/kb/metric-documentation-discoverability/&quot;&gt;Metric: Documentation Discoverability&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://chaoss.community/kb/metric-change-requests-declined/&quot;&gt;Metric: Change Requests Declined&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://chaoss.community/kb/metric-osi-approved-licenses/&quot;&gt;Metric: OSI Approved Licenses&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://chaoss.community/kb/metric-spdx-document/&quot;&gt;Metric: SPDX Document&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://chaoss.community/kb/metric-number-of-downloads/&quot;&gt;Metric: Number of Downloads&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://chaoss.community/kb/metric-code-of-conduct-at-event/&quot;&gt;Metric: Code of Conduct at Event&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://chaoss.community/kb/metric-event-accessibility%ef%bf%bc/&quot;&gt;Metric: Event Accessibility&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://chaoss.community/kb/metric-time-inclusion-for-virtual-events/&quot;&gt;Metric: Time Inclusion for Virtual Events&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://chaoss.community/kb/metric-board-council-diversity/&quot;&gt;Metric: Board/Council Diversity&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://chaoss.community/kb/metric-inclusive-leadership/&quot;&gt;Metric: Inclusive Leadership&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://chaoss.community/kb/metric-mentorship/&quot;&gt;Metric: Mentorship&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://chaoss.community/kb/metric-documentation-usability/&quot;&gt;Metric: Documentation Usability&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://chaoss.community/kb/metric-documentation-accessibility/&quot;&gt;Metric: Documentation Accessibility&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://chaoss.community/kb/metric-contributor-absence-factor/&quot;&gt;Metric: Contributor Absence Factor&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://chaoss.community/kb/metric-change-request-commits/&quot;&gt;Metric: Change Request Commits&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://chaoss.community/kb/metric-change-request-reviews/&quot;&gt;Metric: Change Request Reviews&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://chaoss.community/kb/metric-event-location-inclusivity/&quot;&gt;Metric: Event Location Inclusivity&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://chaoss.community/kb/metric-psychological-safety/&quot;&gt;Metric: Psychological Safety&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://chaoss.community/kb/metric-organizational-diversity/&quot;&gt;Metric: Organizational Diversity&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://chaoss.community/kb/metric-job-opportunities/&quot;&gt;Metric: Job Opportunities&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://chaoss.community/kb/metric-newcomer-experience/&quot;&gt;Metric: Newcomer Experience&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://chaoss.community/kb/metric-contributor-location/&quot;&gt;Metric: Contributor Location&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://chaoss.community/kb/metric-committers/&quot;&gt;Metric: Committers&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://chaoss.community/kb/metric-technical-fork/&quot;&gt;Metric: Technical Fork&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://chaoss.community/kb/metric-burstiness/&quot;&gt;Metric: Burstiness&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://chaoss.community/kb/metric-code-changes-lines/&quot;&gt;Metric: Code Changes Lines&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://chaoss.community/kb/metric-change-request-acceptance-ratio/&quot;&gt;Metric: Change Request Acceptance Ratio&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://chaoss.community/kb/metric-change-requests-duration/&quot;&gt;Metric: Change Requests Duration&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://chaoss.community/kb/metric-issues-new/&quot;&gt;Metric: Issues New&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://chaoss.community/kb/metric-issues-closed/&quot;&gt;Metric: Issues Closed&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://chaoss.community/kb/metric-issue-resolution-duration/&quot;&gt;Metric: Issue Resolution Duration&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://chaoss.community/kb/metric-issue-age/&quot;&gt;Metric: Issue Age&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://chaoss.community/kb/metric-inactive-contributors/&quot;&gt;Metric: Inactive Contributors&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://chaoss.community/kb/metric-license-coverage/&quot;&gt;Metric: License Coverage&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://chaoss.community/kb/metric-clones/&quot;&gt;Metric: Clones&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://chaoss.community/kb/metric-upstream-code-dependencies/&quot;&gt;Metric: Upstream Code Dependencies&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://chaoss.community/kb/metric-elephant-factor/&quot;&gt;Metric: Elephant Factor&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://chaoss.community/kb/metric-diversity-access-tickets/&quot;&gt;Metric: Diversity Access Tickets&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://chaoss.community/kb/metric-inclusive-experience-at-event/&quot;&gt;Metric: Inclusive Experience at Event&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://chaoss.community/kb/metric-family-friendliness/&quot;&gt;Metric: Family Friendliness&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://chaoss.community/kb/metric-event-demographics/&quot;&gt;Metric: Event Demographics&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://chaoss.community/kb/metric-code-of-conduct-for-a-project/&quot;&gt;Metric: Code of Conduct for a Project&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://chaoss.community/kb/defect-resolution-duration/&quot;&gt;Metric: Defect Resolution Duration&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://chaoss.community/kb/metric-code-changes-commits/&quot;&gt;Metric: Code Changes Commits&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://chaoss.community/kb/metric-release-frequency/&quot;&gt;Metric: Release Frequency&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://chaoss.community/kb/metric-public-health-and-safety/&quot;&gt;Metric: Public Health and Safety&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://chaoss.community/kb/metric-project-burnout/&quot;&gt;Metric: Project Burnout&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://chaoss.community/kb/metric-project-velocity/&quot;&gt;Metric: Project Velocity&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://chaoss.community/kb/metric-project-recommendability/&quot;&gt;Metric: Project Recommendability&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://chaoss.community/kb/metric-organizational-influence/&quot;&gt;Metric: Organizational Influence&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://chaoss.community/kb/metric-organizational-project-skill-demand/&quot;&gt;Metric: Organizational Project Skill Demand&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://chaoss.community/kb/metric-change-request-closure-ratio/&quot;&gt;Metric: Change Request Closure Ratio&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://chaoss.community/kb/metric-project-demographics/&quot;&gt;Metric: Project Demographics&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://chaoss.community/kb/metric-communication-transparency/&quot;&gt;Metric: Communication Transparency&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://chaoss.community/kb/metric-change-request-review-duration/&quot;&gt;Metric: Change Request Review Duration&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://chaoss.community/kb/metric-project-access/&quot;&gt;Metric: Project Access&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://chaoss.community/kb/metric-issues-active/&quot;&gt;Metric: Issues Active&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://chaoss.community/kb/metric-issue-response-time/&quot;&gt;Metric: Issue Response Time&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://chaoss.community/kb/metric-new-contributors-closing-issues/&quot;&gt;Metric: New Contributors Closing Issues&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://chaoss.community/kb/metric-contribution-attribution/&quot;&gt;Metric: Contribution Attribution&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://chaoss.community/kb/metric-labor-investment/&quot;&gt;Metric: Labor Investment&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://chaoss.community/kb/metric-new-contributors/&quot;&gt;Metric: New Contributors&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://chaoss.community/kb/metric-academic-open-source-project-impact/&quot;&gt;Metric: Academic Open Source Project Impact&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://chaoss.community/kb/metric-project-popularity/&quot;&gt;Metric: Project Popularity&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://chaoss.community/kb/metric-contributors/&quot;&gt;Metric: Contributors&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://chaoss.community/kb/metric-types-of-contributions/&quot;&gt;Metric: Types of Contributions&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://chaoss.community/kb/metric-conflict-resolution-and-mediation/&quot;&gt;Metric: Conflict Resolution and Mediation&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>The Philosophical Programmer</title>
      <link>https://tedneward.github.io/Research/reading/development/philosophical-programmer/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">reading/development/philosophical-programmer/index.html</guid>
      	<description>
	&lt;h1&gt;Part I: A Philosophical Introduction&lt;/h1&gt; 
&lt;ol&gt; 
 &lt;li&gt; &lt;p&gt;Beyond the Cuckoo Clock&lt;/p&gt; 
  &lt;ul&gt; 
   &lt;li&gt; &lt;p&gt;Man is a tool-using creature&lt;/p&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;First tools were extensions of our physical abilities&lt;/p&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;Medieval clock was first extension of our mind&lt;/p&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;Cuckoo clocks are analog computers--take input (swings of pendulum) and turn them into data (time representation)&lt;/p&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;Computers are digital computers, and infinitiely flexible (unike analog computers)&lt;/p&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Is There an Aesthetic of Programming?&lt;/p&gt; 
  &lt;ul&gt; 
   &lt;li&gt;discussion of algorithms as aesthetics&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;The Ethical Quotient&lt;/p&gt; 
  &lt;ul&gt; 
   &lt;li&gt; &lt;p&gt;ethical challenges: qualities of magnification, precision, alienation, believability, malleability of information, impermeability, and autonomy of operation&lt;/p&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;magnification: computers magnify our thought processes significantly, but have no conscience or controls beyond what we put on them&lt;/p&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;precision: instructions to a computer must be precise&lt;/p&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;alientation: computer isolates programmers and operators from the people affected by their actions/code. &quot;Instead of seein the program as a real instrument affecting the lives of real people, programmers sometimes see it as a game, a challenge to their ingenuity. The alienating quality of the computer permits us to overlook the human consequences of a programming decision or error.&quot; This happens to users on the Internet as well.&lt;/p&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;believability: we believe the computer because it presents us with too much information to be able to effectively doubt any of it&lt;/p&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;malleability: data can change without us knowing it&lt;/p&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;impermeability: we cannot observe the computer, only its side effects and results&lt;/p&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;autonomy of operation: the computer is capable of acting without our intervention or supervision&lt;/p&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ol&gt; 
&lt;h1&gt;Part II: The Structure of the Computer&lt;/h1&gt; 
&lt;ol&gt; 
 &lt;li&gt;Types of Computers&lt;/li&gt; 
 &lt;li&gt;The Parts of a Computer&lt;/li&gt; 
 &lt;li&gt;The Construction of Memory&lt;/li&gt; 
 &lt;li&gt;On a Clear Disk You Can Seek Forever&lt;/li&gt; 
 &lt;li&gt;A Brief Interruption&lt;/li&gt; 
 &lt;li&gt;Operating Systems&lt;/li&gt; 
&lt;/ol&gt; 
&lt;h1&gt;Part III: Fundamental Tools of Programming&lt;/h1&gt; 
&lt;ol&gt; 
 &lt;li&gt;The Language of the Machine&lt;/li&gt; 
 &lt;li&gt;Forms of Data Definition&lt;/li&gt; 
 &lt;li&gt;Classes and Types of Statements&lt;/li&gt; 
 &lt;li&gt;The Functional Program&lt;/li&gt; 
 &lt;li&gt;A Short Commentary&lt;/li&gt; 
 &lt;li&gt;Algorithms and Objects&lt;/li&gt; 
&lt;/ol&gt; 
&lt;h1&gt;Part IV: The Programmer&apos;s Trade&lt;/h1&gt; 
&lt;ol&gt; 
 &lt;li&gt;The Moth in the Machine&lt;/li&gt; 
 &lt;li&gt;The Real World Out There&lt;/li&gt; 
 &lt;li&gt;The Limitations of Design&lt;/li&gt; 
 &lt;li&gt;Programming as Abstraction and Reflection&lt;/li&gt; 
&lt;/ol&gt;
	</description>
    </item>
    <item>
      <title>Software development roles</title>
      <link>https://tedneward.github.io/Research/reading/development/roles/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">reading/development/roles/index.html</guid>
      	<description>
	&lt;h2&gt;Technical Program Manager (TPM)&lt;/h2&gt; 
&lt;p&gt;&lt;a href=&quot;https://newsletter.pragmaticengineer.com/&quot;&gt;Pragmatic Engineer&lt;/a&gt;&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://newsletter.pragmaticengineer.com/p/what-tpms-do&quot;&gt;&quot;What TPMs Do and What Software Engineers Can Learn From Them&quot;&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://newsletter.pragmaticengineer.com/p/scaling-engineering-with-the-tpm-role&quot;&gt;&quot;Scaling Engineering Organizations with the Technical Program Manager Role&quot;&lt;/a&gt; (requires paid access)&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Governance (software development)</title>
      <link>https://tedneward.github.io/Research/reading/development/governance/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">reading/development/governance/index.html</guid>
      	<description>
	&lt;h2&gt;Reading&lt;/h2&gt; 
&lt;h3&gt;Articles&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.infoworld.com/article/4090521/why-software-development-slows-to-a-crawl.html&quot;&gt;Why software development slows to a crawl&lt;/a&gt;: Software organizations don’t slow down because people stop caring. They slow down because responsibility diffuses across owners, reviewers, and committees, while the work required to push anything forward grows heavier each quarter. The challenge for leaders is to continuously tune governance so that clarity and speed increase together. ... Teams fall into a trap where a once-useful rule becomes a tradition, then a barrier. When someone asks why a particular approval exists, the answer becomes circular: because that’s our process. Good governance adapts to current needs, not historical ones. For every process gate, someone should articulate what specific risk it mitigates and what would happen without it. If the answer is “we’ve always done it this way,” the gate needs reevaluation. The most successful engineering cultures build in mechanisms for process retirement. Any new process comes with an expiration date. After six or 12 months, the rule is automatically retired unless someone actively argues for renewal with data showing its necessity. Every rule must have a documented owner and a one-sentence justification. If the current team cannot state the why, the process should be retired.&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Legacy code migration</title>
      <link>https://tedneward.github.io/Research/reading/development/legacy-migration/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">reading/development/legacy-migration/index.html</guid>
      	<description>
	&lt;h2&gt;Reading&lt;/h2&gt; 
&lt;h3&gt;Articles/Blogs/Essays&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://leaddev.com/technical-direction/measure-first-migrate-later-lessons-from-a-230-velocity-boost&quot;&gt;Measure first, migrate later&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Message passing (reading)</title>
      <link>https://tedneward.github.io/Research/reading/development/message-passing/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">reading/development/message-passing/index.html</guid>
      	<description>
	&lt;p&gt;Message-passing is often at the heart of dynamic programming languages like &lt;a href=&quot;/languages/objc.html&quot;&gt;Objective-C&lt;/a&gt;. For example, the &lt;a href=&quot;https://developer.apple.com/documentation/objectivec/objective-c_runtime&quot;&gt;ObjC runtime&lt;/a&gt; (also described &lt;a href=&quot;https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Introduction/Introduction.html#//apple_ref/doc/uid/TP40008048&quot;&gt;here&lt;/a&gt;) is a library for creating instances of objects, obtaining &quot;selectors&quot; to the names of message-receivers (methods) that the object can process, and even do some &lt;a href=&quot;metaobjectprotocol.html&quot;&gt;MOP&lt;/a&gt; operations on the objects.&lt;/p&gt; 
&lt;p&gt;In more widespread distributed systems literature, this is often called &quot;message-oriented middleware&quot; and typically involves messages dispatched over network links to &quot;queues&quot; where they are stored until examined (and possibly consumed) by messaging clients. Those who produce messages are often called &quot;producers&quot;; those who consume them, &quot;consumers&quot;.&lt;/p&gt; 
&lt;h2&gt;Reading&lt;/h2&gt;
	</description>
    </item>
    <item>
      <title>Frictionless</title>
      <link>https://tedneward.github.io/Research/reading/development/frictionless/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">reading/development/frictionless/index.html</guid>
      	<description>
	&lt;p&gt;&lt;em&gt;(Nicole Forsgren, Abi Noda; Shift Key Press Nov 2025; ISBN 978-1662966378)&lt;/em&gt;&lt;/p&gt; 
&lt;p&gt;&lt;em&gt;(As a general rule, this book is following the social media style of authorship, at a slightly larger scale: Instead of one sentence paragraphs, they&apos;re doing one- or two-page chapters. Overall, I&apos;m not entirely impressed so far, particularly since I think a good chunk of the &quot;seven steps&quot; are just a retelling of Kotter&apos;s Change Management steps. Actually, as I go through the material, I begin to suspect a good chunk of it was written by an LLM. The case studies and examples probably aren&apos;t, but a lot of the prose in between feels very LLM-ish. Stuff in Step 3 feels more genuine and additive.)&lt;/em&gt;&lt;/p&gt; 
&lt;h1&gt;PART I Understanding DevEx&lt;/h1&gt; 
&lt;h2&gt;Chapter 1 - What is Developer Experience?&lt;/h2&gt; 
&lt;p&gt;Developer experience isn’t just about making developers happy--it’s about removing friction that slows down your entire business.&lt;/p&gt; 
&lt;h2&gt;Chapter 2 - Why Developer Experience Matters&lt;/h2&gt; 
&lt;p&gt;Poor developer experience isn’t just about productivity--it can hide catastrophic business risks in plain sight.&lt;/p&gt; 
&lt;p&gt;One morning in 2012, a developer at Knight Capital pushed a routine update. Nothing seemed off--until the system started hemorrhaging money. In just 45 minutes, a single change triggered $460 million in losses. The culprit? An old feature flag, long retired, accidentally reactivated by a deployment script. But the real problem wasn’t the bug--it was a development environment that made problems impossible to detect and fix quickly, turning a routine mistake into a company-ending disaster. (Dolfing, Henrico. “Case Study 4: The $440 Million Software Error at Knight Capital.” 5 June 2019, &lt;a href=&quot;http://www.henricodolfing.com/2019/06/project-failure-case-study-knight-capital.html&quot;&gt;www.henricodolfing.com/2019/06/project-failure-case-study-knight-capital.html&lt;/a&gt;).&lt;/p&gt; 
&lt;p&gt;Fast-forward to July 2025: Jason Lemkin was using Replit’s AI coding assistant to build a database for his company SaaStr.AI. He explicitly set a “code freeze”—no changes to live data. But the AI ignored his instructions and deleted his entire production database. (&lt;a href=&quot;https://www.pcmag.com/news/vibe-coding-fiasco-replite-ai-agent-goes-rogue-deletes-company-database&quot;&gt;https://www.pcmag.com/news/vibe-coding-fiasco-replite-ai-agent-goes-rogue-deletes-company-database&lt;/a&gt;)&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;AI acceleration makes existing friction even more costly.&lt;/li&gt; 
 &lt;li&gt;Poor DevEx creates a competitive disadvantage that compounds over time.&lt;/li&gt; 
 &lt;li&gt;Developer experience has a positioning problem.&lt;/li&gt; 
 &lt;li&gt;Good developer experience isn’t just about making developers happy--it’s about removing friction to accelerate business outcomes.&lt;/li&gt; 
 &lt;li&gt;Developer experience acts as a force multiplier.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Chapter 3 - Friction: The Value Killer&lt;/h2&gt; 
&lt;p&gt;Friction can slow any progress, especially in software, which is why improving DevEx is so important.&lt;/p&gt; 
&lt;p&gt;Friction is anything that slows down or gets in the way of completing work:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;em&gt;Onboarding friction.&lt;/em&gt; New developers spend days or weeks struggling with incomplete documentation, waiting for system access approvals, and learning unintuitive toolsets before writing a single line of productive code. Even experienced developers face similar friction during laptop refreshes or system reimaging—losing valuable time during active sprints when their contributions are most needed. Remote developers struggle to find answers in documentation because reaching out for help means scheduling a meeting.&lt;/li&gt; 
 &lt;li&gt;&lt;em&gt;Codebase friction.&lt;/em&gt; Insufficient abstractions force developers to touch many places to make simple changes, brittle monolithic fixtures accumulate over time making tests hard to extend, and patterns that once served the code well become obstacles as the system evolves.&lt;/li&gt; 
 &lt;li&gt;&lt;em&gt;Integration friction.&lt;/em&gt; Misconfigured APIs and incompatible toolchains break developer flow, turning what should be seamless connections into frustrating workarounds and manual steps.&lt;/li&gt; 
 &lt;li&gt;&lt;em&gt;Process friction.&lt;/em&gt; Multi-step approval processes, several iterations of review, and bureaucratic requirements often delay actual development work. The cost of this friction often becomes apparent during hackathons when process requirements are relaxed and innovation happens quickly.&lt;/li&gt; 
 &lt;li&gt;&lt;em&gt;Review friction.&lt;/em&gt; Code reviews that should take hours stretch into days due to inefficient PR assignment, unclear code or module ownership (especially in monorepo environments), multiple review cycles caused by unclear requirements, and large and complicated PRs due to developers working in isolation.&lt;/li&gt; 
 &lt;li&gt;&lt;em&gt;Development friction.&lt;/em&gt; Painfully slow build times, test suites that are unreliable and take ages to complete, incomplete test coverage, and flaky tests that fail intermittently without real issues waste developers’ time and break concentration during active coding sessions.&lt;/li&gt; 
 &lt;li&gt;&lt;em&gt;Deployment friction.&lt;/em&gt; Rather than one-click deploys, developers write custom scripts for every code push because automation is incomplete, or spend hours manually gathering data from disparate systems to make deployment decisions.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;Eliminating these friction points creates immediate business value.&lt;/p&gt; 
&lt;p&gt;“Productivity” sets off alarm bells--”Experience” opens conversations.&lt;/p&gt; 
&lt;h1&gt;PART II The Three Essential Elements of DevEx&lt;/h1&gt; 
&lt;h2&gt;Chapter 4 - The DevEx Framework&lt;/h2&gt; 
&lt;p&gt;&lt;em&gt;Feedback loops, flow state, and cognitive load, each of which is examined further in its own chapter.&lt;/em&gt;&lt;/p&gt; 
&lt;h2&gt;Chapter 5 - Feedback Loops&lt;/h2&gt; 
&lt;p&gt;&lt;em&gt;See OODA.&lt;/em&gt;&lt;/p&gt; 
&lt;h2&gt;Chapter 6 - Flow State&lt;/h2&gt; 
&lt;p&gt;&lt;em&gt;See Csikszentmihalyi.&lt;/em&gt;&lt;/p&gt; 
&lt;h2&gt;Chapter 7 - Cognitive Load&lt;/h2&gt; 
&lt;p&gt;&quot;Excessive cognitive load directly impedes developers’ ability to deliver value to customers.&quot;&lt;/p&gt; 
&lt;p&gt;&quot;The solution is systematic reduction of unnecessary complexity.&quot;&lt;/p&gt; 
&lt;p&gt;&quot;AI presents both opportunities and risks for cognitive load.&quot;&lt;/p&gt; 
&lt;h2&gt;Chapter 8 - Use the Framework to Identify and Remove Friction&lt;/h2&gt; 
&lt;p&gt;&quot;The three elements of DevEx provide a framework for spotting and fixing friction.&quot;&lt;/p&gt; 
&lt;h1&gt;PART III Making the Business Case&lt;/h1&gt; 
&lt;h2&gt;Chapter 9 - Translate Developer Experience into Business Value&lt;/h2&gt; 
&lt;p&gt;&quot;C-suite executives speak the language of business outcomes.&quot;&lt;/p&gt; 
&lt;p&gt;&quot;Talk about recovering time: Convert developer hours into dollar value.&quot;&lt;/p&gt; 
&lt;p&gt;&quot;Talk about saving money: Quantify cost savings.&quot;&lt;/p&gt; 
&lt;p&gt;&quot;Talk about making money: Accelerating revenue through DevEx.&quot;&lt;/p&gt; 
&lt;p&gt;&lt;em&gt;&quot;Capital One&apos;s DevEx transformation&quot; citation here.&lt;/em&gt;&lt;/p&gt; 
&lt;p&gt;&quot;Talk about proven correlations: Link technical metrics to business outcomes.&quot; ... &quot;A specific example of this approach is the developer experience index (DXI), developed by DX. The DXI score is the average of 14 survey questions that ask developers about different aspects of their development process. By correlating this score against self-reported time loss, DX has found that each one-point gain in DXI score translates to saving 13 minutes per week per developer, equivalent to 10 hours annually. (Noda, Abi, and Laura Tacho. “The One Number You Need to Increase Roi per Engineer.” DX, 2025, getdx.com/research/the-one-number-you-need-to-increase-roi-per-engineer/.) This correlation allows organizations to predict financial impact from DevEx improvements.&quot;&lt;/p&gt; 
&lt;h2&gt;Chapter 10 - Connect Your Work to What Others Care About&lt;/h2&gt; 
&lt;p&gt;&quot;To gain leadership support, demonstrate how developer experience directly solves their specific business problems.&quot;&lt;/p&gt; 
&lt;p&gt;&quot;Align your DevEx work with the problems that keep your CEO and CTO up at night.&quot;&lt;/p&gt; 
&lt;p&gt;&quot;Tie it to your company’s biggest priority.&quot;&lt;/p&gt; 
&lt;p&gt;&quot;Give senior leaders something to brag about.&quot;&lt;/p&gt; 
&lt;p&gt;&quot;Reveal performance gaps.&quot;&lt;/p&gt; 
&lt;p&gt;&quot;Always reframe developer experience from a technical nice-to-have into a strategic business enabler.&quot;&lt;/p&gt; 
&lt;h1&gt;PART IV Improving DevEx: A 7-Step Process&lt;/h1&gt; 
&lt;h2&gt;STEP 1 Start Your DevEx Journey&lt;/h2&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;Reminder: &lt;a href=&quot;/management/leading-change&quot;&gt;Kotter&apos;s 8 steps&lt;/a&gt;:&lt;/p&gt; 
 &lt;ol&gt; 
  &lt;li&gt;Establishing a sense of urgency&lt;/li&gt; 
  &lt;li&gt;Forming a powerful guiding coalition&lt;/li&gt; 
  &lt;li&gt;Creating a vision&lt;/li&gt; 
  &lt;li&gt;Communicating the vision&lt;/li&gt; 
  &lt;li&gt;Empowering others to act on the vision&lt;/li&gt; 
  &lt;li&gt;Planning for and creating short-term wins&lt;/li&gt; 
  &lt;li&gt;Consolidating improvements and producing still more change&lt;/li&gt; 
  &lt;li&gt;Mantaining new approaches&lt;/li&gt; 
 &lt;/ol&gt; 
&lt;/blockquote&gt; 
&lt;h3&gt;Chapter 11 - Interview Developers&lt;/h3&gt; 
&lt;p&gt;&quot;To get good information, you’ll need to interview a diverse set of developers.&quot; 12-15. Consider factors such as years of experience, product area, type of development (e.g., legacy, mobile, cloud, data science). Make two planning lists: 1. Demographics that matter. For example, work location (onsite, remote, hybrid) and experience level (junior or senior devs). 2. Work types and organizational areas where devs work.&lt;/p&gt; 
&lt;p&gt;&quot;Let developers know that talking to you is a good use of their time.&quot;&lt;/p&gt; 
&lt;p&gt;&quot;Building strong developer experience starts with earning developers’ trust.&quot;&lt;/p&gt; 
&lt;p&gt;&quot;Most importantly, honor developers’ reality.&quot;&lt;/p&gt; 
&lt;p&gt;&quot;During the interview, let them know you are there to listen and learn.&quot;&lt;/p&gt; 
&lt;p&gt;&quot;You’ll know you’ve done enough interviews when you start hearing the same problems repeatedly—this is called saturation. It usually happens at around 12-15 interviews, but you might need fewer if clear patterns emerge earlier (generally no less than 7), or more if you’re consistently getting new information.&quot;&lt;/p&gt; 
&lt;h3&gt;Chapter 12 - Synthesize What You Learn&lt;/h3&gt; 
&lt;p&gt;&quot;Start identifying labels while you’re still in interview mode.&quot;&lt;/p&gt; 
&lt;p&gt;&quot;Build a flexible framework that evolves with your understanding.&quot;&lt;/p&gt; 
&lt;p&gt;&quot;Capture these themes and supporting evidence in a simple document.&quot;&lt;/p&gt; 
&lt;p&gt;&quot;Take a second pass through your notes.&quot;&lt;/p&gt; 
&lt;h3&gt;Chapter 13 - Visualize Your Developers’ Workflow, Tools, and Friction&lt;/h3&gt; 
&lt;p&gt;&quot;List the steps your developers have to do to write and ship code.&quot;&lt;/p&gt; 
&lt;p&gt;&quot;List &lt;em&gt;everything&lt;/em&gt;, even if it seems trivial—you never know where friction might be lurking.&quot;&lt;/p&gt; 
&lt;p&gt;&quot;Don’t forget specialized developer workflows.&quot;&lt;/p&gt; 
&lt;p&gt;&quot;Consider turning your lists into workflow diagrams.&quot;&lt;/p&gt; 
&lt;h3&gt;Chapter 14 - Understand Your Stakeholders&lt;/h3&gt; 
&lt;p&gt;&quot;You might be surprised just how many stakeholders you have.&quot;&lt;/p&gt; 
&lt;p&gt;Start by listing all potential stakeholder groups. These may include:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Engineering teams: Developers, tech leads, and engineering managers directly affected by improvements.&lt;/li&gt; 
 &lt;li&gt;Auxiliary functions: SREs, data scientists, and customer success engineers may not be product engineers, but your investigations and solutions will likely impact their work.&lt;/li&gt; 
 &lt;li&gt;Leadership: CTOs, VPs of engineering, and other decision-makers who approve resources.&lt;/li&gt; 
 &lt;li&gt;Adjacent functions: Product managers, designers, and QA professionals who interface with development.&lt;/li&gt; 
 &lt;li&gt;Support functions: HR professionals interested in retention metrics, Finance team members monitoring costs, Security teams concerned with compliance aspects&lt;/li&gt; 
 &lt;li&gt;External groups: Customers or partner teams who may benefit from improved developer productivity&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Chapter 15 - Share What You’ve Learned&lt;/h3&gt; 
&lt;p&gt;&quot;Once you’ve synthesized what you learned, be sure to share your findings.&quot;&lt;/p&gt; 
&lt;p&gt;&quot;Once your summaries are shared, be prepared for continued dialogue.&quot;&lt;/p&gt; 
&lt;h2&gt;STEP 2 Start Small and Get a Quick Win&lt;/h2&gt; 
&lt;h3&gt;Chapter 16 - Pick the Right Projects&lt;/h3&gt; 
&lt;p&gt;&quot;When kicking off a DevEx improvement initiative, you need visible wins that validate your approach and transform skeptics into advocates.&quot;&lt;/p&gt; 
&lt;p&gt;&quot;The RICE framework--Reach, Impact, Confidence, Effort--gives you a simple way to evaluate opportunities without getting bogged down in analysis paralysis. RICE can help you tease out projects that have a higher likelihood of success, targeting those with high reach, high impact, and high confidence, while keeping effort low. For early project selection, think of this as “Quick RICE” or “gut-check RICE”—you’re making rapid assessments to identify promising candidates, not conducting detailed analysis. That deeper dive comes later when you have more data.&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Reach: How many developers feel this pain? 
  &lt;ul&gt; 
   &lt;li&gt; &lt;p&gt;Focus on broad reach. Choose improvements that can benefit many developers rather than solving deep problems for a few.&lt;/p&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;Consider frequency. Areas of friction that impact developers frequently (e.g., daily or multiple times a day) are great candidates for early projects.&lt;/p&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Impact: Will developers immediately notice the improvement? 
  &lt;ul&gt; 
   &lt;li&gt; &lt;p&gt;Target visible impact. Pick improvements that developers immediately feel, reducing the need to prove value later. Example: Implementing automated dependency checks and standardized PR templates to reduce code review cycles from three days to one day.&lt;/p&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;Focus on problems developers recognize. Target issues that developers already know about and feel personally. While it’s tempting to tackle underlying root causes, developers and their managers want to see and feel progress. These wins build credibility and naturally gain leadership attention.&lt;/p&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Confidence: Can you deliver this successfully?&lt;/p&gt; 
  &lt;ul&gt; 
   &lt;li&gt; &lt;p&gt;Look for clear milestones where you can show progress. Select initiatives where you can easily identify visible checkpoints that stakeholders can track. Milestones let you demonstrate incremental success, maintain momentum, and identify when something isn’t working before you’ve invested too much time.&lt;/p&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;Choose measurable projects. Select projects where progress and value can be measured through existing or easy-to-capture metrics. This approach eliminates the double burden of both delivering value and proving it exists, allowing your team to focus on solving problems rather than measuring them.&lt;/p&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Effort: How quickly can you show results?&lt;/p&gt; 
  &lt;ul&gt; 
   &lt;li&gt; &lt;p&gt;Find low-hanging fruit. Look for annoying but fixable issues (some people call these “paper cuts”). Common examples include automating repetitive tasks, fixing flaky tests, improving a difficult UI, or streamlining access to development environments. Depending on your context, some of these may require more work, so evaluate and look for things that can be addressed within weeks (or maybe a few months).&lt;/p&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;Target medium complexity. Choose projects complex enough to deliver meaningful value but not so complex that they risk getting stuck. These “goldilocks” initiatives— such as fixing flaky test suites, improving monitoring dashboards, or finishing data migrations—demonstrate competence while maintaining momentum. Avoid both trivial changes that feel like busywork and ambitious refactors that could take quarters to complete.&lt;/p&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;Consider timelines. Early projects should show results in three months, while later efforts should have visible milestones every six to nine months. For example, avoid choosing an initial project that requires a significant re-architecture, as these typically take a significant amount of time and offer little visible progress until they are complete.&lt;/p&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;When evaluating your candidate projects from interview synthesis:&lt;/p&gt; 
&lt;ol&gt; 
 &lt;li&gt;Score each project on a simple scale (High/Medium/Low) for each RICE component.&lt;/li&gt; 
 &lt;li&gt;Look for patterns--projects scoring High on reach and impact with Medium or Low effort are often winners.&lt;/li&gt; 
 &lt;li&gt;Trust your instincts--if something feels off despite good scores, dig deeper.&lt;/li&gt; 
 &lt;li&gt;Consider combinations--sometimes two smaller projects together create more impact than one large one.&lt;/li&gt; 
&lt;/ol&gt; 
&lt;p&gt;&quot;Turn evaluation into clarity.&quot;&lt;/p&gt; 
&lt;p&gt;&quot;Your DevEx breakthrough might be a process, not a tool.&quot;&lt;/p&gt; 
&lt;h3&gt;Chapter 17 - Share Early Wins to Gain Momentum&lt;/h3&gt; 
&lt;p&gt;&quot;Fail fast and share your learnings.&quot;&lt;/p&gt; 
&lt;p&gt;&quot;Celebrate wins along the way.&quot;&lt;/p&gt; 
&lt;p&gt;&quot;Bring others along on the journey.&quot;&lt;/p&gt; 
&lt;p&gt;&quot;Share your findings thoughtfully.&quot;&lt;/p&gt; 
&lt;p&gt;&quot;Keep the conversation going.&quot;&lt;/p&gt; 
&lt;h3&gt;Chapter 18 - Avoid Common Pitfalls&lt;/h3&gt; 
&lt;p&gt;Van Buren and Safferstone studied 5,400 leaders implementing new initiatives in companies. Their work reveals common pitfalls that can undermine long-term success. (Van Buren, Mark E., and Todd Safferstone. “The quick wins paradox.” Harvard Business Review 87.1 (2009): 54-61.) Here’s how successful leaders navigate these challenges:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt; &lt;p&gt;Handling feedback.&lt;/p&gt; 
  &lt;ul&gt; 
   &lt;li&gt; &lt;p&gt;Don’t get defensive when questioned. It’s natural to feel protective of work you’ve invested in, but defensiveness shuts down dialogue. Instead, explain your rationale and reasoning—this builds understanding rather than resistance. DevEx teams often assume their experience represents the broader engineering org—a common blind spot.&lt;/p&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;Do treat criticism as valuable input. Engineers are your customers, and their feedback shapes better solutions. Stay curious, seek early feedback, and remember that listening builds trust.&lt;/p&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Team dynamics.&lt;/p&gt; 
  &lt;ul&gt; 
   &lt;li&gt; &lt;p&gt;Don’t be overconfident when prescribing solutions. Teams may have tried similar approaches and encountered hidden challenges. Focus on identifying and prioritizing problems.&lt;/p&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;Do balance knowledge with genuine curiosity. Let empowered teams explore solutions to the problems you identify, and continue to gather insights from listening tours.&lt;/p&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Decision making.&lt;/p&gt; 
  &lt;ul&gt; 
   &lt;li&gt; &lt;p&gt;Don’t build solutions in isolation. Even with the best intentions to show quick progress, DevEx teams often fall into the trap of working alone to avoid dealing with different opinions. This is especially true in DevEx initiatives because your customers often have strong opinions about the right sonlution.&lt;/p&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;Do embrace collaboration. Choose initiatives that engage the broader engineering organization. While individual quick fixes may seem more efficient, projects with shared ownership create better solutions and stronger buy-in.&lt;/p&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Execution style.&lt;/p&gt; 
  &lt;ul&gt; 
   &lt;li&gt; &lt;p&gt;Don’t micromanage engineers—trust empowered teams across the organization to explore solutions. The best initiatives—and products—are those where leaders identify and prioritize problems, and empowered engineering teams explore solutions.&lt;/p&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;Do invest in sharing context. When engineers understand the broader picture, they design better solutions and make informed decisions. This also builds trust in team judgment. Create clear communication channels for updates and decisions. The research shows that the most successful leaders don’t avoid quick wins—they embrace them. The key difference is their focus on building team capability and shared success rather than individual achievements.&lt;/p&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;STEP 3 Use Data to Optimize Your Own DevEx Work&lt;/h2&gt; 
&lt;h3&gt;Chapter 19 - Establish Your Data Foundation&lt;/h3&gt; 
&lt;p&gt;There are a few kinds of data to think about, and they overlap a bit.&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Qualitative data is descriptive, and includes things like interview transcripts and open-text responses in surveys.&lt;/li&gt; 
 &lt;li&gt;Quantitative data is numerical, specifically in ways that can be calculated, for example a response on a 1-5 survey scale, or statistics from version control system use.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;We will also talk about self-report and system data, each of which can be either qualitative or quantitative.&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Self-report data comes from people’s perceptions and experiences. It can be qualitative (like interviews or open-text responses) or quantitative (like 1-5 scale survey responses).&lt;/li&gt; 
 &lt;li&gt;System data can be observed and measured externally. This is also called objective data. It’s typically quantitative (such as number of commits or turnaround time on a PR) but can also be qualitative (such as error messages).&lt;/li&gt; 
&lt;/ul&gt; 
&lt;table&gt; 
 &lt;thead&gt; 
  &lt;tr&gt;
   &lt;th&gt;. &lt;/th&gt;
   &lt;th&gt; Qualitative Data &lt;/th&gt;
   &lt;th&gt; Quantitative Data&lt;/th&gt;
  &lt;/tr&gt; 
 &lt;/thead&gt; 
 &lt;tbody&gt; 
  &lt;tr&gt;
   &lt;td&gt;Self-report Data &lt;/td&gt;
   &lt;td&gt; Interview transcripts; Open-ended survey responses; Feedback comments &lt;/td&gt;
   &lt;td&gt; Survey ratings; Satisfaction scores; Self-reported productivity metrics&lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt;System Data &lt;/td&gt;
   &lt;td&gt; Error messages; Log entries; Documentation content; User flow &lt;/td&gt;
   &lt;td&gt; Build times; Deployment frequencies; Error rates; System performance metrics&lt;/td&gt;
  &lt;/tr&gt; 
 &lt;/tbody&gt; 
&lt;/table&gt; 
&lt;p&gt;&quot;Surveys and system data are strategic partners, each with unique strengths.&quot;&lt;/p&gt; 
&lt;p&gt;&quot;The most successful DevEx initiatives use both self-report and system data.&quot;&lt;/p&gt; 
&lt;h3&gt;Chapter 20 - Identify and Use the Data You Already Have&lt;/h3&gt; 
&lt;p&gt;&quot;Most organizations have untapped metrics that can provide valuable insights into developer experience.&quot;&lt;/p&gt; 
&lt;p&gt;For example:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Development activity. Version control metrics, pull request patterns, code review times, AI assistant adoption and code generation.&lt;/li&gt; 
 &lt;li&gt;Build and test performance. CI/CD pipeline metrics, test coverage, build times, failure rates—both for traditional and AI-assisted development.&lt;/li&gt; 
 &lt;li&gt;Operations. Deployment frequency, infrastructure costs, monitoring and logging information.&lt;/li&gt; 
 &lt;li&gt;Process. Ticket resolution times, incident response data, feature delivery cycles.&lt;/li&gt; 
 &lt;li&gt;Feedback. Existing developer surveys, retrospective notes, onboarding feedback.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;Find early insights from existing data. Once you find and document your existing data sources, here are some ways to extract valuable insights:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt; &lt;p&gt;Development history analysis.&lt;/p&gt; 
  &lt;ul&gt; 
   &lt;li&gt; &lt;p&gt;Analyze commit patterns: Look for frequency trends, time-of-day patterns, and areas with high churn.&lt;/p&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;Examine pull request metrics: Review time-to-merge, review cycles, and comment patterns.&lt;/p&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;Track feature lifecycles: Identify abandoned projects, reverted changes, and their contexts.&lt;/p&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;Compare AI vs. non-AI development patterns: Review metrics between developers using AI tools and those using traditional approaches. Look for learning curves, productivity changes, and new friction points.&lt;/p&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Incident and failure analysis.&lt;/p&gt; 
  &lt;ul&gt; 
   &lt;li&gt; &lt;p&gt;Connect code changes to incidents: Map specific commits or deployment patterns to system failures. Look for correlations with AI-assisted coding and AI-enabled toolchains.&lt;/p&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;Study incident reports: Identify recurring issues, response times, and root causes.&lt;/p&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;Review postmortem documentation: Extract lessons learned and improvement recommendations, and note any recurring patterns.&lt;/p&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Project documentation mining.&lt;/p&gt; 
  &lt;ul&gt; 
   &lt;li&gt; &lt;p&gt;Analyze archived project specs: Understand reasons for project cancellations or pivots.&lt;/p&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;Review technical debt notes: Identify areas where shortcuts were taken and why.&lt;/p&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;Examine architecture decision documents: Learn from past decisions and their outcomes.&lt;/p&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Tool and platform usage.&lt;/p&gt; 
  &lt;ul&gt; 
   &lt;li&gt; &lt;p&gt;Monitor CI/CD pipeline performance: Track build times, failure rates, and bottlenecks across both traditional and AI-assisted workflows.&lt;/p&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;Review platform support ticket patterns: Identify recurring developer pain points.&lt;/p&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;Analyze tool adoption data: Understand which tools developers actually use vs. available tools.&lt;/p&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Chapter 21 - Use Surveys for Fast Insights&lt;/h3&gt; 
&lt;p&gt;&quot;You can get actionable insights now through surveys.&quot;&lt;/p&gt; 
&lt;p&gt;&quot;A powerful DevEx survey doesn’t need to be long—and it shouldn’t be.&quot;&lt;/p&gt; 
&lt;p&gt;&quot;Measure value with the Sean Ellis Test. While active user metrics and satisfaction scores provide valuable signals, occasionally you need a more direct assessment of how essential your solution—or an existing tool—has become to users. The Sean Ellis Test offers a simple and powerful method that startup companies use to determine product-market fit, and it works equally well for internal developer tools. The test centers on a single powerful question: &lt;em&gt;“How would you feel if you could no longer use [your platform/tool]?”&lt;/em&gt; With just three possible responses: Very disappointed; Somewhat disappointed ;Not disappointed (it isn’t that useful). Through extensive work with startups, Ellis found that products with strong market fit consistently have at least 40 percent of users answering they would be “very disappointed” if they could no longer use the tool. This threshold has become a reliable benchmark for product success.&quot; ... &quot;However, be cautious when interpreting results for mandated tools where users have no alternatives. In these cases, consider adapting the question. For example: &lt;em&gt;“&lt;strong&gt;If you had a choice of developer tools&lt;/strong&gt;, how would you feel if you could no longer use [current tool]?”&lt;/em&gt; This framing helps distinguish between genuine tool value and organizational dependency. You can also pair the Ellis Test with satisfaction questions to better understand whether high disappointment scores reflect tool love or job necessity.&quot;&lt;/p&gt; 
&lt;h3&gt;Chapter 22 - Invest in System Metrics Over Time&lt;/h3&gt; 
&lt;p&gt;When starting out, you might rely heavily on surveys (around 80 percent) with some system data (around 20 percent), giving you quick, broad insights into developer pain points. As you progress in your initiative and you instrument more systems, this balance shifts along an S-curve pattern—system data gradually increases, then ramps up significantly as you build more automated collection capabilities. In mature DevEx programs, system data often comprises the majority of your information simply due to the volume you can collect automatically. Surveys remain crucial throughout your journey and never disappear entirely. Even in mature programs, you’ll continue using survey data for instrumentation decisions, uncovering hidden friction points, and measuring developer satisfaction. The key is that while system data provides precision and continuous monitoring, survey data provides the context and human perspective that systems can’t capture.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Beware survey fatigue.&lt;/strong&gt;&lt;br&gt; We all know this but it’s worth repeating: Bombard your developers with surveys and they’ll stop giving you the insights you actually need. You need to be realistic about what data you can get, what you can’t get, and how often you can get it.&lt;br&gt; &lt;strong&gt;Developers only have so much attention, and work is their priority.&lt;/strong&gt; Your developers are solving complex problems all day. When you ask them to stop that work to fill out a survey, you’re making a withdrawal from a limited attention bank. Make too many withdrawals, and the account closes. Here are some tips for survey success:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;The 15-minute maximum. If your survey takes longer than 15 minutes to complete, you’ve already lost. Developers will either abandon it halfway through or rush answers just to finish. 
  &lt;ul&gt; 
   &lt;li&gt; &lt;p&gt;The timing sweet spot. Forget monthly surveys. We’ve seen dramatically better results with a three- or six-month cadence. Why? Because that’s roughly how long it takes to implement meaningful changes based on previous feedback, and it’s minimal interruption to developer’s work. Show progress before asking for more input.&lt;/p&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;The importance of consolidation. If your organization already has a developer survey but it’s not giving you what you need, don’t launch a competing survey. That’s positioning yourself against an established player (bad move) and introducing additional work for devs (another bad move). Instead, partner with the existing survey team and position your questions as complementary.&lt;/p&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;The differentiation requirement. Multiple surveys can coexist, but they’re most successful when they have clear, distinct positioning in developers’ minds. A culture survey and a technical workflow survey can both succeed if they’re properly positioned and spaced several weeks or months apart.&lt;/p&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;&lt;strong&gt;Do a final check.&lt;/strong&gt; Before you hit “send” on that survey, ask yourself: “If I were in my developers’ shoes, would I stop what I’m doing to answer these questions?” and “Would I care about the results of this survey? Would I want to share the results with someone else?” If the answers aren’t obvious yeses, you need to reposition your approach. &lt;strong&gt;&lt;em&gt;The teams that win at developer feedback aren’t the ones with the most surveys—they’re the ones who respect the context their developers operate in and position their feedback requests accordingly.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;Survey data can be very useful when you don’t have good system data, but don’t fall into the trap of waiting for perfect system data before taking action. Perfect is the enemy of progress. The transition to more system data happens organically as you identify data sources with reasonable quality and coverage across your organization. For instance, if pull requests are a point of friction, you’ll want to analyze metrics like PR cycle time (how long it takes to complete a PR) and PR dwell time (a component of overall cycle time, focusing on how long a PR waits before it is acted on). These objective measures provide precise data about specific friction points.&lt;/p&gt; 
&lt;p&gt;When considering your data, beware of common fallacies that can mislead your DevEx efforts. The &lt;em&gt;streetlight effect&lt;/em&gt; occurs when you focus exclusively on areas where you already have strong system data. Don’t limit your attention to what’s easy to measure. Even in mature DevEx improvement programs, surveys continue to provide crucial insights about emerging issues, subjective experiences, and areas that are difficult to instrument. This is why maintaining some survey component remains valuable even as system data grows to dominate your overall metrics portfolio. Equally important is avoiding the &lt;em&gt;snapshot fallacy&lt;/em&gt;. Don’t treat a single survey or data collection as permanent truth. DevEx needs evolve as your organization changes, technologies advance, and developers gain experience. Plan for regular pulse surveys and ongoing system data analysis to maintain an accurate, current picture of developer experience.&lt;/p&gt; 
&lt;h3&gt;Chapter 23 - Make Sure You Capture the Right Data&lt;/h3&gt; 
&lt;p&gt;&quot;The most effective data strategies work backward from problems to metrics. Start with the pain points your surveys reveal, then identify what specific data would help you understand and track improvements in those areas.&quot;&lt;/p&gt; 
&lt;p&gt;&quot;We suggest you also consider the dimensions of developer experience your metrics represent. Frameworks like SPACE (satisfaction, performance, activity, communication, and efficiency and flow) can help ensure you’re capturing a complete picture rather than just what’s easy to measure.&quot;&lt;/p&gt; 
&lt;p&gt;&quot;Don’t forget to collect data to build a strong business case. Many DevEx improvement initiatives stumble because they focus too narrowly on technical metrics like build times and test effectiveness. While these measurements are essential, they often don’t resonate with all stakeholders or clearly demonstrate business value.&quot;&lt;/p&gt; 
&lt;p&gt;&quot;As you get more data, you’ll need to be more careful about analyzing and drawing conclusions from it.&quot;&lt;/p&gt; 
&lt;p&gt;&quot;Get representative data to understand what’s happening. To build an accurate picture, collect data from across your organization. Your data collection strategy—whether for interviews, surveys, or system logs—directly impacts your conclusions.&quot;&lt;/p&gt; 
&lt;p&gt;&quot;Get enough data to understand what’s happening. Your goal is to get enough data to feel confident about insights and next steps, without getting bogged down in academic-level statistical significance. Here are some good rules of thumb for when you’re just getting started.&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt; &lt;p&gt;For surveys, shoot for at least 30-50 responses. More is better, but you’ll start getting good insights at this level. Getting 100+ responses often gives you pretty stable findings for practical purposes. Depending on your organization—for example, how it’s structured, how technology platforms are used, org-wide cultural differences—we suggest getting enough responses (30-50) per business unit or product team.27&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;For interviews, start with 5-8 people. Keep going until you’re not hearing many new things—usually around 12-15 interviews for focused topics. (You may hear this called “reaching saturation.”) If every interview brings totally new information, you’re still learning and probably need more.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;For system data, aim for comprehensive coverage—ideally data from at least 80 percent of your target systems or population. Make sure your data definitions are consistent and well-documented (e.g., what counts as a “build failure” or “deployment”). Watch out for data quality issues such as missing timestamps, incomplete logs, or inconsistent formatting. If you’re measuring over time, collect at least a few weeks of data to account for typical variations in usage patterns. Be especially careful about seasonality--collecting data during a holiday period or major release cycle might not represent typical patterns.&quot;&lt;/p&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;&quot;Get enough data from enough people to understand what’s happening. For surveys, a response rate above 30 percent is pretty good for most organizational contexts. However, 20-30 percent is fairly typical and usually gives you workable data. If you’re below 15 percent, that’s when you should start wondering if there might be issues with your distribution approach or if the survey itself might be too long or overly complicated.&quot;&lt;/p&gt; 
&lt;p&gt;&quot;When analyzing developer feedback, focus on representation over raw numbers. A 30 percent response rate from developers across different teams, roles, and experience levels will tell you more about patterns across the organization than a 70 percent response rate that’s mostly from one group. This principle applies to both survey data and behavioral metrics.&quot;&lt;/p&gt; 
&lt;p&gt;&quot;Building high response rates. You can achieve surprisingly high participation rates over time by building trust and demonstrating impact. For example, Amazon’s annual developer survey achieved over 90 percent response rates despite taking an hour to complete—a remarkable achievement that came from consistently showing developers how their feedback drove real changes and transparently reporting results back to them. Similarly, hundreds of companies using the DX platform see response rates over 90 percent, thanks to thoughtful survey design, transparent dashboards, and follow-up action that the companies take on the data. The key insight: &lt;strong&gt;&lt;em&gt;Response rates aren’t just about the survey itself, but about the broader culture of feedback and action.&lt;/em&gt;&lt;/strong&gt; When developers see their input driving real changes, they’re willing to invest more time in future surveys.&quot;&lt;/p&gt; 
&lt;h3&gt;Chapter 24 - Turn Data Into Actionable Insights&lt;/h3&gt; 
&lt;p&gt;When you’re diving into DevEx data, start with the basics.&lt;/p&gt; 
&lt;p&gt;Performance bottlenecks emerge when your statistical measures don’t align. The gap between median and average in the build time example points to infrastructure inconsistencies or problematic edge cases that are dragging down the development process.&lt;/p&gt; 
&lt;p&gt;Usage patterns show up in frequency counts and trends over time. A trend line of deployment frequencies could reveal that teams deploy less often on Mondays—sparking questions about team workflows, meeting schedules, or even weekend incident recovery patterns.&lt;/p&gt; 
&lt;p&gt;Friction points can become visible through distributions and frequency counts. When you analyze where developers spend the most time or encounter the most errors, you can spot the bottlenecks.&lt;/p&gt; 
&lt;p&gt;Visualizations are your friend--they transform abstract numbers into patterns that people can quickly grasp. A histogram of build times might immediately show you have a “long tail” of problematic builds, while a trend line of deployment frequencies could reveal that teams deploy less often on Mondays or the end of the fiscal year. These visual patterns often spark the right questions: “Why do we see this dip here?” or “What changed when this metric improved?” Even better, visualizations make it easier to share insights with stakeholders who might get lost in raw numbers.&lt;/p&gt; 
&lt;p&gt;You can do much of the analysis yourself, but sometimes it’s best to partner with a data scientist.&lt;/p&gt; 
&lt;p&gt;Privacy and security are important to consider when sharing results and visualizations. ... A good rule is the Rule of 5: Never show data for groups smaller than five developers. This prevents someone from figuring out, say, which specific developer is struggling with a particular API or deployment system. Also, be extra careful with free-text comments in surveys—they can accidentally contain sensitive information.&lt;/p&gt; 
&lt;h2&gt;STEP 4 Decide Strategy and Priority&lt;/h2&gt; 
&lt;p&gt;Every item on your ever-growing list is important to someone, but may not resonate with someone else.&lt;/p&gt; 
&lt;h3&gt;Chapter 25 - Focus Your DevEx Efforts&lt;/h3&gt; 
&lt;p&gt;Use RICE criteria to clarify decisions and create buy-in—now with real data.&lt;/p&gt; 
&lt;p&gt;An important part of prioritizing is saying no. ... RICE helps you say no systematically by forcing you to evaluate the full picture—not just the loudest complaints or the most interesting technical challenges.&lt;/p&gt; 
&lt;h3&gt;Chapter 26 - Use Relevant Criteria to Set Priority for Developer Experience&lt;/h3&gt; 
&lt;p&gt;RICE can help you tease out projects that have a higher likelihood of success, targeting those with high reach, high impact, and high confidence, while keeping effort low.&lt;/p&gt; 
&lt;p&gt;RICE = (Reach x Impact x Confidence) / Effort&lt;/p&gt; 
&lt;p&gt;Reach measures how many developers are affected and how often. This is your foundation for understanding true impact scale. Possible questions to ask:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;How many developers does this affect?&lt;/li&gt; 
 &lt;li&gt;What’s the frequency of impact? (Daily friction usually trumps quarterly pain.)&lt;/li&gt; 
 &lt;li&gt;Does this affect high-leverage developers disproportionately?&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;Use consistent units across all calculations. For example, don’t mix “daily impacts” for some items with “number of developers affected” for others. This ensures a fair comparison across different types of improvements.&lt;/p&gt; 
&lt;p&gt;Impact assesses how significantly this change will improve developers’ daily experience. Questions to ask:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Will developers immediately feel this improvement?&lt;/li&gt; 
 &lt;li&gt;How significantly will this change their daily experience?&lt;/li&gt; 
 &lt;li&gt;Does this remove a major constraint or just reduce minor friction? When scoring impact, use a simple 1-3 scale: 
  &lt;ul&gt; 
   &lt;li&gt;1 = Low impact: Minor improvement to workflow.&lt;/li&gt; 
   &lt;li&gt;2 = Moderate impact: Noticeable productivity gain.&lt;/li&gt; 
   &lt;li&gt;3 = High impact: Major bottleneck elimination or significant time savings.&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;Confidence reflects how certain you are that the initiative will succeed as planned, and is typically estimated as a percentage (e.g., 80% confident). Consider:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Technical feasibility and known solutions.&lt;/li&gt; 
 &lt;li&gt;Team expertise and capacity.&lt;/li&gt; 
 &lt;li&gt;Dependencies and potential blockers.&lt;/li&gt; 
 &lt;li&gt;Past experience with similar initiatives.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;Effort measures the total investment needed, typically in person-months. Be sure to include:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Development time.&lt;/li&gt; 
 &lt;li&gt;Testing and deployment.&lt;/li&gt; 
 &lt;li&gt;Documentation and training.&lt;/li&gt; 
 &lt;li&gt;Ongoing maintenance considerations.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;Look for business impact and strategic alignment. Start by asking, “Is it easy for me to talk about this challenge in terms of metrics that business leaders care about?” Equally important is considering, “How does this initiative align with or leverage existing work to maximize business value?”&lt;/p&gt; 
&lt;p&gt;Think about collective vs. local action.&lt;/p&gt; 
&lt;p&gt;Consider timelines, urgency, and organizational readiness. Key questions here include:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;“What challenge is best to tackle first because it is the fastest to complete?”&lt;/li&gt; 
 &lt;li&gt;“Do we have the right skills internally, or will this require external expertise?”&lt;/li&gt; 
 &lt;li&gt;“Can we address this challenge with our current resources and capabilities?”&lt;/li&gt; 
 &lt;li&gt;“Which challenges will get worse if we wait, and what problems will that create?”&lt;/li&gt; 
 &lt;li&gt;“How does this initiative align with our organization’s natural business rhythm?”&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;Use constraints and risks. Great questions to ask here include:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;“What challenge should we tackle first because it represents a critical bottleneck in our development flow?”&lt;/li&gt; 
 &lt;li&gt;“Do we have control over the key dependencies needed for success?”&lt;/li&gt; 
 &lt;li&gt;“Can we implement this change with minimal disruption to existing workflows?”&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;Don’t forget team and organizational factors. Ask yourself, “Which challenge allows us to strengthen our people and organization while solving technical problems?” Look for projects where team members can make meaningful contributions that showcase their expertise while creating opportunities for growth and recognition. The most successful initiatives align with teams’ professional development interests and incentives.&lt;/p&gt; 
&lt;p&gt;Don’t forget other considerations. The examples above aren’t comprehensive–you’ll want to include criteria specific to your organization.&lt;/p&gt; 
&lt;h3&gt;Chapter 27 - See the Bigger Picture: Use a Quick Rubric&lt;/h3&gt; 
&lt;p&gt;Avoid getting lost in the weeds by looking at the big picture.&lt;/p&gt; 
&lt;p&gt;Create your rubric. Start with the criteria that matter most for your organization. Common DevEx prioritization criteria include:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;RICE analysis&lt;/li&gt; 
 &lt;li&gt;Can be mapped to business value.&lt;/li&gt; 
 &lt;li&gt;Requires collective action.&lt;/li&gt; 
 &lt;li&gt;Aligns with timelines and rhythm of business.&lt;/li&gt; 
 &lt;li&gt;Is a constraint.&lt;/li&gt; 
 &lt;li&gt;Aligns with team goals.&lt;/li&gt; 
 &lt;li&gt;[Your context-specific questions here.]&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;Make the most of your analysis. The combination of RICE scoring and strategic rubrics gives you perspective:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Use RICE scores for quantitative justification, ROI calculations, and detailed resource planning.&lt;/li&gt; 
 &lt;li&gt;Use the rubric for strategic communication, stakeholder alignment, and big-picture decision making.&lt;/li&gt; 
 &lt;li&gt;When they conflict, consider whether your RICE inputs need adjustment or whether strategic factors (such as timeline or team capacity) should override pure numerical optimization.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;STEP 5 Sell Your Strategy&lt;/h2&gt; 
&lt;p&gt;Many DevEx teams underestimate the importance of strategic communications.&lt;/p&gt; 
&lt;h3&gt;Chapter 28 - Leverage Your Stakeholder Analysis for Effective Communication&lt;/h3&gt; 
&lt;p&gt;The relationships you’ve built and insights you’ve gathered during your listening tour will help you craft messages that resonate with each group.&lt;/p&gt; 
&lt;p&gt;Remember your stakeholders are more than just developers.&lt;/p&gt; 
&lt;p&gt;Tailor your approach based on stakeholder characteristics.&lt;/p&gt; 
&lt;p&gt;Refine your stakeholder list with communication-specific details. &quot;We often find it helpful to list key stakeholders and information in a table or a spreadsheet. This is handy for organization as well as identifying any information you may be missing for certain stakeholder groups. Your stakeholders—and the information you decide to collect—will differ. Here, you’ll identify major stakeholders, their motivation (why they care), what support level they need (skeptical, neutral, enthusiastic), your engagement strategy (inform, convince, collaborate), their information needs, their engagement strategy, and their preferred communication channels.&quot;&lt;/p&gt; 
&lt;p&gt;Your stakeholders need to know what the problem is and why they should care. Don’t assume everyone sees the DevEx problems faced by your organization as clearly as you do. People come to the table with diverse backgrounds, shaping their views on what’s good, bad, or even possible in your systems. Some stakeholders may also have preconceived solutions—for instance, leadership might assume that adopting AI tools will automatically solve developer productivity challenges, without understanding the limitations of AI or the specific friction points that need addressing first.&lt;/p&gt; 
&lt;p&gt;Use the EMI framework for stakeholder communications. When crafting DevEx communications, apply the EMI framework to ensure messages resonate with each stakeholder group:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;E = Educate: Address knowledge gaps specific to their role and perspective.&lt;/li&gt; 
 &lt;li&gt;M = Motivate: Connect DevEx improvements to their priorities and pain points.&lt;/li&gt; 
 &lt;li&gt;I = Inform: Provide actionable details relevant to their involvement.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;Think of your DevEx initiative like a product—and “sell” it to your stakeholders. When communicating about your DevEx improvement initiative, adopt a product mindset to make your message more compelling. This approach helps you:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt; &lt;p&gt;Focus on solving specific problems rather than just implementing technology.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Clearly articulate value in terms stakeholders understand.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Create a coherent narrative about your initiative’s purpose and benefits.&lt;/p&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;For “investors” (leaders who fund your work), you’ll need to be able to briefly outline the business case, competitive landscape, and expected returns. For “customers” (developers and engineering managers), you’ll need to emphasize how your solution addresses their specific pain points. This product-based framing transforms abstract concepts like “improving developer experience” into concrete solutions that stakeholders can easily understand and support. For a more detailed approach to treating your DevEx tooling and automation ecosystem as a product, see the Third Practice: Make Technology Sustainable and Effective.&lt;/p&gt; 
&lt;h3&gt;Chapter 29 - Effective Messaging Takes Customization and Repetition&lt;/h3&gt; 
&lt;p&gt;&lt;em&gt;Psych 101.&lt;/em&gt;&lt;/p&gt; 
&lt;p&gt;Tell people what’s going on—and say it more than once.&lt;/p&gt; 
&lt;p&gt;Give your DevEx initiative an identity.&lt;/p&gt; 
&lt;p&gt;You’ll want more materials to help others confidently spread the word without always needing you.&lt;/p&gt; 
&lt;p&gt;Build capability, not just awareness. &quot;Effective DevEx communication goes beyond informing people—it builds their capability to understand, engage with, and champion your initiatives. Design your materials to move stakeholders through a three-stage progression:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Understand. They grasp the big picture, value, why DevEx matters, and core terminology.&lt;/li&gt; 
 &lt;li&gt;Try. They use what they’ve learned to engage with the ideas and actively look for ways to support and enable your work.&lt;/li&gt; 
 &lt;li&gt;Activate. They mentor others, build capabilities in their teams, and provide recommendations for sustaining and improving DevEx initiatives.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;STEP 6 Drive Change at (Your) Scale&lt;/h2&gt; 
&lt;h3&gt;Chapter 30 - Adapt Your Approach to Your Scope&lt;/h3&gt; 
&lt;h3&gt;Chapter 31 - Drive Change With Global Scope of Control&lt;/h3&gt; 
&lt;h3&gt;Chapter 32 - Drive Change With Local Scope of Control&lt;/h3&gt; 
&lt;h3&gt;Chapter 33 - Drive Change With Middle Ground Scope of Control&lt;/h3&gt; 
&lt;h2&gt;STEP 7 Evaluate Your Progress and Show Value&lt;/h2&gt; 
&lt;h3&gt;Chapter 34 - Analyze Your Data&lt;/h3&gt; 
&lt;h3&gt;Chapter 35 - Prepare to Communicate Your Results&lt;/h3&gt; 
&lt;h3&gt;Chapter 36 - Share Progress&lt;/h3&gt; 
&lt;h3&gt;Chapter 37 - Navigate Conflicting Metrics&lt;/h3&gt; 
&lt;h3&gt;Chapter 38 - Learn and Improve&lt;/h3&gt; 
&lt;h3&gt;Chapter 39 - Evaluation Is Just One Step in a Virtuous Cycle&lt;/h3&gt; 
&lt;h1&gt;PART V Evolving and Sustaining DevEx&lt;/h1&gt; 
&lt;h2&gt;THE FIRST PRACTICE Resource Your DevEx Initiative&lt;/h2&gt; 
&lt;h3&gt;Chapter 40 - Bootstrap Your Early Efforts&lt;/h3&gt; 
&lt;h3&gt;Chapter 41 - Build a Dedicated Function&lt;/h3&gt; 
&lt;h3&gt;Chapter 42 - Developing Talent for DevEx Roles&lt;/h3&gt; 
&lt;h3&gt;Chapter 43 - Make Developer Experience Everyone’s Job&lt;/h3&gt; 
&lt;h3&gt;Chapter 44 - Secure Budget at Different Organizational Stages&lt;/h3&gt; 
&lt;h3&gt;Chapter 45 - Making DevEx Stick&lt;/h3&gt; 
&lt;h2&gt;THE SECOND PRACTICE Create Structures to Support Change&lt;/h2&gt; 
&lt;h3&gt;Chapter 46 - A Framework For DevEx Change&lt;/h3&gt; 
&lt;h3&gt;Chapter 47 - Support Teams Through Change&lt;/h3&gt; 
&lt;h3&gt;Chapter 48 - Guide Organizations Through Change&lt;/h3&gt; 
&lt;h3&gt;Chapter 49 - Support Yourself Through Challenging Work&lt;/h3&gt; 
&lt;h2&gt;THE THIRD PRACTICE Make Technology Sustainable and Effective&lt;/h2&gt; 
&lt;h3&gt;Chapter 50 - Adopt a Product Mindset&lt;/h3&gt; 
&lt;h3&gt;Chapter 51 - Use Product Management Principles to Build Better Solutions&lt;/h3&gt; 
&lt;h3&gt;Chapter 52 - Use Tooling Standardization to Drive Efficiency&lt;/h3&gt; 
&lt;h3&gt;Chapter 53 - Deal with Technical Debt in DevEx Initiatives&lt;/h3&gt; 
&lt;h3&gt;Chapter 54 - Bring It All Together: The Sustainable Technology Mindset&lt;/h3&gt; 
&lt;h2&gt;THE FOURTH PRACTICE Design Metrics That Evolve and Amplify Impact&lt;/h2&gt; 
&lt;h3&gt;Chapter 55 - Design Metrics for Your Stakeholders&lt;/h3&gt; 
&lt;h3&gt;Chapter 56 - Use Metrics to Solve Your Stakeholders’ Problems&lt;/h3&gt; 
&lt;h3&gt;Chapter 57 - Fast Is Relative to Your Competition&lt;/h3&gt; 
&lt;h3&gt;Chapter 58 - Start Simple and Scale Smartly&lt;/h3&gt; 
&lt;h3&gt;Chapter 59 - How AI Changes (and Doesn’t Change) the Metrics You Need&lt;/h3&gt; 
&lt;h3&gt;Chapter 60 - Maintain Your Metrics Like Any Product&lt;/h3&gt; 
&lt;h1&gt;Final Thoughts&lt;/h1&gt; 
&lt;h3&gt;Chapter 61 - What Are You Waiting For?&lt;/h3&gt;
	</description>
    </item>
    <item>
      <title>High Scalability (Website) notes</title>
      <link>https://tedneward.github.io/Research/reading/development/high-scalability/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">reading/development/high-scalability/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;http://highscalability.com&quot;&gt;Blog&lt;/a&gt;&lt;/p&gt; 
&lt;h3&gt;&lt;a href=&quot;http://highscalability.com/blog/2015/11/9/a-360-degree-view-of-the-entire-netflix-stack.html&quot;&gt;A 360 Degree View Of The Entire Netflix Stack&lt;/a&gt;&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;Netflix infrastructure and transcoding is on EC2 with master copies of digital films from movie studios being stored on Amazon S3.&lt;/li&gt; 
 &lt;li&gt;Open-source software on the backend includes Java, MySQL, Gluster, Apache Tomcat, Hive, Chukwa, Cassandra, and Hadoop.&lt;/li&gt; 
 &lt;li&gt;The Netflix Open Connect CDN is provided for larger ISPs that have over 100,000 subscribers. It is a low-power, high-storage density appliance caches Netflix content within the ISPs’ data centers to reduce internet transit costs.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;&lt;a href=&quot;http://highscalability.com/blog/2015/11/2/how-shopify-scales-to-handle-flash-sales-from-kanye-west-and.html&quot;&gt;How Shopify Scales To Handle Flash Sales From Kanye West And The Superbowl&lt;/a&gt;&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;Handles about 300 million unique visitors a month, but biggest challenge is from &quot;flash sales&quot;.&lt;/li&gt; 
 &lt;li&gt;Requests received by Nginx and forwarded to a cluster of servers running Docker with the Rails app.&lt;/li&gt; 
 &lt;li&gt;Data tier includes Memcached, Redis, ElasticSearch, MySQL, Kafka, and Zookeeper.&lt;/li&gt; 
 &lt;li&gt;Performed load testing to populate a &quot;Resiliency Matrix,&quot; which specifies happens to systems when a service (e.g. MySQL, Redis, etc.) goes down.&lt;/li&gt; 
 &lt;li&gt;Scaling databases is hard, especially sharding. Try to cache a lot before you have to do it. But shards to help isolate incidents.&lt;/li&gt; 
 &lt;li&gt;Most shortcomings from resilience testing have been fixed with database scaling and automatic failovers.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;&lt;a href=&quot;http://highscalability.com/blog/2015/7/22/architecting-backend-for-a-social-product.html&quot;&gt;Architecting Backend For A Social Product&lt;/a&gt;&lt;/h3&gt; 
&lt;h4&gt;Data Storage&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;Identify which data is the most frequently queried, and which data is not so frequently required (e.g. can be archived for analysis).&lt;/li&gt; 
 &lt;li&gt;Data queried at a high frequency should be in a place where it is always available, faster to read and write, and horizontally scalable.&lt;/li&gt; 
 &lt;li&gt;Can represent connected or relational data using a graph database like Neo4j, FlockDB, AllegroGraph and InfiniteGraph.&lt;/li&gt; 
 &lt;li&gt;To store data with availability and scalability, consider S3, Google Cloud Storage, or Rackspace Cloud Files. But metadata indexing is a separate concern.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Session Data&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;Can store this in a key-value store like Redis or a document-based storage solution like MongoDB.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Indexing&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;To build an index, can write a simple system at point of content ingestion what creates an inverted index. Can graduate to Apache Storm.&lt;/li&gt; 
 &lt;li&gt;The indexing system itself could be Solr or ElasticSearch, both of which use Lucene.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Queuing &amp;amp; Push Notifications&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;Events with high fanout can be processed using a queue such as ActiveMQ.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Caching Strategy&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;The server-side application cache should store data in a format that is ready to render and requires no messaging or further action. This may require denormalization when content is ingested.&lt;/li&gt; 
 &lt;li&gt;Redis can be treated as an in-memory application cache with sharding, leader-follower node configuration, and is fast for incremental operations to collections.&lt;/li&gt; 
 &lt;li&gt;We can cache at the reverse proxy level, such as on Nginx. This requires setting HTTP response headers correctly.&lt;/li&gt; 
 &lt;li&gt;We should cache resources aggressively in the app or in the browser, such as by setting the proper HTTP caching headers, or persisting data in SQLite.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Transport Protocols&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;Consider using HTTP/2 or SPDY over HTTP/1.1.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Components&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;The load balancer determines which proxy server the request should be forwarded to based on a decided strategy.&lt;/li&gt; 
 &lt;li&gt;The proxy server handles all incoming requests. It is an SSL termination point, and will cache HTTP responses based on the defined policy.&lt;/li&gt; 
 &lt;li&gt;The event processor is responsilble for any events with a fan-out, such as notifications.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;&lt;a href=&quot;http://highscalability.com/blog/2015/3/9/applovin-marketing-to-mobile-consumers-worldwide-by-processi.html&quot;&gt;AppLovin: Marketing To Mobile Consumers Worldwide By Processing 30 Billion Requests A Day&lt;/a&gt;&lt;/h3&gt; 
&lt;h4&gt;Technology Stack&lt;/h4&gt; 
&lt;h5&gt;Data Storage&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;MySQL for ad data.&lt;/li&gt; 
 &lt;li&gt;Spark for offline processing and deep data analysis.&lt;/li&gt; 
 &lt;li&gt;Redis for basic caching.&lt;/li&gt; 
 &lt;li&gt;Thrift for all data storage and transfers.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;Core App And Services&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;Jenkins for continuous integration and deployment.&lt;/li&gt; 
 &lt;li&gt;Zookeeper for distributed locking.&lt;/li&gt; 
 &lt;li&gt;HAProxy for high availability.&lt;/li&gt; 
 &lt;li&gt;Checkstyle and PMD for static code analysis.&lt;/li&gt; 
 &lt;li&gt;Syslog for DC-centralized log server.&lt;/li&gt; 
 &lt;li&gt;Hibernate for transaction-based services.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;Servers And Provisioning&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;Chef for configuring servers.&lt;/li&gt; 
 &lt;li&gt;Load balancing is a combination of software like HAProxy and hardware.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Monitoring Stack&lt;/h4&gt; 
&lt;h5&gt;Server Monitoring&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;Graphite as data format.&lt;/li&gt; 
 &lt;li&gt;PagerDuty for issue escalation.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Architecture Overview&lt;/h4&gt; 
&lt;h5&gt;General Considerations&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;Store everything in RAM. If it does not fit, save it to SSD.&lt;/li&gt; 
 &lt;li&gt;Automate everything.&lt;/li&gt; 
 &lt;li&gt;Zero-copy message passing.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;Message Processing&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;Sending a message means writing to disk.&lt;/li&gt; 
 &lt;li&gt;Message dispatching system provides isolation and extensibility of the system.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;Ad Serving&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;Nginx is really fast.&lt;/li&gt; 
 &lt;li&gt;jemalloc gave a 30% speed improvement.&lt;/li&gt; 
 &lt;li&gt;Torrents propagate serving data across all servers, yielding 83% network load drop on originating server.&lt;/li&gt; 
 &lt;li&gt;mmap is used to share ad serving data across nginx processes.&lt;/li&gt; 
 &lt;li&gt;XXHash is the fastest hash function with a low collision rate. 75x faster than SHA-1.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Data Warehouse&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;Aggregation is key to allow fast reports on large amounts of data.&lt;/li&gt; 
 &lt;li&gt;7 days of raw logs is usually enough for debug.&lt;/li&gt; 
 &lt;li&gt;Backup in S3 for catastrophic failures.&lt;/li&gt; 
 &lt;li&gt;Raw data is stored in a Spark cluster.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;&lt;a href=&quot;http://highscalability.com/blog/2014/11/10/nifty-architecture-tricks-from-wix-building-a-publishing-pla.html&quot;&gt;Nifty Architecture Tricks From Wix - Building A Publishing Platform At Scale&lt;/a&gt;&lt;/h3&gt; 
&lt;p&gt;Platform on which over 54 million web sites have been created, most of which receive under 100 page views per day. So traditional caching does not apply.&lt;/p&gt; 
&lt;p&gt;Novel consequences:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Does not use transactions. all data is immutable and they use a simple eventual consistency strategy.&lt;/li&gt; 
 &lt;li&gt;Does not cache. Instead, they pay great attention to optimizing the rendering path so that every page displays in under 100ms.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Guidelines For How To Build Services&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;Services are stateless. To horizontally scale, just add more servers.&lt;/li&gt; 
 &lt;li&gt;With the exception of billing/financial transactions, all other services do not use transactions.&lt;/li&gt; 
 &lt;li&gt;When designing a new service caching is not part of the architecture. If a service performs poorly, first optimize the code before emplying caching.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Editor Segment&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;MySQL is a great key-value store. Key is based on a hash function of the file so the key is immutable.&lt;/li&gt; 
 &lt;li&gt;An &quot;active database&quot; contains the 6% of sites that are still being updated. It is really fast and relatively small in terms of storage.&lt;/li&gt; 
 &lt;li&gt;An &quot;archive database&quot; contains the remaining data that is infrequently accessed. It is relatively slow, but contains huge amounts of storage.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;High Availability For Editor Segment&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;All data is immutable. Revisions are stored for everything. If a corruption can’t be fixed, revert to version where the data was fine.&lt;/li&gt; 
 &lt;li&gt;To protect against unavailability, data s replicated across different geographical locations and multiple cloud services.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Modeling Data With No Database Transactions&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;JSON files are inserted into the database, and finally a manifest is inserted with the identifiers of all resources that were just saved.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Public Segment&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;Public SLA is that response time is &amp;lt; 100ms at peak traffic. Web sites must be fast with no caching.&lt;/li&gt; 
 &lt;li&gt;Data is stored in a denormalized format, optimized for read by primary key. Everything that is needed is returned in a single request.&lt;/li&gt; 
 &lt;li&gt;The data returned is in JSON format. Rendering is offloaded to the client.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Lessons Learned&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;Identify your critical path and concerns.&lt;/li&gt; 
 &lt;li&gt;De-normalize and precalculate data, and thereby reduce network chattter, for performance.&lt;/li&gt; 
 &lt;li&gt;Take advantage of client’s CPU power.&lt;/li&gt; 
 &lt;li&gt;Go immutable. Immutability has far reaching consequences for an architecture, and is an elegant solution to a lot of problems.&lt;/li&gt; 
 &lt;li&gt;What really locks you down is data. Moving lots of data to a different cloud is really hard.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;&lt;a href=&quot;http://highscalability.com/blog/2014/7/21/stackoverflow-update-560m-pageviews-a-month-25-servers-and-i.html&quot;&gt;StackOverflow Update: 560M Pageviews A Month, 25 Servers, And It&apos;s All About Performance&lt;/a&gt;&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;25 servers for everything. That’s high availability, load balancing, caching, databases, searching, and utility functions.&lt;/li&gt; 
 &lt;li&gt;Still uses Microsoft products.&lt;/li&gt; 
 &lt;li&gt;Uses a scale-up strategy. Not using any cloud service, where their SQL Servers loaded with 384 GB of RAM and 2TB of SSD would cost a fortune.&lt;/li&gt; 
 &lt;li&gt;Jeff Atwood said &quot;Hardware is cheap, programmers are expensive&quot; and this apparently still holds true.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Stats&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;Peak is 2600-3000 requests/sec on most weekdays.&lt;/li&gt; 
 &lt;li&gt;Each web server has 2x 320GB SSDs in a RAID 1, and each ElasticSearch box has 300 GB also using SSDs.&lt;/li&gt; 
 &lt;li&gt;Has a 40:60 read-write ratio.&lt;/li&gt; 
 &lt;li&gt;11 web servers using IIS, 2 load balancers using HAProxy, 4 active database nodes using MS SQL, 3 application servers implementing the tag engine, 3 machines running ElasticSearch, 2 machines running Redis for distributed cache and messaging.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Platform&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;ElasticSearch, Redis, HAProxy, and MS SQL.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Servers&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;The database server is at 10% usage except during backups. The database servers have 384GB of RAM and the web servers are at 10%-15% CPU usage.&lt;/li&gt; 
 &lt;li&gt;Scale-up is still working. Other scale-out sites with a similar numbers tend to run on between 100 and 300 servers.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;SSDs&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;ElasticSearch performs much better on SSDs, given SO writes/re-indexes very frequently.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;High Availability&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;The main datacenter is in New York and the backup datacenter is in Oregon.&lt;/li&gt; 
 &lt;li&gt;Not everything is replicated between data centers (very temporary cache data that&apos;s not needed to eat bandwidth by syncing, etc.), but the important resources are.&lt;/li&gt; 
 &lt;li&gt;Nginx was used for SSL, but a transition has been made to using HAProxy to terminate SSL.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Databasing&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;Each site has its own database, and the schema for each is the same. This is effectively a form of partitioning and horizontal scaling.&lt;/li&gt; 
 &lt;li&gt;All the schema changes are applied to all site databases at the same time.&lt;/li&gt; 
 &lt;li&gt;Partitioning is not required. Indexing takes care of everything and the data just is not large enough.&lt;/li&gt; 
 &lt;li&gt;Scores are denormalized, so querying is often needed.&lt;/li&gt; 
 &lt;li&gt;The Tag Engine is entirely self-contained, and runs on three servers for redundancy. If all of them fail, the local web servers will load the tag engine in memory and keep on going.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Coding&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;Compilation is very fast.&lt;/li&gt; 
 &lt;li&gt;New features are hidden via feature switches.&lt;/li&gt; 
 &lt;li&gt;Heavy usage of static classes and methods, for simplicity and better performance.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Caching&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;Network level cache is caching in the browser, CDN, and proxies.&lt;/li&gt; 
 &lt;li&gt;Redis works as a distributed in-memory key-value store for all servers that serve the same site.&lt;/li&gt; 
 &lt;li&gt;SQL Server Cache caches the entire database in memory.&lt;/li&gt; 
 &lt;li&gt;SSD is used as a cache, and is usually only hit when the SQL server cache is warming up.&lt;/li&gt; 
 &lt;li&gt;TODO&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Executables linking and loading reading</title>
      <link>https://tedneward.github.io/Research/reading/development/linking-loading/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">reading/development/linking-loading/index.html</guid>
      	<description>
	&lt;ul&gt; 
 &lt;li&gt;Advanced C and C++ Compiling 
  &lt;ul&gt; 
   &lt;li&gt;2014; Milan Stevanovic​&lt;/li&gt; 
   &lt;li&gt;&quot;Engineering guide to C/C++ compiling, linking, and binary files structure&quot;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://www.apress.com/9781430266679&quot;&gt;http://www.apress.com/9781430266679&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://link.springer.com/book/10.1007%2F978-1-4302-6668-6&quot;&gt;http://link.springer.com/book/10.1007%2F978-1-4302-6668-6&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/apress/adv-c-cpp-compiling&quot;&gt;https://github.com/apress/adv-c-cpp-compiling&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Linkers and Loaders 
  &lt;ul&gt; 
   &lt;li&gt;1999; John R. Levine&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.iecc.com/linker/&quot;&gt;https://www.iecc.com/linker/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Assemblers and Loaders 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.davidsalomon.name/&quot;&gt;https://www.davidsalomon.name/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Written during 1985--1992, the book developed from class notes on computer organization. It includes numerous exercises with answers provided, and review questions following each chapter. The book is bound as a paperback with a colorful cover.&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.davidsalomon.name/assem.advertis/AssemAd.html&quot;&gt;https://www.davidsalomon.name/assem.advertis/AssemAd.html&lt;/a&gt; (&lt;a href=&quot;http://www.davidsalomon.name/assem.advertis/asl.pdf&quot;&gt;PDF&lt;/a&gt;) (&lt;a href=&quot;./asl.pdf&quot;&gt;Local&lt;/a&gt;)&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Beginner&apos;s Guide to Linkers&lt;/p&gt; 
  &lt;ul&gt; 
   &lt;li&gt;2010; David Drysdale&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.lurklurk.org/linkers/linkers.html&quot;&gt;https://www.lurklurk.org/linkers/linkers.html&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Linkers and Loaders 
  &lt;ul&gt; 
   &lt;li&gt;ACM Computing Surveys, Volume 4, Number 3, September 1972&lt;/li&gt; 
   &lt;li&gt;Leon Presser, John R. White&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://www-inst.eecs.berkeley.edu/~cs162/sp06/hand-outs/p149-presser-linker-loader.pdf&quot;&gt;http://www-inst.eecs.berkeley.edu/~cs162/sp06/hand-outs/p149-presser-linker-loader.pdf&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Binary File Descriptor library (BFD) 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://sourceware.org/binutils/docs/bfd/&quot;&gt;https://sourceware.org/binutils/docs/bfd/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://publicclu2.blogspot.com/2013/05/binary-file-descriptor-library-bfd.html&quot;&gt;https://publicclu2.blogspot.com/2013/05/binary-file-descriptor-library-bfd.html&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Concurrent Linking with the GNU Gold Linker 
  &lt;ul&gt; 
   &lt;li&gt;2013 Thesis; Sander Mathijs van Veen&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://smvv.io/gold.pdf&quot;&gt;https://smvv.io/gold.pdf&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Oracle Solaris 11.1 Linkers and Libraries Guide 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://docs.oracle.com/cd/E26502_01/html/E26507/&quot;&gt;https://docs.oracle.com/cd/E26502_01/html/E26507/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;The Missing Link: Explaining ELF Static Linking, Semantically 
  &lt;ul&gt; 
   &lt;li&gt;OOPSLA 2016&lt;/li&gt; 
   &lt;li&gt;Stephen Kell, Dominic P. Mulligan, Peter Sewell&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://www.cl.cam.ac.uk/~pes20/rems/papers/oopsla-elf-linking-2016.pdf&quot;&gt;http://www.cl.cam.ac.uk/~pes20/rems/papers/oopsla-elf-linking-2016.pdf&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;The Sad State of Symbol Aliases 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;http://blog.omega-prime.co.uk/2011/07/06/the-sad-state-of-symbol-aliases/&quot;&gt;http://blog.omega-prime.co.uk/2011/07/06/the-sad-state-of-symbol-aliases/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;The Theory, History and Future of System Linkers 
  &lt;ul&gt; 
   &lt;li&gt;HelloGCC Workshop 2013; Luba Tang&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/hellogcc/HelloGCC2013/blob/master/linker_overall.pdf&quot;&gt;https://github.com/hellogcc/HelloGCC2013/blob/master/linker_overall.pdf&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Readings: Blogs&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;Eli Bendersky - Linkers and loaders 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://eli.thegreenplace.net/tag/linkers-and-loaders&quot;&gt;https://eli.thegreenplace.net/tag/linkers-and-loaders&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Load-time relocation of shared libraries 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://eli.thegreenplace.net/2011/08/25/load-time-relocation-of-shared-libraries&quot;&gt;https://eli.thegreenplace.net/2011/08/25/load-time-relocation-of-shared-libraries&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;Position Independent Code (PIC) in shared libraries 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://eli.thegreenplace.net/2011/11/03/position-independent-code-pic-in-shared-libraries&quot;&gt;https://eli.thegreenplace.net/2011/11/03/position-independent-code-pic-in-shared-libraries&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;Position Independent Code (PIC) in shared libraries on x64 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://eli.thegreenplace.net/2011/11/11/position-independent-code-pic-in-shared-libraries-on-x64&quot;&gt;https://eli.thegreenplace.net/2011/11/11/position-independent-code-pic-in-shared-libraries-on-x64&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;How statically linked programs run on Linux 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://eli.thegreenplace.net/2012/08/13/how-statically-linked-programs-run-on-linux&quot;&gt;https://eli.thegreenplace.net/2012/08/13/how-statically-linked-programs-run-on-linux&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;Library order in static linking 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://eli.thegreenplace.net/2013/07/09/library-order-in-static-linking&quot;&gt;https://eli.thegreenplace.net/2013/07/09/library-order-in-static-linking&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Fun with weak symbols 
  &lt;ul&gt; 
   &lt;li&gt;2012; Mike Hommey&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://glandium.org/blog/?p=2388&quot;&gt;https://glandium.org/blog/?p=2388&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Ian Lance Taylor 
  &lt;ul&gt; 
   &lt;li&gt;20 part linker essay by Ian Lance Taylor 
    &lt;ul&gt; 
     &lt;li&gt;Notes: Day 40: Linkers are amazing. 
      &lt;ul&gt; 
       &lt;li&gt;2013; Julia Evans&lt;/li&gt; 
       &lt;li&gt;&lt;a href=&quot;http://jvns.ca/blog/2013/12/10/day-40-learning-about-linkers/&quot;&gt;http://jvns.ca/blog/2013/12/10/day-40-learning-about-linkers/&lt;/a&gt;&lt;/li&gt; 
      &lt;/ul&gt; &lt;/li&gt; 
     &lt;li&gt;TOC: &lt;a href=&quot;https://checkoway.net/musings/linkers/&quot;&gt;https://checkoway.net/musings/linkers/&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;TOC: &lt;a href=&quot;https://lwn.net/Articles/276782/&quot;&gt;https://lwn.net/Articles/276782/&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;1. Introduction, personal history, first half of what&apos;s-a-linker - &lt;a href=&quot;http://www.airs.com/blog/archives/38&quot;&gt;http://www.airs.com/blog/archives/38&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;2. What&apos;s-a-linker: Dynamic linking, linker data types, linker operation - &lt;a href=&quot;http://www.airs.com/blog/archives/39&quot;&gt;http://www.airs.com/blog/archives/39&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;3. Address spaces, Object file formats - &lt;a href=&quot;http://www.airs.com/blog/archives/40&quot;&gt;http://www.airs.com/blog/archives/40&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;4. Shared Libraries - &lt;a href=&quot;http://www.airs.com/blog/archives/41&quot;&gt;http://www.airs.com/blog/archives/41&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;5. More Shared Libraries -- specifically, linker implementation; ELF Symbols - &lt;a href=&quot;http://www.airs.com/blog/archives/42&quot;&gt;http://www.airs.com/blog/archives/42&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;6. Relocations, Position Dependent Shared Libraries - &lt;a href=&quot;http://www.airs.com/blog/archives/43&quot;&gt;http://www.airs.com/blog/archives/43&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;7. Thread Local Storage (TLS) optimization - &lt;a href=&quot;http://www.airs.com/blog/archives/44&quot;&gt;http://www.airs.com/blog/archives/44&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;8. ELF Segments and Sections - &lt;a href=&quot;http://www.airs.com/blog/archives/45&quot;&gt;http://www.airs.com/blog/archives/45&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;9. Symbol Versions, Relaxation optimization - &lt;a href=&quot;http://www.airs.com/blog/archives/46&quot;&gt;http://www.airs.com/blog/archives/46&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;10. Parallel linking - &lt;a href=&quot;http://www.airs.com/blog/archives/47&quot;&gt;http://www.airs.com/blog/archives/47&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;11. Archive format - &lt;a href=&quot;http://www.airs.com/blog/archives/48&quot;&gt;http://www.airs.com/blog/archives/48&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;12. Symbol resolution - &lt;a href=&quot;http://www.airs.com/blog/archives/49&quot;&gt;http://www.airs.com/blog/archives/49&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;13. Symbol resolution from the user&apos;s point of view; Static Linking vs. Dynamic Linking - &lt;a href=&quot;http://www.airs.com/blog/archives/50&quot;&gt;http://www.airs.com/blog/archives/50&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;14. Link time optimization, aka Whole Program optimization; Initialization Code - &lt;a href=&quot;http://www.airs.com/blog/archives/51&quot;&gt;http://www.airs.com/blog/archives/51&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;15. COMDAT sections - &lt;a href=&quot;http://www.airs.com/blog/archives/52&quot;&gt;http://www.airs.com/blog/archives/52&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;16. C++ Template Instantiation, Exception Frames - &lt;a href=&quot;http://www.airs.com/blog/archives/53&quot;&gt;http://www.airs.com/blog/archives/53&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;17. Warning Symbols - &lt;a href=&quot;http://www.airs.com/blog/archives/54&quot;&gt;http://www.airs.com/blog/archives/54&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;18. Incremental Linking - &lt;a href=&quot;http://www.airs.com/blog/archives/55&quot;&gt;http://www.airs.com/blog/archives/55&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;19. &lt;code&gt;__start&lt;/code&gt; and &lt;code&gt;__stop&lt;/code&gt; Symbols, Byte Swapping - &lt;a href=&quot;http://www.airs.com/blog/archives/56&quot;&gt;http://www.airs.com/blog/archives/56&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;20. Last post; Update on gold&apos;s status - &lt;a href=&quot;http://www.airs.com/blog/archives/57&quot;&gt;http://www.airs.com/blog/archives/57&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;Protected Symbols - &lt;a href=&quot;https://www.airs.com/blog/archives/307&quot;&gt;https://www.airs.com/blog/archives/307&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;gold 
    &lt;ul&gt; 
     &lt;li&gt;Gold Workqueues - &lt;a href=&quot;https://www.airs.com/blog/archives/78&quot;&gt;https://www.airs.com/blog/archives/78&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;STT_GNU_IFUNC - &lt;a href=&quot;https://www.airs.com/blog/archives/403&quot;&gt;https://www.airs.com/blog/archives/403&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;A New ELF Linker 
      &lt;ul&gt; 
       &lt;li&gt;GCC Summit 2008&lt;/li&gt; 
       &lt;li&gt;Proceedings of the GCC Developers&apos; Summit (2008)&lt;/li&gt; 
       &lt;li&gt;&lt;a href=&quot;https://research.google.com/pubs/pub34417.html&quot;&gt;https://research.google.com/pubs/pub34417.html&lt;/a&gt;&lt;/li&gt; 
       &lt;li&gt;&lt;a href=&quot;https://gcc.gnu.org/wiki/HomePage?action=AttachFile&amp;amp;do=view&amp;amp;target=gcc-2008-proceedings.pdf&quot;&gt;https://gcc.gnu.org/wiki/HomePage?action=AttachFile&amp;amp;do=view&amp;amp;target=gcc-2008-proceedings.pdf&lt;/a&gt;&lt;/li&gt; 
       &lt;li&gt;&lt;a href=&quot;http://airs.com/ian/gold-slides.pdf&quot;&gt;http://airs.com/ian/gold-slides.pdf&lt;/a&gt;&lt;/li&gt; 
      &lt;/ul&gt; &lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Nick Desaulniers 
  &lt;ul&gt; 
   &lt;li&gt;Part 1 – Object Files and Symbols - &lt;a href=&quot;https://nickdesaulniers.github.io/blog/2016/08/13/object-files-and-symbols/&quot;&gt;https://nickdesaulniers.github.io/blog/2016/08/13/object-files-and-symbols/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Part 2 – Static and Dynamic Libraries - &lt;a href=&quot;https://nickdesaulniers.github.io/blog/2016/11/20/static-and-dynamic-libraries/&quot;&gt;https://nickdesaulniers.github.io/blog/2016/11/20/static-and-dynamic-libraries/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Stephen Kell 
  &lt;ul&gt; 
   &lt;li&gt;Linking and loading: what&apos;s incidental? 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;http://www.cl.cam.ac.uk/~srk31/blog/research/linking-and-loading-complexity.html&quot;&gt;http://www.cl.cam.ac.uk/~srk31/blog/research/linking-and-loading-complexity.html&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;Dynamic linking and security 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;http://www.cl.cam.ac.uk/~srk31/blog/research/dynamic-linker-security.html&quot;&gt;http://www.cl.cam.ac.uk/~srk31/blog/research/dynamic-linker-security.html&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;C libraries and linking 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;http://www.cl.cam.ac.uk/~srk31/blog/research/c-libraries-compilers-and-linking.html&quot;&gt;http://www.cl.cam.ac.uk/~srk31/blog/research/c-libraries-compilers-and-linking.html&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;Link order 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;http://www.cl.cam.ac.uk/~srk31/blog/devel/link-order.html&quot;&gt;http://www.cl.cam.ac.uk/~srk31/blog/devel/link-order.html&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;Weak dynamic symbols 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;http://www.cl.cam.ac.uk/~srk31/blog/devel/weak-symbols.html&quot;&gt;http://www.cl.cam.ac.uk/~srk31/blog/devel/weak-symbols.html&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Trevor Pounds 
  &lt;ul&gt; 
   &lt;li&gt;Versioning Symbols for Shared Libraries (glibc) 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://web.archive.org/web/20150906233231/http://www.trevorpounds.com/blog/?p=33&quot;&gt;https://web.archive.org/web/20150906233231/http://www.trevorpounds.com/blog/?p=33&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;Linking to Older Versioned Symbols (glibc) 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://web.archive.org/web/20150906233154/http://www.trevorpounds.com/blog/?p=103&quot;&gt;https://web.archive.org/web/20150906233154/http://www.trevorpounds.com/blog/?p=103&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Readings: Linker Scripts&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;OSDev Wiki 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://wiki.osdev.org/Category:Linkers&quot;&gt;https://wiki.osdev.org/Category:Linkers&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Linker Scripts 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;http://wiki.osdev.org/Linker_Scripts&quot;&gt;http://wiki.osdev.org/Linker_Scripts&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;LD - Linker Scripts 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://sourceware.org/binutils/docs/ld/Scripts.html&quot;&gt;https://sourceware.org/binutils/docs/ld/Scripts.html&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Readings: LTO&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;(Ab)using LTO plugin API for system-wide shrinking of dynamic libraries 
  &lt;ul&gt; 
   &lt;li&gt;GNU Tools Cauldron 2018&lt;/li&gt; 
   &lt;li&gt;Vladislav Ivanishin&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=BNYGB7dHgkc&quot;&gt;https://www.youtube.com/watch?v=BNYGB7dHgkc&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://gcc.gnu.org/wiki/cauldron2018?action=AttachFile&amp;amp;do=view&amp;amp;target=lto-plugin-api-abuse.pdf&quot;&gt;https://gcc.gnu.org/wiki/cauldron2018?action=AttachFile&amp;amp;do=view&amp;amp;target=lto-plugin-api-abuse.pdf&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;GCC Wiki - LinkTimeOptimization 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://gcc.gnu.org/wiki/LinkTimeOptimization&quot;&gt;https://gcc.gnu.org/wiki/LinkTimeOptimization&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Honza Hubička&apos;s Blog 
  &lt;ul&gt; 
   &lt;li&gt;Linktime optimization in GCC, part 1 - brief history 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;http://hubicka.blogspot.com/2014/04/linktime-optimization-in-gcc-1-brief.html&quot;&gt;http://hubicka.blogspot.com/2014/04/linktime-optimization-in-gcc-1-brief.html&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;Linktime optimization in GCC, part 2 - Firefox 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;http://hubicka.blogspot.com/2014/04/linktime-optimization-in-gcc-2-firefox.html&quot;&gt;http://hubicka.blogspot.com/2014/04/linktime-optimization-in-gcc-2-firefox.html&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;Linktime optimization in GCC, part 3 - LibreOffice 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://hubicka.blogspot.com/2014/09/linktime-optimization-in-gcc-part-3.html&quot;&gt;https://hubicka.blogspot.com/2014/09/linktime-optimization-in-gcc-part-3.html&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;Link time and inter-procedural optimization improvements in GCC 5 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://hubicka.blogspot.com/2015/04/GCC5-IPA-LTO-news.html&quot;&gt;https://hubicka.blogspot.com/2015/04/GCC5-IPA-LTO-news.html&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;Building libreoffice with GCC 6 and LTO 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://hubicka.blogspot.com/2016/03/building-libreoffice-with-gcc-6-and-lto.html&quot;&gt;https://hubicka.blogspot.com/2016/03/building-libreoffice-with-gcc-6-and-lto.html&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;GCC 8: link time and interprocedural optimization 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://hubicka.blogspot.com/2018/06/gcc-8-link-time-and-interprocedural.html&quot;&gt;https://hubicka.blogspot.com/2018/06/gcc-8-link-time-and-interprocedural.html&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;LLVM Link Time Optimization: Design and Implementation 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://llvm.org/docs/LinkTimeOptimization.html&quot;&gt;https://llvm.org/docs/LinkTimeOptimization.html&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Optimizing Large Applications 
  &lt;ul&gt; 
   &lt;li&gt;2014 Master&apos;s Thesis; Martin Liška&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://arxiv.org/abs/1403.6997&quot;&gt;https://arxiv.org/abs/1403.6997&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Optimizing real world applications with GCC Link Time Optimization 
  &lt;ul&gt; 
   &lt;li&gt;2010 GCC Developers&apos; Summit; T. Glek, J. Hubicka&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://arxiv.org/abs/1010.2196&quot;&gt;https://arxiv.org/abs/1010.2196&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;ThinLTO 
  &lt;ul&gt; 
   &lt;li&gt;ThinLTO: Scalable and Incremental LTO 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;http://blog.llvm.org/2016/06/thinlto-scalable-and-incremental-lto.html&quot;&gt;http://blog.llvm.org/2016/06/thinlto-scalable-and-incremental-lto.html&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;ThinLTO: Scalable and Incremental Link-Time Optimization 
    &lt;ul&gt; 
     &lt;li&gt;CppCon 2017; Teresa Johnson&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=p9nH2vZ2mNo&quot;&gt;https://www.youtube.com/watch?v=p9nH2vZ2mNo&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;ThinLTO: Scalable and incremental LTO 
    &lt;ul&gt; 
     &lt;li&gt;CGO 2017&lt;/li&gt; 
     &lt;li&gt;Teresa Johnson, Mehdi Amini, and Xinliang David Li&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://research.google/pubs/pub47584/&quot;&gt;https://research.google/pubs/pub47584/&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Readings: OS&lt;/h2&gt; 
&lt;h3&gt;macOS&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;Debugging Dyld 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://lowlevelbits.org/debugging-dyld/&quot;&gt;https://lowlevelbits.org/debugging-dyld/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Linux&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;Linker limitations on 32-bit architectures 
  &lt;ul&gt; 
   &lt;li&gt;2019; Alexander E. Patrakov&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://lwn.net/Articles/797303/&quot;&gt;https://lwn.net/Articles/797303/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Linux EDR Evasion With Meterpreter and LD_PRELOAD 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://forensicitguy.github.io/posts/linux-edr-evasion-with-ld-preload/&quot;&gt;https://forensicitguy.github.io/posts/linux-edr-evasion-with-ld-preload/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Linux Internals 
  &lt;ul&gt; 
   &lt;li&gt;Dynamic Linking Wizardry 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://0x00sec.org/t/linux-internals-dynamic-linking-wizardry/1082&quot;&gt;https://0x00sec.org/t/linux-internals-dynamic-linking-wizardry/1082&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;The Art Of Symbol Resolution 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://0x00sec.org/t/linux-internals-the-art-of-symbol-resolution/1488&quot;&gt;https://0x00sec.org/t/linux-internals-the-art-of-symbol-resolution/1488&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Solaris&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;Surfing With The Linker Aliens: Solaris Linking &amp;amp; ELF Blogs 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;http://www.linker-aliens.org/&quot;&gt;http://www.linker-aliens.org/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;The Link-editors - a source tour 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;http://www.linker-aliens.org/blogs/rie/entry/the_link_editors_a_source/&quot;&gt;http://www.linker-aliens.org/blogs/rie/entry/the_link_editors_a_source/&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;What Are &quot;Tentative&quot; Symbols? 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;http://www.linker-aliens.org/blogs/ali/entry/what_are_tentative_symbols/&quot;&gt;http://www.linker-aliens.org/blogs/ali/entry/what_are_tentative_symbols/&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Windows&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;Raymond Chen - The Old New Thing 
  &lt;ul&gt; 
   &lt;li&gt;Understanding the classical model for linking 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://blogs.msdn.microsoft.com/oldnewthing/tag/linker&quot;&gt;https://blogs.msdn.microsoft.com/oldnewthing/tag/linker&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;Groundwork: The algorithm 
      &lt;ul&gt; 
       &lt;li&gt;&lt;a href=&quot;https://devblogs.microsoft.com/oldnewthing/20130107-00/?p=5633&quot;&gt;https://devblogs.microsoft.com/oldnewthing/20130107-00/?p=5633&lt;/a&gt;&lt;/li&gt; 
      &lt;/ul&gt; &lt;/li&gt; 
     &lt;li&gt;Taking symbols along for the ride 
      &lt;ul&gt; 
       &lt;li&gt;&lt;a href=&quot;https://devblogs.microsoft.com/oldnewthing/20130108-00/?p=5623&quot;&gt;https://devblogs.microsoft.com/oldnewthing/20130108-00/?p=5623&lt;/a&gt;&lt;/li&gt; 
      &lt;/ul&gt; &lt;/li&gt; 
     &lt;li&gt;You can override an LIB with another LIB, and a LIB with an OBJ, but you can’t override an OBJ 
      &lt;ul&gt; 
       &lt;li&gt;&lt;a href=&quot;https://devblogs.microsoft.com/oldnewthing/20130109-00/?p=5613&quot;&gt;https://devblogs.microsoft.com/oldnewthing/20130109-00/?p=5613&lt;/a&gt;&lt;/li&gt; 
      &lt;/ul&gt; &lt;/li&gt; 
     &lt;li&gt;Sometimes you don’t want a symbol to come along for a ride 
      &lt;ul&gt; 
       &lt;li&gt;&lt;a href=&quot;https://devblogs.microsoft.com/oldnewthing/20130110-00/?p=5593&quot;&gt;https://devblogs.microsoft.com/oldnewthing/20130110-00/?p=5593&lt;/a&gt;&lt;/li&gt; 
      &lt;/ul&gt; &lt;/li&gt; 
     &lt;li&gt;Understanding errors in classical linking: The delay-load catch-22 
      &lt;ul&gt; 
       &lt;li&gt;&lt;a href=&quot;https://devblogs.microsoft.com/oldnewthing/20130111-00/?p=5583&quot;&gt;https://devblogs.microsoft.com/oldnewthing/20130111-00/?p=5583&lt;/a&gt;&lt;/li&gt; 
      &lt;/ul&gt; &lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;Using linker segments and &lt;code&gt;__declspec(allocate(…))&lt;/code&gt; to arrange data in a specific order 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://blogs.msdn.microsoft.com/oldnewthing/20181107-00/?p=100155&quot;&gt;https://blogs.msdn.microsoft.com/oldnewthing/20181107-00/?p=100155&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;Gotchas when using linker sections to arrange data, part 1 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://blogs.msdn.microsoft.com/oldnewthing/20181108-00/?p=100165&quot;&gt;https://blogs.msdn.microsoft.com/oldnewthing/20181108-00/?p=100165&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;Gotchas when using linker sections to arrange data, part 2 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://blogs.msdn.microsoft.com/oldnewthing/20181109-00/?p=100175&quot;&gt;https://blogs.msdn.microsoft.com/oldnewthing/20181109-00/?p=100175&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;Why would the incremental linker insert padding between section fragments? 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://blogs.msdn.microsoft.com/oldnewthing/20190114-00/?p=100695&quot;&gt;https://blogs.msdn.microsoft.com/oldnewthing/20190114-00/?p=100695&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Readings: Relocations&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;Binary Dodo - Arun 
  &lt;ul&gt; 
   &lt;li&gt;Investigating linking with COMMON symbols in ELF 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://binarydodo.wordpress.com/2016/05/09/investigating-linking-with-common-symbols-in-elf/&quot;&gt;https://binarydodo.wordpress.com/2016/05/09/investigating-linking-with-common-symbols-in-elf/&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;Symbol binding types in ELF and their effect on linking of relocatable files 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://binarydodo.wordpress.com/2016/05/12/symbol-binding-types-in-elf-and-their-effect-on-linking-of-relocatable-files/&quot;&gt;https://binarydodo.wordpress.com/2016/05/12/symbol-binding-types-in-elf-and-their-effect-on-linking-of-relocatable-files/&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;Symbol resolution during link-editing 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://binarydodo.wordpress.com/2016/07/01/symbol-resolution-during-link-editing/&quot;&gt;https://binarydodo.wordpress.com/2016/07/01/symbol-resolution-during-link-editing/&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;ELF Binaries and Relocation Entries - Stafford Horne 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;http://stffrdhrn.github.io/hardware/embedded/openrisc/2019/11/29/relocs.html&quot;&gt;http://stffrdhrn.github.io/hardware/embedded/openrisc/2019/11/29/relocs.html&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://intezer.com/tag/elf/&quot;&gt;Executable and Linkable Format 101&lt;/a&gt; - Ignacio Sanmillan 
  &lt;ul&gt; 
   &lt;li&gt;Part 3: Relocations - &lt;a href=&quot;https://www.intezer.com/executable-and-linkable-format-101-part-3-relocations/&quot;&gt;https://www.intezer.com/executable-and-linkable-format-101-part-3-relocations/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;GOT and PLT 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://systemoverlord.com/2017/03/19/got-and-plt-for-pwning.html&quot;&gt;https://systemoverlord.com/2017/03/19/got-and-plt-for-pwning.html&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Ian Lance Taylor 
  &lt;ul&gt; 
   &lt;li&gt;Linkers 2. What&apos;s-a-linker: Dynamic linking, linker data types, linker operation 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;http://www.airs.com/blog/archives/39&quot;&gt;http://www.airs.com/blog/archives/39&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;Linkers 5. More Shared Libraries -- specifically, linker implementation; ELF Symbols 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;http://www.airs.com/blog/archives/42&quot;&gt;http://www.airs.com/blog/archives/42&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;Linkers 6. Relocations, Position Dependent Shared Libraries 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;http://www.airs.com/blog/archives/43&quot;&gt;http://www.airs.com/blog/archives/43&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;Linkers 9. Symbol Versions, Relaxation optimization 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;http://www.airs.com/blog/archives/46&quot;&gt;http://www.airs.com/blog/archives/46&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;Linker combreloc 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://www.airs.com/blog/archives/186&quot;&gt;https://www.airs.com/blog/archives/186&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;Linker relro 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://www.airs.com/blog/archives/189&quot;&gt;https://www.airs.com/blog/archives/189&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Introduction to the ELF Format - Keith Makan 
  &lt;ul&gt; 
   &lt;li&gt;Part VI(1): The Symbol Table and Relocations - &lt;a href=&quot;https://blog.k3170makan.com/2018/10/introduction-to-elf-format-part-vi.html&quot;&gt;https://blog.k3170makan.com/2018/10/introduction-to-elf-format-part-vi.html&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Part VI(2): The Symbol Table and Relocations - &lt;a href=&quot;https://blog.k3170makan.com/2018/10/introduction-to-elf-format-part-vi_18.html&quot;&gt;https://blog.k3170makan.com/2018/10/introduction-to-elf-format-part-vi_18.html&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Part VI(3): More Relocation tricks - r_addend execution - &lt;a href=&quot;https://blog.k3170makan.com/2018/10/introduction-to-elf-format-part-vi-more.html&quot;&gt;https://blog.k3170makan.com/2018/10/introduction-to-elf-format-part-vi-more.html&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Linkers and loaders - Eli Bendersky - &lt;a href=&quot;http://eli.thegreenplace.net/tag/linkers-and-loaders&quot;&gt;http://eli.thegreenplace.net/tag/linkers-and-loaders&lt;/a&gt; 
  &lt;ul&gt; 
   &lt;li&gt;Load-time relocation of shared libraries 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://eli.thegreenplace.net/2011/08/25/load-time-relocation-of-shared-libraries&quot;&gt;https://eli.thegreenplace.net/2011/08/25/load-time-relocation-of-shared-libraries&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Making our own executable packer - Amos Wenger 
  &lt;ul&gt; 
   &lt;li&gt;ELF relocations - &lt;a href=&quot;https://fasterthanli.me/blog/2020/elf-relocations/&quot;&gt;https://fasterthanli.me/blog/2020/elf-relocations/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;More ELF relocations - &lt;a href=&quot;https://fasterthanli.me/blog/2020/more-elf-relocations/&quot;&gt;https://fasterthanli.me/blog/2020/more-elf-relocations/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Moving code around - Thiago Macieira 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;http://blog.qt.io/blog/2010/12/04/moving-code-around/&quot;&gt;http://blog.qt.io/blog/2010/12/04/moving-code-around/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://blog.qt.io/blog/2010/12/05/moving-code-around-more-easily/&quot;&gt;http://blog.qt.io/blog/2010/12/05/moving-code-around-more-easily/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Oracle Solaris 11.1 Linker and Libraries Guide 
  &lt;ul&gt; 
   &lt;li&gt;Relocation Processing 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://docs.oracle.com/cd/E26502_01/html/E26507/chapter3-29.html&quot;&gt;https://docs.oracle.com/cd/E26502_01/html/E26507/chapter3-29.html&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;Relocation Sections 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://docs.oracle.com/cd/E23824_01/html/819-0690/chapter6-54839.html&quot;&gt;https://docs.oracle.com/cd/E23824_01/html/819-0690/chapter6-54839.html&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Relocations in ELF Toolchains - Palmer Dabbelt 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.sifive.com/blog/2017/08/21/all-aboard-part-2-relocations/&quot;&gt;https://www.sifive.com/blog/2017/08/21/all-aboard-part-2-relocations/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Relocations: fantastic symbols, but where to find them? - Siddhesh Poyarekar 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://siddhesh.in/posts/relocations-fantastic-symbols-but-where-to-find-them.html&quot;&gt;https://siddhesh.in/posts/relocations-fantastic-symbols-but-where-to-find-them.html&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Resolving ELF Relocation Name / Symbols - Chris Rohlf 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://em386.blogspot.com/2006/10/resolving-elf-relocation-name-symbols.html&quot;&gt;https://em386.blogspot.com/2006/10/resolving-elf-relocation-name-symbols.html&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Readings: Security&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;An Evil Copy: How the Loader Betrays You 
  &lt;ul&gt; 
   &lt;li&gt;Network and Distributed System Security Symposium (NDSS) 2017&lt;/li&gt; 
   &lt;li&gt;Xinyang Ge, Mathias Payer, Trent Jaeger&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://nebelwelt.net/publications/files/17NDSS.pdf&quot;&gt;https://nebelwelt.net/publications/files/17NDSS.pdf&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.microsoft.com/en-us/research/publication/evil-copy-loader-betrays/&quot;&gt;https://www.microsoft.com/en-us/research/publication/evil-copy-loader-betrays/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Breaking the links: Exploiting the linker 
  &lt;ul&gt; 
   &lt;li&gt;2011; Tim Brown&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://packetstormsecurity.com/files/102814/Breaking-The-Links-Exploiting-The-Linker.html&quot;&gt;https://packetstormsecurity.com/files/102814/Breaking-The-Links-Exploiting-The-Linker.html&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;paper: &lt;a href=&quot;https://dl.packetstormsecurity.net/papers/general/BTL.pdf&quot;&gt;https://dl.packetstormsecurity.net/papers/general/BTL.pdf&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;slides: &lt;a href=&quot;https://labs.portcullis.co.uk/download/BTLCC.pdf&quot;&gt;https://labs.portcullis.co.uk/download/BTLCC.pdf&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Dynamic Loader Oriented Programming on Linux 
  &lt;ul&gt; 
   &lt;li&gt;Reversing and Offensive-oriented Trends Symposium (ROOTS) 2017&lt;/li&gt; 
   &lt;li&gt;Julian Kirsch, Bruno Bierbaumer, Thomas Kittel, and Claudia Eckert&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://kirschju.re/projects/static/kirsch-roots-2017-paper.pdf&quot;&gt;https://kirschju.re/projects/static/kirsch-roots-2017-paper.pdf&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/kirschju/wiedergaenger&quot;&gt;https://github.com/kirschju/wiedergaenger&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Types for the Chain of Trust: No (loader) write left behind 
  &lt;ul&gt; 
   &lt;li&gt;2018 PhD dissertation; Rebecca .bx Shapiro&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://typedregions.com/&quot;&gt;http://typedregions.com/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Dissertation: &lt;a href=&quot;http://typedregions.com/main.pdf&quot;&gt;http://typedregions.com/main.pdf&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Defense slides: &lt;a href=&quot;http://typedregions.com/defense-slides.pdf&quot;&gt;http://typedregions.com/defense-slides.pdf&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Readings: Shared Libraries&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;Fun with weak dynamic linking 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://glandium.org/blog/?p=2764&quot;&gt;https://glandium.org/blog/?p=2764&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;How To Write Shared Libraries - Ulrich Drepper 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.akkadia.org/drepper/dsohowto.pdf&quot;&gt;https://www.akkadia.org/drepper/dsohowto.pdf&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Inlining — shared libraries are special 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://kristerw.blogspot.com/2016/11/inlining-shared-libraries-are-special.html&quot;&gt;https://kristerw.blogspot.com/2016/11/inlining-shared-libraries-are-special.html&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;PLT and GOT - the key to code sharing and dynamic libraries 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.technovelty.org/linux/plt-and-got-the-key-to-code-sharing-and-dynamic-libraries.html&quot;&gt;https://www.technovelty.org/linux/plt-and-got-the-key-to-code-sharing-and-dynamic-libraries.html&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Shared Libraries: Understanding Dynamic Loading 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;http://amir.rachum.com/blog/2016/09/17/shared-libraries/&quot;&gt;http://amir.rachum.com/blog/2016/09/17/shared-libraries/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Software Multiplexing: Share Your Libraries and Statically Link Them Too 
  &lt;ul&gt; 
   &lt;li&gt;SPLASH 2018 OOPSLA&lt;/li&gt; 
   &lt;li&gt;Will Dietz, Vikram Adve&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://2018.splashcon.org/event/splash-2018-oopsla-software-multiplexing-share-your-libraries-and-statically-link-them-too&quot;&gt;https://2018.splashcon.org/event/splash-2018-oopsla-software-multiplexing-share-your-libraries-and-statically-link-them-too&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://publish.illinois.edu/allvm-project/&quot;&gt;https://publish.illinois.edu/allvm-project/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/allvm/allvm-tools&quot;&gt;https://github.com/allvm/allvm-tools&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;hr&gt; 
&lt;h1&gt;Software&lt;/h1&gt; 
&lt;ul&gt; 
 &lt;li&gt;GNU Linker Output Viewer &amp;amp; Editor 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/JonTheBurger/GLOVE&quot;&gt;https://github.com/JonTheBurger/GLOVE&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;ld-limiter: Limit number of parallel link jobs 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/yugr/ld-limiter&quot;&gt;https://github.com/yugr/ld-limiter&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;libdlbind: Dynamic creation and update of ELF files, or: an allocator for JIT compilers 
  &lt;ul&gt; 
   &lt;li&gt;an extension to System V-style dynamic loaders to allow dynamic allocation of objects and dynamic binding of symbols&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/stephenrkell/libdlbind&quot;&gt;https://github.com/stephenrkell/libdlbind&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;linkermapviz 
  &lt;ul&gt; 
   &lt;li&gt;Interactive visualization of GNU ld’s linker map with a tree map.&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/PromyLOPh/linkermapviz&quot;&gt;https://github.com/PromyLOPh/linkermapviz&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;linksem: Semantic model for aspects of ELF static linking and DWARF debug information 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/rems-project/linksem&quot;&gt;https://github.com/rems-project/linksem&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;ShlibVisibilityChecker: Tool for locating internal symbols unnecessarily exported from shared libraries 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/yugr/ShlibVisibilityChecker&quot;&gt;https://github.com/yugr/ShlibVisibilityChecker&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Software: Linkers&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;ld - the GNU linker 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://sourceware.org/binutils/docs/ld/&quot;&gt;https://sourceware.org/binutils/docs/ld/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;LLD - The LLVM Linker 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://lld.llvm.org/&quot;&gt;https://lld.llvm.org/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Software: OS: macOS&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;ld64: Instructions on how to build the ld64 linker on macOS 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/dmaclach/ld64&quot;&gt;https://github.com/dmaclach/ld64&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;[lld] Initial commit for new Mach-O backend 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://reviews.llvm.org/D75382&quot;&gt;https://reviews.llvm.org/D75382&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;macdylibbundler: Utility to ease bundling libraries into executables for OSX 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/auriamg/macdylibbundler&quot;&gt;https://github.com/auriamg/macdylibbundler&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;zld: A faster version of Apple&apos;s linker 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/michaeleisel/zld&quot;&gt;https://github.com/michaeleisel/zld&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Software: OS: Linux&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;dlinject.py: Inject a shared library (i.e. arbitrary code) into a live linux process, without ptrace 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/DavidBuchanan314/dlinject&quot;&gt;https://github.com/DavidBuchanan314/dlinject&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Faulty.lib: Dynamic linker for compressed libraries, with on-demand decompression (ELF Linux systems) 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/glandium/faulty.lib&quot;&gt;https://github.com/glandium/faulty.lib&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Implib.so: POSIX equivalent of Windows DLL import libraries 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/yugr/Implib.so&quot;&gt;https://github.com/yugr/Implib.so&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;libosuction: A tool for stripping dynamic libraries of unneeded symbols 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/ispras/libosuction&quot;&gt;https://github.com/ispras/libosuction&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;System-Wide Elimination of Unreferenced Code and Data in Dynamically Linked Programs 
    &lt;ul&gt; 
     &lt;li&gt;Ivannikov ISPRAS Open Conference (ISPRAS) 2017&lt;/li&gt; 
     &lt;li&gt;V. Ivanishin, E. Kudryashov, A. Monakov, D. Melnik, J. Lee&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://doi.org/10.1109/ISPRAS.2017.00007&quot;&gt;https://doi.org/10.1109/ISPRAS.2017.00007&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;libpreloadvaccine: Whitelisting LD_PRELOAD libraries using LD_AUDIT 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/ForensicITGuy/libpreloadvaccine&quot;&gt;https://github.com/ForensicITGuy/libpreloadvaccine&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Whitelisting LD_PRELOAD for Fun and No Profit 
    &lt;ul&gt; 
     &lt;li&gt;Shmoocon 2020; Tony Lambert&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=nM9Y2Sky6S0&quot;&gt;https://www.youtube.com/watch?v=nM9Y2Sky6S0&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://speakerdeck.com/forensicitguy/whitelisting-ld-preload-for-fun-and-no-profit&quot;&gt;https://speakerdeck.com/forensicitguy/whitelisting-ld-preload-for-fun-and-no-profit&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;libprocesshider: Hide a process under Linux using the ld preloader 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/gianlucaborello/libprocesshider&quot;&gt;https://github.com/gianlucaborello/libprocesshider&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://sysdig.com/blog/hiding-linux-processes-for-fun-and-profit/&quot;&gt;https://sysdig.com/blog/hiding-linux-processes-for-fun-and-profit/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;hr&gt; 
&lt;h1&gt;Talks&lt;/h1&gt; 
&lt;h2&gt;Talks: 2019&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;Dynamic Linking On GNU/Linux 
  &lt;ul&gt; 
   &lt;li&gt;emBO++ 2019; Florian Sowade&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=G2r5JhVDddw&quot;&gt;https://www.youtube.com/watch?v=G2r5JhVDddw&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.slideshare.net/FlorianSowade/dynamic-linking-on-gnulinux/&quot;&gt;https://www.slideshare.net/FlorianSowade/dynamic-linking-on-gnulinux/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Pardon the Interposition—Modifying and Improving Software Behavior with Interposers 
  &lt;ul&gt; 
   &lt;li&gt;USENIX LISA 2019; Danny Chen&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.usenix.org/conference/lisa19/presentation/chen&quot;&gt;https://www.usenix.org/conference/lisa19/presentation/chen&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;The ACM-NVIDIA Compiler summer school lectures (2019) 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://nptel.ac.in/courses/128/106/128106009/&quot;&gt;https://nptel.ac.in/courses/128/106/128106009/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/playlist?list=PLPeEbErKGwN15rF-BnlngobapgIRZbAK4&quot;&gt;https://www.youtube.com/playlist?list=PLPeEbErKGwN15rF-BnlngobapgIRZbAK4&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Program Execution Environment 
    &lt;ul&gt; 
     &lt;li&gt;part 1: &lt;a href=&quot;https://www.youtube.com/watch?v=Sf4JnUcJxSQ&quot;&gt;https://www.youtube.com/watch?v=Sf4JnUcJxSQ&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;part 2: &lt;a href=&quot;https://www.youtube.com/watch?v=e3DnPTUunZk&quot;&gt;https://www.youtube.com/watch?v=e3DnPTUunZk&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;part 3: &lt;a href=&quot;https://www.youtube.com/watch?v=h__sj8IfONg&quot;&gt;https://www.youtube.com/watch?v=h__sj8IfONg&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;part 4: &lt;a href=&quot;https://www.youtube.com/watch?v=yzYXrwxu6YM&quot;&gt;https://www.youtube.com/watch?v=yzYXrwxu6YM&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;part 5: &lt;a href=&quot;https://www.youtube.com/watch?v=4_LK7nOSlbM&quot;&gt;https://www.youtube.com/watch?v=4_LK7nOSlbM&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;part 6: &lt;a href=&quot;https://www.youtube.com/watch?v=CzAwzTkbMDw&quot;&gt;https://www.youtube.com/watch?v=CzAwzTkbMDw&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;part 7: &lt;a href=&quot;https://www.youtube.com/watch?v=IWU5Av6YpEw&quot;&gt;https://www.youtube.com/watch?v=IWU5Av6YpEw&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;part 8: &lt;a href=&quot;https://www.youtube.com/watch?v=Wd4NaS0_7Tc&quot;&gt;https://www.youtube.com/watch?v=Wd4NaS0_7Tc&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;What makes LLD so fast? 
  &lt;ul&gt; 
   &lt;li&gt;FOSDEM 2019; Peter Smith&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://fosdem.org/2019/schedule/event/llvm_lld/&quot;&gt;https://fosdem.org/2019/schedule/event/llvm_lld/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=CeHhveHHzII&quot;&gt;https://www.youtube.com/watch?v=CeHhveHHzII&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Talks: 2018&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;Behind the Scenes of the Xcode Build Process 
  &lt;ul&gt; 
   &lt;li&gt;WWDC 2018; Jake Petroules, Jürgen Ributzka, Devin Coughlin, Louis Gerbarg&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://developer.apple.com/videos/play/wwdc2018/415/&quot;&gt;https://developer.apple.com/videos/play/wwdc2018/415/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;The Bits Between the Bits: How We Get to main() 
  &lt;ul&gt; 
   &lt;li&gt;CppCon 2018; Matt Godbolt&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=dOfucXtyEsU&quot;&gt;https://www.youtube.com/watch?v=dOfucXtyEsU&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Slides: &lt;a href=&quot;https://mattgodbolt.github.io/cppcon-bits-between-bits/&quot;&gt;https://mattgodbolt.github.io/cppcon-bits-between-bits/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Talks: 2017&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;App Startup Time: Past, Present, and Future 
  &lt;ul&gt; 
   &lt;li&gt;WWDC 2017; Louis Gerbarg&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://developer.apple.com/videos/play/wwdc2017/413/&quot;&gt;https://developer.apple.com/videos/play/wwdc2017/413/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&quot;Learn about the dyld dynamic linker used on Apple platforms, how it&apos;s changed over the years, and where it&apos;s headed next. Find out how improved tooling makes it easier to optimize your app&apos;s launch time, and see how new changes coming in dyld will bring even further launch time improvements.&quot;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;LLD from a user&apos;s perspective 
  &lt;ul&gt; 
   &lt;li&gt;FOSDEM 2017; Peter Smith&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://archive.fosdem.org/2017/schedule/event/lld/&quot;&gt;https://archive.fosdem.org/2017/schedule/event/lld/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://archive.fosdem.org/2017/schedule/event/lld/attachments/slides/1446/export/events/attachments/lld/slides/1446/FosdemLLD2017.pdf&quot;&gt;https://archive.fosdem.org/2017/schedule/event/lld/attachments/slides/1446/export/events/attachments/lld/slides/1446/FosdemLLD2017.pdf&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;My Little Object File: How Linkers Implement C++ 
  &lt;ul&gt; 
   &lt;li&gt;CppCon 2017; Michael Spencer&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://youtu.be/a5L66zguFe4&quot;&gt;https://youtu.be/a5L66zguFe4&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;The Missing Link: The Curious symbiosis between C++ and the Linker 
  &lt;ul&gt; 
   &lt;li&gt;C++ Meetup Sydney hosted by IMC; December 6, 2017&lt;/li&gt; 
   &lt;li&gt;Dave Gittins&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=twNoIhGKIoo&quot;&gt;https://www.youtube.com/watch?v=twNoIhGKIoo&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Talks: 2016&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;New LLD linker for ELF: A high performance linker from the LLVM project 
  &lt;ul&gt; 
   &lt;li&gt;2016 EuroLLVM Developers&apos; Meeting; R. Ueyama&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=CYCRqjVa6l4&quot;&gt;https://www.youtube.com/watch?v=CYCRqjVa6l4&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://llvm.org/devmtg/2016-03/Presentations/EuroLLVM%202016-%20New%20LLD%20linker%20for%20ELF.pdf&quot;&gt;https://llvm.org/devmtg/2016-03/Presentations/EuroLLVM%202016-%20New%20LLD%20linker%20for%20ELF.pdf&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Optimizing App Startup Time: Linkers, loaders, and you 
  &lt;ul&gt; 
   &lt;li&gt;WWDC 2016; Nick Kledzik, Louis Gerbarg&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://developer.apple.com/videos/play/wwdc2016/406/&quot;&gt;https://developer.apple.com/videos/play/wwdc2016/406/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&quot;Launching an App is a complicated and subtle process and the ramifications on launch times of different App design patterns are often non-obvious. Come learn what happens in the time between when an App begins launching and when the main() function gets control and how that time relates to the code and structure of your App. Learn about the inner details of the dynamic loader, dyld, and best practices for structuring your code to perform at its best from the very start.&quot;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Naked Objects</title>
      <link>https://tedneward.github.io/Research/reading/development/nakedobjects/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">reading/development/nakedobjects/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;http://isis.apache.org/versions/2.0.0-M1/guides/ugfun/resources/core-concepts/Pawson-Naked-Objects-thesis.pdf&quot;&gt;Richard Pawson&apos;s Thesis&lt;/a&gt; was the backbone of this. Later, after creating the original Naked Objects framework (in Java Swing), he wrote &lt;a href=&quot;http://www.nakedobjects.org/book/&quot;&gt;a book&lt;/a&gt; (now unfortunately woefully out of date in terms of implmentation) on it.&lt;/p&gt; 
&lt;p&gt;See also: &lt;a href=&quot;/presentation/nakedobjects&quot;&gt;Naked Objects Framework&lt;/a&gt; and &lt;a href=&quot;/presentation/isis&quot;&gt;Apache Isis&lt;/a&gt;, the two direct successors to Pawson&apos;s work for the CLR and JVM, respectively.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Fuzzing (as part of testing)</title>
      <link>https://tedneward.github.io/Research/reading/development/fuzzing/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">reading/development/fuzzing/index.html</guid>
      	<description>
	&lt;h1&gt;General&lt;/h1&gt; 
&lt;ul&gt; 
 &lt;li&gt;Awesome Fuzzing 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/secfigo/Awesome-Fuzzing&quot;&gt;https://github.com/secfigo/Awesome-Fuzzing&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Google Fuzzing Forum 
  &lt;ul&gt; 
   &lt;li&gt;Tutorials, examples, discussions, research proposals, and other resources related to fuzzing&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/google/fuzzing&quot;&gt;https://github.com/google/fuzzing&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.reddit.com/r/fuzzing/&quot;&gt;https://www.reddit.com/r/fuzzing/&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;The Fuzzing Project 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://fuzzing-project.org/&quot;&gt;https://fuzzing-project.org/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;hr&gt; 
&lt;h1&gt;Readings&lt;/h1&gt; 
&lt;h2&gt;Readings: Books&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.fuzzingbook.org/&quot;&gt;Generating Software Tests: Breaking Software for Fun and Profit&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Readings: General&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;Evaluating Fuzz Testing 
  &lt;ul&gt; 
   &lt;li&gt;ACM Conference on Computer and Communications Security (CCS) 2018&lt;/li&gt; 
   &lt;li&gt;George T. Klees, Andrew Ruef, Benjamin Cooper, Shiyi Wei, Michael Hicks&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://www.cs.umd.edu/~mwh/papers/klees2018fuzzeval.html&quot;&gt;http://www.cs.umd.edu/~mwh/papers/klees2018fuzzeval.html&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://arxiv.org/abs/1808.09700&quot;&gt;https://arxiv.org/abs/1808.09700&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=ID8XtoMn43I&quot;&gt;https://www.youtube.com/watch?v=ID8XtoMn43I&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Evaluating Empirical Evaluations (for Fuzz Testing) 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;http://www.pl-enthusiast.net/2018/08/23/evaluating-empirical-evaluations-for-fuzz-testing/&quot;&gt;http://www.pl-enthusiast.net/2018/08/23/evaluating-empirical-evaluations-for-fuzz-testing/&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;How to Spot Good Fuzzing Research 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://blog.trailofbits.com/2018/10/05/how-to-spot-good-fuzzing-research/&quot;&gt;https://blog.trailofbits.com/2018/10/05/how-to-spot-good-fuzzing-research/&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;Fuzzing and how to evaluate it 
    &lt;ul&gt; 
     &lt;li&gt;ISSISP 2018; Michael Hicks&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://cs.anu.edu.au/cybersec/issisp2018/assets/slides/hicks-fuzz-testing-eval.pdf&quot;&gt;https://cs.anu.edu.au/cybersec/issisp2018/assets/slides/hicks-fuzz-testing-eval.pdf&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/wcventure/FuzzingPaper&quot;&gt;FuzzingPaper: Recent Papers Related To Fuzzing&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;Fuzzing: a survey 
  &lt;ul&gt; 
   &lt;li&gt;Cybersecurity 2018&lt;/li&gt; 
   &lt;li&gt;Jun Li, Bodong Zhao and Chao Zhang&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://cybersecurity.springeropen.com/articles/10.1186/s42400-018-0002-y&quot;&gt;https://cybersecurity.springeropen.com/articles/10.1186/s42400-018-0002-y&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Fuzzing: Hack, Art, and Science 
  &lt;ul&gt; 
   &lt;li&gt;Communications of the ACM (CACM) 63(2) 2020&lt;/li&gt; 
   &lt;li&gt;Patrice Godefroid&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://doi.org/10.1145/3363824&quot;&gt;https://doi.org/10.1145/3363824&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://cacm.acm.org/magazines/2020/2/242350-fuzzing&quot;&gt;https://cacm.acm.org/magazines/2020/2/242350-fuzzing&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://patricegodefroid.github.io/public_psfiles/Fuzzing-101-CACM2020.pdf&quot;&gt;https://patricegodefroid.github.io/public_psfiles/Fuzzing-101-CACM2020.pdf&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;The Art, Science, and Engineering of Fuzzing: A Survey 
  &lt;ul&gt; 
   &lt;li&gt;IEEE Transactions on Software Engineering (2019)&lt;/li&gt; 
   &lt;li&gt;Valentin J.M. Manes, HyungSeok Han, Choongwoo Han, Sang Kil Cha, Manuel Egele, Edward J. Schwartz, Maverick Woo&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://arxiv.org/abs/1812.00140&quot;&gt;https://arxiv.org/abs/1812.00140&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.jiliac.com/publication/survey/&quot;&gt;https://www.jiliac.com/publication/survey/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Genealogy Database of Fuzzers 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://github.com/SoftSec-KAIST/Fuzzing-Survey&quot;&gt;https://github.com/SoftSec-KAIST/Fuzzing-Survey&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://fuzzing-survey.org/&quot;&gt;https://fuzzing-survey.org/&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;The Fuzzing Hype-Train: How Random Testing Triggers Thousands of Crashes 
  &lt;ul&gt; 
   &lt;li&gt;IEEE Security &amp;amp; Privacy, 17(1) 2019&lt;/li&gt; 
   &lt;li&gt;Mathias Payer&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://ieeexplore.ieee.org/document/8674043&quot;&gt;https://ieeexplore.ieee.org/document/8674043&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Readings: Practice&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;Billions and billions of constraints: Whitebox fuzz testing in production 
  &lt;ul&gt; 
   &lt;li&gt;International Conference on Software Engineering ICSE 2013&lt;/li&gt; 
   &lt;li&gt;E. Bounimova, P. Godefroid, D. Molnar&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.microsoft.com/en-us/research/publication/billions-and-billions-of-constraints-whitebox-fuzz-testing-in-production/&quot;&gt;https://www.microsoft.com/en-us/research/publication/billions-and-billions-of-constraints-whitebox-fuzz-testing-in-production/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://patricegodefroid.github.io/public_psfiles/icse2013.pdf&quot;&gt;https://patricegodefroid.github.io/public_psfiles/icse2013.pdf&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://courses.cs.washington.edu/courses/cse484/14au/slides/whitebox-fuzzing.pdf&quot;&gt;https://courses.cs.washington.edu/courses/cse484/14au/slides/whitebox-fuzzing.pdf&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Interview with Patrice Godefroid - &lt;a href=&quot;https://www.coursera.org/learn/software-security/lecture/SItpe/interview-with-patrice-godefroid&quot;&gt;https://www.coursera.org/learn/software-security/lecture/SItpe/interview-with-patrice-godefroid&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Building an ARM-based Fuzzing Cluster 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://baerli.github.io/arm-fuzzingcluster/&quot;&gt;https://baerli.github.io/arm-fuzzingcluster/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Circumventing Fuzzing Roadblocks with Compiler Transformations 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://lafintel.wordpress.com/2016/08/15/circumventing-fuzzing-roadblocks-with-compiler-transformations/&quot;&gt;https://lafintel.wordpress.com/2016/08/15/circumventing-fuzzing-roadblocks-with-compiler-transformations/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;LAF LLVM Passes - &lt;a href=&quot;https://gitlab.com/laf-intel/laf-llvm-pass&quot;&gt;https://gitlab.com/laf-intel/laf-llvm-pass&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Fuzzers love assertions 
  &lt;ul&gt; 
   &lt;li&gt;Jesse Ruderman&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://www.squarefree.com/2014/02/03/fuzzers-love-assertions/&quot;&gt;http://www.squarefree.com/2014/02/03/fuzzers-love-assertions/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Fuzzing with AFL workshop 
  &lt;ul&gt; 
   &lt;li&gt;SteelCon 2017, BSides London and Bristol 2019&lt;/li&gt; 
   &lt;li&gt;Michael Macnair&lt;/li&gt; 
   &lt;li&gt;Exercises to learn how to fuzz with American Fuzzy Lop&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/mykter/afl-training&quot;&gt;https://github.com/mykter/afl-training&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Fuzzing workflows: a fuzz job from start to finish 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://foxglovesecurity.com/2016/03/15/fuzzing-workflows-a-fuzz-job-from-start-to-finish/&quot;&gt;https://foxglovesecurity.com/2016/03/15/fuzzing-workflows-a-fuzz-job-from-start-to-finish/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;John Regehr 
  &lt;ul&gt; 
   &lt;li&gt;Who Fuzzes the Fuzzer? - &lt;a href=&quot;https://blog.regehr.org/archives/501&quot;&gt;https://blog.regehr.org/archives/501&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Better Random Testing by Leaving Features Out - &lt;a href=&quot;https://blog.regehr.org/archives/591&quot;&gt;https://blog.regehr.org/archives/591&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Swarm Testing 
    &lt;ul&gt; 
     &lt;li&gt;ISSTA 2012; Alex Groce, Chaoqiang Zhang, Eric Eide, Yang Chen, John Regehr&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;http://www.cs.utah.edu/~regehr/papers/swarm12.pdf&quot;&gt;http://www.cs.utah.edu/~regehr/papers/swarm12.pdf&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;Draft Paper about Better Fuzzing - &lt;a href=&quot;https://blog.regehr.org/archives/595&quot;&gt;https://blog.regehr.org/archives/595&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;Tricking a Whitebox Testcase Generator - &lt;a href=&quot;https://blog.regehr.org/archives/672&quot;&gt;https://blog.regehr.org/archives/672&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;How to Fuzz an ADT Implementation - &lt;a href=&quot;https://blog.regehr.org/archives/896&quot;&gt;https://blog.regehr.org/archives/896&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Fuzzers Need Taming - &lt;a href=&quot;https://blog.regehr.org/archives/925&quot;&gt;https://blog.regehr.org/archives/925&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Levels of Fuzzing - &lt;a href=&quot;https://blog.regehr.org/archives/1039&quot;&gt;https://blog.regehr.org/archives/1039&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;A New Compiler Fuzzing Paper - &lt;a href=&quot;https://blog.regehr.org/archives/1061&quot;&gt;https://blog.regehr.org/archives/1061&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;What afl-fuzz Is Bad At - &lt;a href=&quot;https://blog.regehr.org/archives/1238&quot;&gt;https://blog.regehr.org/archives/1238&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;API Fuzzing vs. File Fuzzing: A Cautionary Tale - &lt;a href=&quot;https://blog.regehr.org/archives/1269&quot;&gt;https://blog.regehr.org/archives/1269&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Reducers are Fuzzers - &lt;a href=&quot;https://blog.regehr.org/archives/1284&quot;&gt;https://blog.regehr.org/archives/1284&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Write Fuzzable Code - &lt;a href=&quot;https://blog.regehr.org/archives/1687&quot;&gt;https://blog.regehr.org/archives/1687&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Helping Generative Fuzzers Avoid Looking Only Where the Light is Good, Part 1 - &lt;a href=&quot;https://blog.regehr.org/archives/1700&quot;&gt;https://blog.regehr.org/archives/1700&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;One Weird Trick for Finding More Crashes: crasher recycling 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://insights.sei.cmu.edu/cert/2013/09/one-weird-trick-for-finding-more-crashes-1.html&quot;&gt;https://insights.sei.cmu.edu/cert/2013/09/one-weird-trick-for-finding-more-crashes-1.html&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Statistical Evaluation of a Fuzzing Dictionary 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://bshastry.github.io/2018/10/01/Evaluating-Dictionary-For-Fuzzing.html&quot;&gt;https://bshastry.github.io/2018/10/01/Evaluating-Dictionary-For-Fuzzing.html&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Static Program Analysis as a Fuzzing Aid 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://link.springer.com/chapter/10.1007/978-3-319-66332-6_2&quot;&gt;https://link.springer.com/chapter/10.1007/978-3-319-66332-6_2&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;Orthrus: A tool to manage, conduct, and assess dictionary-based fuzz testing 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://github.com/test-pipeline/Orthrus&quot;&gt;https://github.com/test-pipeline/Orthrus&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;The Art of Fuzzing – Slides and Demos 
  &lt;ul&gt; 
   &lt;li&gt;2017; René Freingruber&lt;/li&gt; 
   &lt;li&gt;AFL &amp;amp; WinAFL, Taint Analysis, Reversing Tricks for Fuzzing, in-memory fuzzing, DynamoRio&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://sec-consult.com/en/blog/2017/11/the-art-of-fuzzing-slides-and-demos/&quot;&gt;https://sec-consult.com/en/blog/2017/11/the-art-of-fuzzing-slides-and-demos/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://sec-consult.com/wp-content/uploads/files/vulnlab/the_art_of_fuzzing_slides.pdf&quot;&gt;https://sec-consult.com/wp-content/uploads/files/vulnlab/the_art_of_fuzzing_slides.pdf&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;What You Corrupt Is Not What You Crash: Challenges in Fuzzing Embedded Devices 
  &lt;ul&gt; 
   &lt;li&gt;NDSS 2018&lt;/li&gt; 
   &lt;li&gt;M. Muench, J. Stijohann, F. Kargl, A. Francillon, Davide Balzarotti&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://s3.eurecom.fr/docs/ndss18_muench.pdf&quot;&gt;http://s3.eurecom.fr/docs/ndss18_muench.pdf&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/avatartwo/ndss18_wycinwyc&quot;&gt;https://github.com/avatartwo/ndss18_wycinwyc&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;hr&gt; 
&lt;h1&gt;Software&lt;/h1&gt; 
&lt;ul&gt; 
 &lt;li&gt;Angora: a mutation-based fuzzer 
  &lt;ul&gt; 
   &lt;li&gt;increase branch coverage by solving path constraints without symbolic execution&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/AngoraFuzzer/Angora&quot;&gt;https://github.com/AngoraFuzzer/Angora&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Angora: Efficient Fuzzing by Principled Search 
    &lt;ul&gt; 
     &lt;li&gt;Security and Privacy (S&amp;amp;P) 2018&lt;/li&gt; 
     &lt;li&gt;Peng Chen, Hao Chen&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://arxiv.org/abs/1803.01307&quot;&gt;https://arxiv.org/abs/1803.01307&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;ClusterFuzz: a scalable fuzzing infrastructure which finds security and stability issues in software 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/google/clusterfuzz&quot;&gt;https://github.com/google/clusterfuzz&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://opensource.googleblog.com/2019/02/open-sourcing-clusterfuzz.html&quot;&gt;https://opensource.googleblog.com/2019/02/open-sourcing-clusterfuzz.html&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;DeepState: A unit test-like interface for fuzzing and symbolic execution 
  &lt;ul&gt; 
   &lt;li&gt;DeepState is a framework that provides C and C++ developers with a common interface to various symbolic execution and fuzzing engines. Users can write one test harness using a Google Test-like API, then execute it using multiple backends without having to learn the complexities of the underlying engines. It supports writing unit tests and API sequence tests, as well as automatic test generation.&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/trailofbits/deepstate&quot;&gt;https://github.com/trailofbits/deepstate&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;DeepState: Symbolic Unit Testing for C and C++ 
    &lt;ul&gt; 
     &lt;li&gt;NDSS 18 Workshop on Binary Analysis Research&lt;/li&gt; 
     &lt;li&gt;Peter Goodman and Alex Groce&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://www.cefns.nau.edu/~adg326/bar18.pdf&quot;&gt;https://www.cefns.nau.edu/~adg326/bar18.pdf&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;Fuzzing an API with DeepState 
    &lt;ul&gt; 
     &lt;li&gt;Part 1: &lt;a href=&quot;https://blog.trailofbits.com/2019/01/22/fuzzing-an-api-with-deepstate-part-1/&quot;&gt;https://blog.trailofbits.com/2019/01/22/fuzzing-an-api-with-deepstate-part-1/&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;Part 2: &lt;a href=&quot;https://blog.trailofbits.com/2019/01/23/fuzzing-an-api-with-deepstate-part-2/&quot;&gt;https://blog.trailofbits.com/2019/01/23/fuzzing-an-api-with-deepstate-part-2/&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;FuzzFactory: Domain-Specific Fuzzing with Waypoints 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/rohanpadhye/FuzzFactory&quot;&gt;https://github.com/rohanpadhye/FuzzFactory&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;SPLASH 2019 OOPSLA 
    &lt;ul&gt; 
     &lt;li&gt;Rohan Padhye, Caroline Lemieux, Koushik Sen, Laurent Simon, Hayawardh Vijayakumar&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://2019.splashcon.org/details/splash-2019-oopsla/57/FuzzFactory-Domain-Specific-Fuzzing-with-Waypoints&quot;&gt;https://2019.splashcon.org/details/splash-2019-oopsla/57/FuzzFactory-Domain-Specific-Fuzzing-with-Waypoints&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://people.eecs.berkeley.edu/~ksen/papers/fuzzfactory.pdf&quot;&gt;https://people.eecs.berkeley.edu/~ksen/papers/fuzzfactory.pdf&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://people.eecs.berkeley.edu/~rohanpadhye/files/fuzzfactory-oopsla19.pdf&quot;&gt;https://people.eecs.berkeley.edu/~rohanpadhye/files/fuzzfactory-oopsla19.pdf&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Grammarinator: ANTLRv4 grammar-based test generator 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/renatahodovan/grammarinator&quot;&gt;https://github.com/renatahodovan/grammarinator&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Honggfuzz 
  &lt;ul&gt; 
   &lt;li&gt;Security oriented fuzzer with powerful analysis options. Supports evolutionary, feedback-driven fuzzing based on code coverage (software- and hardware-based)&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://honggfuzz.dev/&quot;&gt;https://honggfuzz.dev/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/google/honggfuzz&quot;&gt;https://github.com/google/honggfuzz&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Feedback-driven fuzzing - &lt;a href=&quot;https://github.com/google/honggfuzz/blob/master/docs/FeedbackDrivenFuzzing.md&quot;&gt;https://github.com/google/honggfuzz/blob/master/docs/FeedbackDrivenFuzzing.md&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Fuzzing TCP servers - &lt;a href=&quot;http://blog.swiecki.net/2018/01/fuzzing-tcp-servers.html&quot;&gt;http://blog.swiecki.net/2018/01/fuzzing-tcp-servers.html&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Internals of Hongfuzz - Intel PT - &lt;a href=&quot;https://tunnelshade.in/blog/2018/09/hongfuzz-intel-pt-instrumentation/&quot;&gt;https://tunnelshade.in/blog/2018/09/hongfuzz-intel-pt-instrumentation/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;JFS (JIT Fuzzing Solver) 
  &lt;ul&gt; 
   &lt;li&gt;Constraint solver based on coverage-guided fuzzing&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/delcypher/jfs&quot;&gt;https://github.com/delcypher/jfs&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Just Fuzz It: Solving Floating-Point Constraints using Coverage-Guided Fuzzing 
    &lt;ul&gt; 
     &lt;li&gt;ESEC/FSE 2019&lt;/li&gt; 
     &lt;li&gt;Daniel Liew, Cristian Cadar, Alastair F. Donaldson, and J. Ryan Stinnett.&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://srg.doc.ic.ac.uk/files/papers/jfs-esecfse-19.pdf&quot;&gt;https://srg.doc.ic.ac.uk/files/papers/jfs-esecfse-19.pdf&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;MoonLight: Fuzzing Corpus Design and Construction 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://gitlab.anu.edu.au/lunar/moonlight&quot;&gt;https://gitlab.anu.edu.au/lunar/moonlight&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Nautilus: Fishing for Deep Bugs with Grammars 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/RUB-SysSec/nautilus&quot;&gt;https://github.com/RUB-SysSec/nautilus&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Network and Distributed System Security Symposium (NDSS) 2019 
    &lt;ul&gt; 
     &lt;li&gt;Cornelius Aschermann, Tommaso Frassetto, Thorsten Holz, Patrick Jauernig, Ahmad-Reza Sadeghi, Daniel Teuchert&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://www.syssec.ruhr-uni-bochum.de/research/publications/nautilus/&quot;&gt;https://www.syssec.ruhr-uni-bochum.de/research/publications/nautilus/&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Orthrus 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/test-pipeline/orthrus&quot;&gt;https://github.com/test-pipeline/orthrus&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Orthrus is a tool for managing, conducting, and assessing dictionary-based security (fuzz) testing for autotools projects. At the moment, it supports Clang/LLVM instrumentation and the AFL ecosystem (afl-fuzz, afl-utils, afl-cov). The ultimate aim is for Orthrus to be a generic wrapper around state-of-the-art fuzz and instrumentation tools on the one hand, and disparate build systems on the other.&lt;/li&gt; 
   &lt;li&gt;Static Program Analysis as a Fuzzing Aid 
    &lt;ul&gt; 
     &lt;li&gt;RAID 2017&lt;/li&gt; 
     &lt;li&gt;Bhargava Shastry, Markus Leutner, Tobias Fiebig, Kashyap Thimmaraju, Fabian Yamaguchi, Konrad Rieck, Stefan Schmid, Jean-Pierre Seifert, Anja Feldmann&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://aperture-labs.org/pdf/raid2017.pdf&quot;&gt;https://aperture-labs.org/pdf/raid2017.pdf&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;http://users.sec.t-labs.tu-berlin.de/~bshastry/raid17_slidedeck.pdf&quot;&gt;http://users.sec.t-labs.tu-berlin.de/~bshastry/raid17_slidedeck.pdf&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://link.springer.com/chapter/10.1007/978-3-319-66332-6_2&quot;&gt;https://link.springer.com/chapter/10.1007/978-3-319-66332-6_2&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;Static Exploration of Taint-Style Vulnerabilities Found by Fuzzing 
    &lt;ul&gt; 
     &lt;li&gt;USENIX WOOT 2017&lt;/li&gt; 
     &lt;li&gt;Bhargava Shastry, Federico Maggi, Fabian Yamaguchi, Konrad Rieck, Jean-Pierre Seifert&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://arxiv.org/abs/1706.00206&quot;&gt;https://arxiv.org/abs/1706.00206&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;QSYM: A Practical Concolic Execution Engine Tailored for Hybrid Fuzzing 
  &lt;ul&gt; 
   &lt;li&gt;USENIX Security 2018&lt;/li&gt; 
   &lt;li&gt;Insu Yun, Sangho Lee, Meng Xu, Yeongjin Jang, Taesoo Kim&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/sslab-gatech/qsym/&quot;&gt;https://github.com/sslab-gatech/qsym/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.usenix.org/conference/usenixsecurity18/presentation/yun&quot;&gt;https://www.usenix.org/conference/usenixsecurity18/presentation/yun&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Radamsa 
  &lt;ul&gt; 
   &lt;li&gt;a general-purpose fuzzer&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://gitlab.com/akihe/radamsa&quot;&gt;https://gitlab.com/akihe/radamsa&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;RamFuzz: Combining Unit Tests, Fuzzing, and AI 
  &lt;ul&gt; 
   &lt;li&gt;A fuzzer for individual method parameters&lt;/li&gt; 
   &lt;li&gt;RamFuzz is a fuzzer for individual method parameters in unit tests. A unit test can use RamFuzz to generate random parameter values for methods under test. The values are logged, and the log can be replayed to repeat the exact same test scenario. But RamFuzz also allows mutation of the replay, where some parts of the log are replayed while others are replaced by newly generated values. The new run is also logged, yielding a mutated test scenario and allowing the classic fuzzing evolution process of progressively mutating the input until a bug is triggered.&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/dekimir/RamFuzz&quot;&gt;https://github.com/dekimir/RamFuzz&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;RamFuzz: A Framework for C++ Test Generation via Deep Learning - &lt;a href=&quot;https://github.com/dekimir/RamFuzz/blob/master/sci/ramfuzz.md&quot;&gt;https://github.com/dekimir/RamFuzz/blob/master/sci/ramfuzz.md&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;RapidFuzz 
  &lt;ul&gt; 
   &lt;li&gt;An experiment of hacking around RapidCheck to combine RapidCheck&apos;s property-based testing with libFuzzer.&lt;/li&gt; 
   &lt;li&gt;It was very much influenced by Dan Luu&apos;s post which suggested exactly this combination: &lt;a href=&quot;http://danluu.com/testing/&quot;&gt;http://danluu.com/testing/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/unapiedra/rapidfuzz&quot;&gt;https://github.com/unapiedra/rapidfuzz&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;TriforceAFL: AFL/QEMU fuzzing with full-system emulation. 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/nccgroup/triforceafl&quot;&gt;https://github.com/nccgroup/triforceafl&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/timnewsham/TriforceAFL&quot;&gt;https://github.com/timnewsham/TriforceAFL&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.nccgroup.trust/uk/about-us/newsroom-and-events/blogs/2016/june/project-triforce-run-afl-on-everything/&quot;&gt;https://www.nccgroup.trust/uk/about-us/newsroom-and-events/blogs/2016/june/project-triforce-run-afl-on-everything/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;zzuf: a transparent application input fuzzer 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/samhocevar/zzuf&quot;&gt;https://github.com/samhocevar/zzuf&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://caca.zoy.org/wiki/zzuf&quot;&gt;http://caca.zoy.org/wiki/zzuf&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Software: AFL&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;american fuzzy lop (AFL) 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;http://lcamtuf.coredump.cx/afl/&quot;&gt;http://lcamtuf.coredump.cx/afl/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Technical &quot;whitepaper&quot; for afl-fuzz 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;http://lcamtuf.coredump.cx/afl/technical_details.txt&quot;&gt;http://lcamtuf.coredump.cx/afl/technical_details.txt&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;Automatically inferring file syntax with afl-analyze 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://lcamtuf.blogspot.com/2016/02/say-hello-to-afl-analyze.html&quot;&gt;https://lcamtuf.blogspot.com/2016/02/say-hello-to-afl-analyze.html&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;AFL++ 
  &lt;ul&gt; 
   &lt;li&gt;afl++ is afl 2.56b with community patches, AFLfast power schedules, qemu 3.1 upgrade + laf-intel support, MOpt mutators, InsTrim instrumentation, unicorn_mode, Redqueen and a lot more!&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://aflplus.plus/&quot;&gt;https://aflplus.plus/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/AFLplusplus/AFLplusplus&quot;&gt;https://github.com/AFLplusplus/AFLplusplus&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;AFL-based-fuzzers-overview 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/google/fuzzing/blob/master/docs/afl-based-fuzzers-overview.md&quot;&gt;https://github.com/google/fuzzing/blob/master/docs/afl-based-fuzzers-overview.md&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;afl-utils 
  &lt;ul&gt; 
   &lt;li&gt;Utilities for automated crash sample processing/analysis, easy afl-fuzz job management and corpus optimization&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://gitlab.com/rc0r/afl-utils&quot;&gt;https://gitlab.com/rc0r/afl-utils&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;afl-cov - AFL Fuzzing Code Coverage 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/mrash/afl-cov&quot;&gt;https://github.com/mrash/afl-cov&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;afl-cov: AFL fuzzing coverage CFG visualization 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/axt/afl-cov&quot;&gt;https://github.com/axt/afl-cov&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;afl-fuzz on different file systems 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://barro.github.io/2018/06/afl-fuzz-on-different-file-systems/&quot;&gt;https://barro.github.io/2018/06/afl-fuzz-on-different-file-systems/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;AFL-Mutation-Chain 
  &lt;ul&gt; 
   &lt;li&gt;Recovers an approximation of the mutation chain that led to a particular seed in an AFL queue. Outputs the chain in either JSON or Graphviz DOT format.&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/adrianherrera/afl-mutation-chain&quot;&gt;https://github.com/adrianherrera/afl-mutation-chain&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;AFLGo: Directed Greybox Fuzzing 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/aflgo/aflgo&quot;&gt;https://github.com/aflgo/aflgo&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Directed Greybox Fuzzing 
    &lt;ul&gt; 
     &lt;li&gt;Conference on Computer and Communications Security (CCS) 2017&lt;/li&gt; 
     &lt;li&gt;Marcel Böhme, Van-Thuan Pham, Manh-Dung Nguyen, Abhik Roychoudhury&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;http://www.comp.nus.edu.sg/~abhik/pdf/CCS17.pdf&quot;&gt;http://www.comp.nus.edu.sg/~abhik/pdf/CCS17.pdf&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Awesome-AFL 
  &lt;ul&gt; 
   &lt;li&gt;A curated list of different AFL forks and AFL inspired fuzzers with detailed equivalent academic papers with AFL-fuzzing tutorials&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/Microsvuln/Awesome-AFL&quot;&gt;https://github.com/Microsvuln/Awesome-AFL&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Driller: augmenting AFL with symbolic execution! 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/shellphish/driller&quot;&gt;https://github.com/shellphish/driller&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Driller: Augmenting fuzzing through selective symbolic execution 
    &lt;ul&gt; 
     &lt;li&gt;NDSS 2016&lt;/li&gt; 
     &lt;li&gt;N. Stephens, J. Grosen, C. Salls, A. Dutcher, R. Wang, J. Corbetta, Y. Shoshitaishvili, C. Kruegel, G. Vigna&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://www.cs.ucsb.edu/~vigna/publications/2016_NDSS_Driller.pdf&quot;&gt;https://www.cs.ucsb.edu/~vigna/publications/2016_NDSS_Driller.pdf&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Internals of AFL fuzzer - Compile Time Instrumentation 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://tunnelshade.in/blog/2018/01/afl-internals-compile-time-instrumentation/&quot;&gt;https://tunnelshade.in/blog/2018/01/afl-internals-compile-time-instrumentation/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;WinAFL: A fork of AFL for fuzzing Windows binaries 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/googleprojectzero/winafl&quot;&gt;https://github.com/googleprojectzero/winafl&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Zoo AFL: AFL utilities and modifications 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://habr.com/en/company/dsec/blog/449134/&quot;&gt;https://habr.com/en/company/dsec/blog/449134/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Software: libFuzzer&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;libFuzzer – a library for coverage-guided fuzz testing. 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;http://llvm.org/docs/LibFuzzer.html&quot;&gt;http://llvm.org/docs/LibFuzzer.html&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://tutorial.libFuzzer.info&quot;&gt;http://tutorial.libFuzzer.info&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Deconstructing LibProtobuf/Mutator Fuzzing 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://bshastry.github.io/2019/01/18/Deconstructing-LPM.html&quot;&gt;https://bshastry.github.io/2019/01/18/Deconstructing-LPM.html&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Efficient Fuzzing Guide 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://chromium.googlesource.com/chromium/src/testing/libfuzzer/+/HEAD/efficient_fuzzing.md&quot;&gt;https://chromium.googlesource.com/chromium/src/testing/libfuzzer/+/HEAD/efficient_fuzzing.md&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Fuzzing arbitrary functions in ELF binaries using LIEF and LibFuzzer 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://blahcat.github.io/2018/03/11/fuzzing-arbitrary-functions-in-elf-binaries/&quot;&gt;https://blahcat.github.io/2018/03/11/fuzzing-arbitrary-functions-in-elf-binaries/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Introduction to using libFuzzer with llvm-toolset 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://developers.redhat.com/blog/2019/03/05/introduction-to-using-libfuzzer-with-llvm-toolset/&quot;&gt;https://developers.redhat.com/blog/2019/03/05/introduction-to-using-libfuzzer-with-llvm-toolset/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;libfuzzer-workshop 
  &lt;ul&gt; 
   &lt;li&gt;Materials of &quot;Modern fuzzing of C/C++ Projects&quot; workshop&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/Dor1s/libfuzzer-workshop&quot;&gt;https://github.com/Dor1s/libfuzzer-workshop&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;libfuzzerfication 
  &lt;ul&gt; 
   &lt;li&gt;LibFuzzerfication project uses libFuzzer for fuzzing popular applications and libraries.&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/ouspg/libfuzzerfication&quot;&gt;https://github.com/ouspg/libfuzzerfication&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;libprotobuf-mutator 
  &lt;ul&gt; 
   &lt;li&gt;a library to randomly mutate protobuffers; can be used together with guided fuzzing engines, such as libFuzzer&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/google/libprotobuf-mutator&quot;&gt;https://github.com/google/libprotobuf-mutator&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Software: Benchmarking&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;fuzzer-test-suite: Set of tests for fuzzing engines 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/google/fuzzer-test-suite&quot;&gt;https://github.com/google/fuzzer-test-suite&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;FuzzBench: Fuzzer Benchmarking as a Service 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/google/FuzzBench&quot;&gt;https://github.com/google/FuzzBench&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://security.googleblog.com/2020/03/fuzzbench-fuzzer-benchmarking-as-service.html&quot;&gt;https://security.googleblog.com/2020/03/fuzzbench-fuzzer-benchmarking-as-service.html&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://opensource.googleblog.com/2020/03/fuzzbench-fuzzer-benchmarking-as-service.html&quot;&gt;https://opensource.googleblog.com/2020/03/fuzzbench-fuzzer-benchmarking-as-service.html&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Software: OS: Linux&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;difuze: Fuzzer for Linux Kernel Drivers 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/ucsb-seclab/difuze&quot;&gt;https://github.com/ucsb-seclab/difuze&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;DIFUZE: Interface Aware Fuzzing for Kernel Drivers - CCS 2017&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://acmccs.github.io/papers/p2123-corinaA.pdf&quot;&gt;https://acmccs.github.io/papers/p2123-corinaA.pdf&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://seclist.us/difuze-fuzzer-for-linux-kernel-drivers.html&quot;&gt;http://seclist.us/difuze-fuzzer-for-linux-kernel-drivers.html&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;syzkaller: an unsupervised, coverage-guided kernel fuzzer 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/google/syzkaller&quot;&gt;https://github.com/google/syzkaller&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Coverage-guided kernel fuzzing with syzkaller - &lt;a href=&quot;https://lwn.net/Articles/677764/&quot;&gt;https://lwn.net/Articles/677764/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Software: OS: Windows&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;Sienna Locomotive: A user-friendly fuzzing and crash triage tool for Windows 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/trailofbits/sienna-locomotive&quot;&gt;https://github.com/trailofbits/sienna-locomotive&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;User-Friendly Fuzzing with Sienna Locomotive 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://blog.trailofbits.com/2019/04/08/user-friendly-fuzzing-with-sienna-locomotive/&quot;&gt;https://blog.trailofbits.com/2019/04/08/user-friendly-fuzzing-with-sienna-locomotive/&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Software: Performance&lt;/h2&gt; 
&lt;p&gt;Fuzzing applied to software performance.&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;PerfFuzz: Automatically Generate Pathological Inputs for C/C++ programs 
  &lt;ul&gt; 
   &lt;li&gt;ISSTA 2018&lt;/li&gt; 
   &lt;li&gt;Caroline Lemieux, Rohan Padhye, Koushik Sen, and Dawn Song&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/carolemieux/perffuzz&quot;&gt;https://github.com/carolemieux/perffuzz&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://people.eecs.berkeley.edu/~rohanpadhye/files/PerfFuzz-issta18.pdf&quot;&gt;https://people.eecs.berkeley.edu/~rohanpadhye/files/PerfFuzz-issta18.pdf&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;perf fuzzer: Targeted fuzzing of the perf_event_open() system call 
  &lt;ul&gt; 
   &lt;li&gt;Technical Report, University of Maine, Tech. Rep., 2015&lt;/li&gt; 
   &lt;li&gt;V. M. Weaver and D. Jones&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://web.eece.maine.edu/~vweaver/projects/perf_events/fuzzer/2015_perf_fuzzer_tr.pdf&quot;&gt;http://web.eece.maine.edu/~vweaver/projects/perf_events/fuzzer/2015_perf_fuzzer_tr.pdf&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;perf_fuzzer perf_event syscall fuzzer 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;http://web.eece.maine.edu/~vweaver/projects/perf_events/fuzzer/&quot;&gt;http://web.eece.maine.edu/~vweaver/projects/perf_events/fuzzer/&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;perf_event Validation Tests 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;http://web.eece.maine.edu/~vweaver/projects/perf_events/validation/&quot;&gt;http://web.eece.maine.edu/~vweaver/projects/perf_events/validation/&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://github.com/deater/perf_event_tests&quot;&gt;https://github.com/deater/perf_event_tests&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;SlowFuzz: Automated Domain-Independent Detection of Algorithmic Complexity Vulnerabilities 
  &lt;ul&gt; 
   &lt;li&gt;A spin on libFuzzer so as to favor inputs incurring a slowdown. The key modifications consist of changing the fitness function, to favor inputs that excercise more basic block edges, as well as introducing probabilities in the selection of mutations to be performed, so as to preserve &quot;locality&quot; of the created inputs.&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/nettrino/slowfuzz&quot;&gt;https://github.com/nettrino/slowfuzz&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;ACM CCS 2017 
    &lt;ul&gt; 
     &lt;li&gt;Theofilos Petsios, Jason Zhao, Angelos D. Keromytis, Suman Jana&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://arxiv.org/abs/1708.08437&quot;&gt;https://arxiv.org/abs/1708.08437&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=ZuWWs64UTts&quot;&gt;https://www.youtube.com/watch?v=ZuWWs64UTts&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;hr&gt; 
&lt;h1&gt;Talks&lt;/h1&gt; 
&lt;h2&gt;Talks: 2020&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;Lightning in a Bottle: 25 Years of Fuzzing 
  &lt;ul&gt; 
   &lt;li&gt;FuzzCon 2020; Richard Johnson&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://docs.google.com/presentation/d/1L3ZmbCxdkZZCCrZ1gBI5Kj32rAnNNho3rZVzQXjnCvs&quot;&gt;https://docs.google.com/presentation/d/1L3ZmbCxdkZZCCrZ1gBI5Kj32rAnNNho3rZVzQXjnCvs&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Talks: 2019&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;C++ Sanitizers and Fuzzing for the Windows Platform Using New Compilers, Visual Studio, and Azure 
  &lt;ul&gt; 
   &lt;li&gt;CppCon 2019: Jim Radigan&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=0EsqxGgYOQU&quot;&gt;https://www.youtube.com/watch?v=0EsqxGgYOQU&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/CppCon/CppCon2019/tree/master/Presentations/address_sanitizers__cloud_at_microsoft&quot;&gt;https://github.com/CppCon/CppCon2019/tree/master/Presentations/address_sanitizers__cloud_at_microsoft&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Fuzzing for developers 
  &lt;ul&gt; 
   &lt;li&gt;StockholmCpp::0x15 - Pi Day 2019; Paul Dreik&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=e_Oc9SkCo5s&quot;&gt;https://www.youtube.com/watch?v=e_Oc9SkCo5s&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Going Beyond Coverage-Guided Fuzzing with Structured Fuzzing 
  &lt;ul&gt; 
   &lt;li&gt;Black Hat 2019; Jonathan Metzman&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=S8JvzWDnjc0&quot;&gt;https://www.youtube.com/watch?v=S8JvzWDnjc0&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.blackhat.com/us-19/briefings/schedule/#going-beyond-coverage-guided-fuzzing-with-structured-fuzzing-16110&quot;&gt;https://www.blackhat.com/us-19/briefings/schedule/#going-beyond-coverage-guided-fuzzing-with-structured-fuzzing-16110&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Make your programs more reliable with Fuzzing 
  &lt;ul&gt; 
   &lt;li&gt;ACCU 2019; Marshall Clow&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=x0FQkAPokfE&quot;&gt;https://www.youtube.com/watch?v=x0FQkAPokfE&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Modern Source Fuzzing 
  &lt;ul&gt; 
   &lt;li&gt;OffensiveCon19; Ned Williamson&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=xzG0pLM4Q64&quot;&gt;https://www.youtube.com/watch?v=xzG0pLM4Q64&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Testing Legacy Code - Fuzzing for Better Input Data 
  &lt;ul&gt; 
   &lt;li&gt;Meeting C++ 2019; Tina Ulbrich, Niel Waldren&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://meetingcpp.com/mcpp/slides/2019/Testing%20Legacy%20Code%20-%20Fuzzing%20for%20Better%20Input%20Data.pdf&quot;&gt;https://meetingcpp.com/mcpp/slides/2019/Testing%20Legacy%20Code%20-%20Fuzzing%20for%20Better%20Input%20Data.pdf&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;What the Fuzz 
  &lt;ul&gt; 
   &lt;li&gt;Black Hat Europe 2019; Cornelius Aschermann and Sergej Schumilo&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=Wy7qY5ms3qY&quot;&gt;https://www.youtube.com/watch?v=Wy7qY5ms3qY&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.blackhat.com/eu-19/briefings/schedule/#what-the-fuzz-18031&quot;&gt;https://www.blackhat.com/eu-19/briefings/schedule/#what-the-fuzz-18031&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Talks: 2018&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;Adventures in Fuzzing 
  &lt;ul&gt; 
   &lt;li&gt;NYU Talk 2018; Brandon Falk&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=SngK4W4tVc0&quot;&gt;https://www.youtube.com/watch?v=SngK4W4tVc0&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/gamozolabs/adventures_in_fuzzing&quot;&gt;https://github.com/gamozolabs/adventures_in_fuzzing&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Finding security vulnerabilities with modern fuzzing techniques 
  &lt;ul&gt; 
   &lt;li&gt;RuhrSec 2018; Rene Freingruber&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=KFmeHz_vxfo&quot;&gt;https://www.youtube.com/watch?v=KFmeHz_vxfo&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Fuzzing Corpus Optimization - Moonwalking with Moonbeams 
  &lt;ul&gt; 
   &lt;li&gt;CSides Canberra 2018; Shane Magrath&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/DSTCyber/presentations/tree/master/2018-fuzzing-corpus-distillation&quot;&gt;https://github.com/DSTCyber/presentations/tree/master/2018-fuzzing-corpus-distillation&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://gitlab.anu.edu.au/lunar/moonlight&quot;&gt;https://gitlab.anu.edu.au/lunar/moonlight&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Fuzzing with AFL 
  &lt;ul&gt; 
   &lt;li&gt;NDC TechTown 2018; Erlend Oftedal&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=DFQT1YxvpDo&quot;&gt;https://www.youtube.com/watch?v=DFQT1YxvpDo&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://vimeo.com/292689978&quot;&gt;https://vimeo.com/292689978&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Making Your Library More Reliable with Fuzzing 
  &lt;ul&gt; 
   &lt;li&gt;C++Now 2018; Marshall Clow&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=LlLJRHToyUk&quot;&gt;https://www.youtube.com/watch?v=LlLJRHToyUk&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/boostcon/cppnow_presentations_2018/blob/master/05-10-2018_thursday/making_your_library_more_reliable_with_fuzzing__marshall_clow__cppnow_05182018.pdf&quot;&gt;https://github.com/boostcon/cppnow_presentations_2018/blob/master/05-10-2018_thursday/making_your_library_more_reliable_with_fuzzing__marshall_clow__cppnow_05182018.pdf&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Seems Exploitable: Exposing Hidden Exploitable Behaviors Using Extended Differential Fuzzing 
  &lt;ul&gt; 
   &lt;li&gt;HITB2018AMS; Fernando Arnaboldi&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://conference.hitb.org/hitbsecconf2018ams/sessions/seems-exploitable-exposing-hidden-exploitable-behaviors-using-extended-differential-fuzzing/&quot;&gt;https://conference.hitb.org/hitbsecconf2018ams/sessions/seems-exploitable-exposing-hidden-exploitable-behaviors-using-extended-differential-fuzzing/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Structure aware fuzzing 
  &lt;ul&gt; 
   &lt;li&gt;Meeting C++ 2018; Réka Kovács&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=wTWNmOSKfD4&quot;&gt;https://www.youtube.com/watch?v=wTWNmOSKfD4&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://meetingcpp.com/mcpp/slides/2018/Structured%20fuzzing.pdf&quot;&gt;https://meetingcpp.com/mcpp/slides/2018/Structured%20fuzzing.pdf&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Want more stable kernel? Fuzz it! 
  &lt;ul&gt; 
   &lt;li&gt;DevConf.cz 2018; Hangbin Liu&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=XlPQpVlC37A&quot;&gt;https://www.youtube.com/watch?v=XlPQpVlC37A&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Talks: 2017&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;Between Testing and Formal Verification 
  &lt;ul&gt; 
   &lt;li&gt;SecAppDev, March 2017; Jan Tobias Mühlberg&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://handouts.secappdev.org/handouts/2017/Jan%20Tobias%20Muehlberg/201705-secappdev-muehlberg.pdf&quot;&gt;https://handouts.secappdev.org/handouts/2017/Jan%20Tobias%20Muehlberg/201705-secappdev-muehlberg.pdf&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=tjkLPErCFW0&quot;&gt;https://www.youtube.com/watch?v=tjkLPErCFW0&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/verifast/verifast&quot;&gt;https://github.com/verifast/verifast&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Finding Security Vulnerabilities by Fuzzing and Dynamic Code Analysis 
  &lt;ul&gt; 
   &lt;li&gt;Verification Futures 2017; Richard Storer&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://www.testandverification.com/wp-content/uploads/2017/Verification_Futures/Richard_Storer_MathEmbedded.pdf&quot;&gt;http://www.testandverification.com/wp-content/uploads/2017/Verification_Futures/Richard_Storer_MathEmbedded.pdf&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=vCLLA7C5Afg&quot;&gt;https://www.youtube.com/watch?v=vCLLA7C5Afg&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Fuzz or lose: why and how to make fuzzing a standard practice for C++ 
  &lt;ul&gt; 
   &lt;li&gt;CppCon 2017; Kostya Serebryany&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=k-Cv8Q3zWNQ&quot;&gt;https://www.youtube.com/watch?v=k-Cv8Q3zWNQ&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Fuzz Testing 
  &lt;ul&gt; 
   &lt;li&gt;C++ Weekly 85; Jason Turner&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=gO0KBoqkOoU&quot;&gt;https://www.youtube.com/watch?v=gO0KBoqkOoU&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Fuzzing with AFL 
  &lt;ul&gt; 
   &lt;li&gt;Circle City Con 2017; Adam DC949&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://www.irongeek.com/i.php?page=videos/circlecitycon2017/106-fuzzing-with-afl-adam-dc949&quot;&gt;http://www.irongeek.com/i.php?page=videos/circlecitycon2017/106-fuzzing-with-afl-adam-dc949&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Modern Fuzzing of Media-Processing Projects 
  &lt;ul&gt; 
   &lt;li&gt;FOSDEM 2017; Max Moroz&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://archive.fosdem.org/2017/schedule/event/om_fuzzing/&quot;&gt;https://archive.fosdem.org/2017/schedule/event/om_fuzzing/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=QQs82BdoA9c&quot;&gt;https://www.youtube.com/watch?v=QQs82BdoA9c&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Talks: 2016&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;Effective File Format Fuzzing – Thoughts, Techniques and Results 
  &lt;ul&gt; 
   &lt;li&gt;Black Hat Europe 2016; Mateusz Jurczyk&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=qTTwqFRD1H8&quot;&gt;https://www.youtube.com/watch?v=qTTwqFRD1H8&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.blackhat.com/eu-16/briefings/schedule/#effective-file-format-fuzzing--thoughts-techniques-and-results-4879&quot;&gt;https://www.blackhat.com/eu-16/briefings/schedule/#effective-file-format-fuzzing--thoughts-techniques-and-results-4879&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://j00ru.vexillium.org/talks/blackhat-eu-effective-file-format-fuzzing-thoughts-techniques-and-results/&quot;&gt;https://j00ru.vexillium.org/talks/blackhat-eu-effective-file-format-fuzzing-thoughts-techniques-and-results/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.blackhat.com/docs/eu-16/materials/eu-16-Jurczyk-Effective-File-Format-Fuzzing-Thoughts-Techniques-And-Results.pdf&quot;&gt;https://www.blackhat.com/docs/eu-16/materials/eu-16-Jurczyk-Effective-File-Format-Fuzzing-Thoughts-Techniques-And-Results.pdf&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Fuzz Smarter Not Harder: An afl fuzz Primer 
  &lt;ul&gt; 
   &lt;li&gt;BSides San Francisco 2016; Craig Young&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=29RbO5bftwo&quot;&gt;https://www.youtube.com/watch?v=29RbO5bftwo&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;The Smart Fuzzer Revolution 
  &lt;ul&gt; 
   &lt;li&gt;BSides Lisbon 2016; Dan Guido&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=g1E2Ce5cBhI&quot;&gt;https://www.youtube.com/watch?v=g1E2Ce5cBhI&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Talks: 2015&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;Automated Software Testing for the 21st Century 
  &lt;ul&gt; 
   &lt;li&gt;TCE 2015; Patrice Godefroid&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://patricegodefroid.github.io/public_psfiles/talk-tce2015.pdf&quot;&gt;https://patricegodefroid.github.io/public_psfiles/talk-tce2015.pdf&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=HbIrWdjbX8Y&quot;&gt;https://www.youtube.com/watch?v=HbIrWdjbX8Y&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Talks: 2007&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;Revolutionizing the Field of Grey-box Attack Surface Testing with Evolutionary Fuzzing 
  &lt;ul&gt; 
   &lt;li&gt;DEFCON 2007; Jared DeMott, Richard Enbody, William Punch&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://www.blackhat.com/presentations/bh-usa-07/DeMott_Enbody_and_Punch/Presentation/bh-usa-07-demott_enbody_and_punch.pdf&quot;&gt;http://www.blackhat.com/presentations/bh-usa-07/DeMott_Enbody_and_Punch/Presentation/bh-usa-07-demott_enbody_and_punch.pdf&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.blackhat.com/presentations/bh-usa-07/DeMott_Enbody_and_Punch/Whitepaper/bh-usa-07-demott_enbody_and_punch-WP.pdf&quot;&gt;https://www.blackhat.com/presentations/bh-usa-07/DeMott_Enbody_and_Punch/Whitepaper/bh-usa-07-demott_enbody_and_punch-WP.pdf&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.vdalabs.com/tools/EFS.pdf&quot;&gt;https://www.vdalabs.com/tools/EFS.pdf&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=g7uFJnbvjNg&quot;&gt;https://www.youtube.com/watch?v=g7uFJnbvjNg&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=G7sX7RhJ_2w&quot;&gt;https://www.youtube.com/watch?v=G7sX7RhJ_2w&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>History pieces (from the tech industry)</title>
      <link>https://tedneward.github.io/Research/reading/development/history-pieces/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">reading/development/history-pieces/index.html</guid>
      	<description>
	&lt;p&gt;Databases: A Year in Review &lt;a href=&quot;https://www.cs.cmu.edu/~pavlo/blog/2025/01/2024-databases-retrospective.html&quot;&gt;2024&lt;/a&gt; &lt;a href=&quot;https://www.cs.cmu.edu/~pavlo/blog/2024/01/2023-databases-retrospective.html&quot;&gt;2023&lt;/a&gt; &lt;a href=&quot;https://www.cs.cmu.edu/~pavlo/blog/2022/12/2022-databases-retrospective.html&quot;&gt;2022&lt;/a&gt; &lt;a href=&quot;https://www.cs.cmu.edu/~pavlo/blog/2021/12/2021-databases-retrospective.html&quot;&gt;2021&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;State of WebAssembly &lt;a href=&quot;https://platform.uno/blog/state-of-webassembly-2024-2025/&quot;&gt;2024 and 2025&lt;/a&gt; &lt;a href=&quot;https://platform.uno/blog/state-of-webassembly-2023-2024/&quot;&gt;2023 and 2024&lt;/a&gt; &lt;a href=&quot;https://platform.uno/blog/the-state-of-webassembly-2022-and-2023/&quot;&gt;2022 and 2023&lt;/a&gt; &lt;a href=&quot;https://platform.uno/blog/the-state-of-webassembly-2021-and-2022/&quot;&gt;2021 and 2022&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Low-Code/No-Code reading</title>
      <link>https://tedneward.github.io/Research/reading/development/low-code-no-code/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">reading/development/low-code-no-code/index.html</guid>
      	<description>
	&lt;h1&gt;What is Low-Code?&lt;/h1&gt; 
&lt;p&gt;Low-code development platforms focus on ease-of-use and a visual app building approach so business professionals can utilize them for creating their own solutions. This means that those closest to business problems can be empowered to quickly turn ideas into action, with point-and-click simplicity.&lt;/p&gt; 
&lt;h3&gt;What are the benefits?&lt;/h3&gt; 
&lt;p&gt;In today’s fast pace world where every business is a digital business, application development is becoming a core competency of every company. Businesses need to stay ahead of increased competition, keep pace with customer demands and find new ways to grow. Low-code is an approach to addressing these challenges.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Maximize the effectiveness&lt;/strong&gt; of every employee by delivering real-time, actionable insights across systems in in a highly personalized manner&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Improve speed and agility&lt;/strong&gt; by making it easy for everyone to continuously innovate in an application ecosystem on a single platform&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Reduce IT complexity &amp;amp; costs&lt;/strong&gt; by eliminating traditional IT development burdens, bolstering security and standardizing governance on one platform rather than across many applications&lt;/p&gt; 
&lt;h3&gt;What is the difference between low-code and no-code?&lt;/h3&gt; 
&lt;p&gt;Low-code is a well-defined category of application development platforms designed to make application developers faster and more productive. No-code is more like a feature of low-code where visual techniques are used to develop parts, or the whole, of an application.&lt;/p&gt; 
&lt;p&gt;Gartner views “no-code” application platforms as part of the Low Code Application Platform (LCAP) market. Gartner calls “no-code” a marketing and positioning statement, implying that the platform requires text entry only for formulas or simple expressions, with all other aspects of development being enabled by visual modeling or configuration. Gartner’s LCAP market definition includes such no-code platforms.&lt;/p&gt; 
&lt;p&gt;Whether you call it low-code or no-code, the most important factor is what skill set is needed to build applications with the platform. Forrester divides the market of low-code platforms into two parts: those designed for “business developers” and those designed for “professional IT developers.”&lt;/p&gt; 
&lt;h3&gt;Why do businesses need to use low-code to stay ahead?&lt;/h3&gt; 
&lt;p&gt;&lt;strong&gt;Improved agility:&lt;/strong&gt; Because they’re visual in nature, creating apps with low-code allows for a more agile, effective process.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Decreased costs:&lt;/strong&gt; Building apps and programs in less time saves companies a lot of money. It reduces the need for more developers—saving money on labor and employment. And, because of its ability to make nearly every task more efficient, entire organizations become more productive—increased productivity = more money.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Better customer experience:&lt;/strong&gt; Low-code innovation is fast and effective, allowing companies to keep pace with the changing landscape of customer wants and need. Happier customers means loyal customers, and loyal customers create profit for life.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Tech talent gap:&lt;/strong&gt; As the tech talent gap widens, low-code allows businesses to begin closing the gap without spending crazy amounts of money.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Decreased development time:&lt;/strong&gt; On average, users can minimize the development period of apps by 10 times (compared to traditional methods), bringing products to market faster.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Automation:&lt;/strong&gt; Like everything else in business and life, automation keeps things simple and ensures most hiccups are avoided. Low-code has operational features that can accelerate the development of the products and empower business experts who know the silos of data and process start to build-up.&lt;/p&gt; 
&lt;h1&gt;Manifesto&lt;/h1&gt; 
&lt;p&gt;Technology, and the role it plays in the business landscape, is an ever-evolving juggernaut. Core systems and business challenges are progressively complex. The pace of that evolution increases exponentially — what is fast right now will be glacial in hindsight.&lt;/p&gt; 
&lt;p&gt;To keep up, you must build and deploy innovative, timely solutions. We believe that building solutions with low-code makes that possible. We believe software should be built well. We believe it should deliver business value. We believe it should be delivered at speed.&lt;/p&gt; 
&lt;p&gt;To make this happen at scale we adhere to these Application Development Pillars:&lt;/p&gt; 
&lt;h3&gt;Focus on business impact&lt;/h3&gt; 
&lt;p&gt;Create alignment, achieve clarity, succeed quickly.&lt;/p&gt; 
&lt;h3&gt;No brain power goes to waste&lt;/h3&gt; 
&lt;p&gt;Unleash all the makers from across the enterprise.&lt;/p&gt; 
&lt;h3&gt;Do everything with an agile attitude&lt;/h3&gt; 
&lt;p&gt;Empower small teams, build for the cloud, deploy swiftly and often.&lt;/p&gt; 
&lt;h3&gt;Assemble from existing business capabilities&lt;/h3&gt; 
&lt;p&gt;Utilize established assets, don’t default to building from scratch.&lt;/p&gt; 
&lt;h3&gt;Connect everything and everybody&lt;/h3&gt; 
&lt;p&gt;APIs, integrations, new ways to access data — be open and accessible.&lt;/p&gt; 
&lt;p&gt;We know low-code is capable of building valuable solutions at speed, but as with any tool, it needs to be used correctly to get the best results.&lt;/p&gt; 
&lt;h1&gt;9 Principles&lt;/h1&gt; 
&lt;p&gt;We defined the following 9 Principles of Low-Code Application Developmentto empower makers from the enterprise to the dorm room to build software that makes a difference. The less we push ourselves into this, the greater value it will have for all our audiences — prospects, customers, the media, potential employees.&lt;/p&gt; 
&lt;h3&gt;Model-Driven Development&lt;/h3&gt; 
&lt;p&gt;Transform ideas into applications that deliver business value through abstraction, automation, and openness.&lt;/p&gt; 
&lt;h3&gt;Collaboration&lt;/h3&gt; 
&lt;p&gt;Leverage a shared visual language to support the interchange of knowledge and ideas between business domain experts and developers.&lt;/p&gt; 
&lt;h3&gt;Agility&lt;/h3&gt; 
&lt;p&gt;Manage the full enterprise application development lifecycle with agile workstreams to eliminate bottlenecks, support iterative delivery and achieve shortest time-to-value.&lt;/p&gt; 
&lt;h3&gt;The Cloud&lt;/h3&gt; 
&lt;p&gt;Cloud enables the ease and speed of application deployment that customers demand.&lt;/p&gt; 
&lt;h3&gt;Openness&lt;/h3&gt; 
&lt;p&gt;Anything can be integrated with an agnostic enterprise application development platform – this removes limitations on what can be built.&lt;/p&gt; 
&lt;h3&gt;Multi-User Development&lt;/h3&gt; 
&lt;p&gt;Multiple developers should be able to work on an application at the same time. The platform must support and synchronize their work streams.&lt;/p&gt; 
&lt;h3&gt;Experimentation &amp;amp; Innovation&lt;/h3&gt; 
&lt;p&gt;Development tools need to be affordable and nimble so innovators everywhere can experiment, explore, and create.&lt;/p&gt; 
&lt;h3&gt;Governance &amp;amp; Control&lt;/h3&gt; 
&lt;p&gt;Robust governance and control processes and protocols are essential.&lt;/p&gt; 
&lt;h3&gt;Community&lt;/h3&gt; 
&lt;p&gt;A platform without a community is no platform at all.&lt;/p&gt; 
&lt;p&gt;&lt;em&gt;(Source: &lt;a href=&quot;https://www.mendix.com/low-code-guide/the-low-code-manifesto/&quot;&gt;Medix&lt;/a&gt;)&lt;/em&gt; | &lt;em&gt;(Source: &lt;a href=&quot;https://www.creatio.com/page/low-code&quot;&gt;Creatio&lt;/a&gt;)&lt;/em&gt;&lt;/p&gt; 
&lt;h1&gt;Reasons to go low-code&lt;/h1&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;strong&gt;Legacy systems are outdated&lt;/strong&gt;: These systems can no longer support the needs of businesses to quickly innovate and transform to stay competitive&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Traditional platforms and point solutions have limits&lt;/strong&gt;: These solutions are limiting businesses to the processes they support and don&apos;t reach the processes that make them unique&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Shortage of software developers&lt;/strong&gt;: There will never be enough developers to support the pace of innovation required to stay ahead&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Maintain a competitive advantage&lt;/strong&gt;: Stay ahead of increased competition by driving rapid innovation on what makes you competitively unique&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Customer satisfaction&lt;/strong&gt;: Keep pace with customer demands by continually perfecting the processes that deliver exceptional customer experiences&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Innovation at the edge&lt;/strong&gt;: Enable new ways to grow by enabling completely new operating models that serve customers in new and better ways&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Win the talent war&lt;/strong&gt;: Attract employees with a culture of continuous improvement and opportunities to learn and apply new technical skills&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;&lt;em&gt;(Source: &lt;a href=&quot;https://www.quickbase.com/business-application-platform/what-is-low-code&quot;&gt;Quickbase&lt;/a&gt;)&lt;/em&gt;&lt;/p&gt; 
&lt;h1&gt;&lt;a href=&quot;https://www.quickbase.com/blog/a-brief-history-of-low-code-development-platforms&quot;&gt;A Brief History of Low-Code Development Platforms&lt;/a&gt;&lt;/h1&gt; 
&lt;p&gt;1982: James Martin published &lt;em&gt;Application Development Without Programmers&lt;/em&gt;. “The number of programmers available per computer is shrinking so fast that most computers in the future must be put to work at least in part without programmers.&quot; Led to 4GLs, CASE tools, and RAD tools.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Why These Failed:&lt;/strong&gt;&lt;/p&gt; 
&lt;ol&gt; 
 &lt;li&gt;&lt;strong&gt;They promised more than they could deliver.&lt;/strong&gt; IT managers felt burned by unrealistic expectations sold to them by consultants and vendors. While 4GL and visual programming technologies offered a glimpse of a better world for IT and the business, the tools themselves simply could not live up to the hype. Building applications that would scale was particularly difficult.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;The tools did not support best practices.&lt;/strong&gt; Version control, testing, deployment, documentation, and other development best practices did not exist for most tools, and had to be performed manually.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;They amplified security risks.&lt;/strong&gt; Empowering non-technical people to build these original stand-alone software apps (even with the assistance of new tools) exposed the organization to several risks — chief among them that most non-technical builders did not possess the skillset to create and deploy applications with appropriate security and governance.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;The internet swallowed everything.&lt;/strong&gt; By the mid 2000s, a significant portion of software development was already focused on web applications, as more business sought to enable better worker productivity by delivering business applications via the cloud rather than on traditional server environments. This offset some of the need for traditional IT solutions for everyday problems.&lt;/li&gt; 
&lt;/ol&gt; 
&lt;p&gt;&lt;strong&gt;Why would these new platforms succeed where others have failed?&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;The answer is in the platform. Rather than offering an interface that simply obscures the actual code generating an application, the new generation of low-code platformsare self-contained (yet extensible) platforms that enable people to build within an environment that’s already hospitable to all the unseen components of the application. In fact, most modern low-code platforms are delivered via the web, meaning users don’t have to worry about any updates at all.&lt;/p&gt; 
&lt;p&gt;The cloud platform approach also empowers these tools to provide far more security and reliability than ever — making it much easier for organizations to deploy with confidence that they have the right controls in place to meet their security and compliance standards. If the platform itself offers high-level security and compliance controls, the path to deploying platform applicationssecurely is much shorter.&lt;/p&gt; 
&lt;p&gt;Finally, the user base for these platforms has matured significantly in the last decade with the world’s most successful companies utilizing low-code platforms to power their unique processes.This has given rise to best practices, a thriving ecosystem of partners and low-code builders, and a better understanding overall of the capabilities of each platform.&lt;/p&gt; 
&lt;h1&gt;&lt;a href=&quot;https://www.quickbase.com/blog/the-future-of-low-code-platforms&quot;&gt;The Future of Low-Code Platforms&lt;/a&gt;&lt;/h1&gt; 
&lt;p&gt;&lt;strong&gt;No-code beats low-code in the long run&lt;/strong&gt;&lt;br&gt; Recently Forrester named Quick Base a Leader in its New Wave: Low-code Development Platforms for Business Developers. Forrester also issued a separate report focused on Low-code Development Platforms for AD&amp;amp;D Pros. We think Forrester’s decision to define two separate markets — one aimed at non-technical business developers (sometimes called “no-code platforms”) and one aimed at professional developers working in IT — calls attention to fundamental differences in the ways low-code and no-code platforms can be deployed.&lt;/p&gt; 
&lt;p&gt;Whereas low-code platforms for professional developers are designed to help professional developers build solutions faster (and therefore serve more business requests), no-code platforms are designed to offload much or all of the responsibility of developing and delivering apps to the business developers themselves.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Natural Language Processing for Semantic Search</title>
      <link>https://tedneward.github.io/Research/reading/development/nlp-for-semantic-search/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">reading/development/nlp-for-semantic-search/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.pinecone.io/learn/nlp/&quot;&gt;Website&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Book in progress.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Fuzzy logic</title>
      <link>https://tedneward.github.io/Research/reading/development/fuzzy-logic/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">reading/development/fuzzy-logic/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.spiceworks.com/tech/devops/articles/fuzzy-logic/amp/&quot;&gt;What is Fuzzy Logic? Definition, Working, Pros and Cons&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Software reading</title>
      <link>https://tedneward.github.io/Research/reading/development/index/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">reading/development/index/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://cses.fi/book/book.pdf&quot;&gt;Competitive Programmer&apos;s Handbook&lt;/a&gt; (Not sure where else this belongs.)&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://github.com/ossu/computer-science&quot;&gt;Computer Science Education&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://www.reforge.com/blog/technical-decision-making&quot;&gt;Why Engineers Should Invest in Decision Making Skills Early&lt;/a&gt;: &quot;... to make more successful technical calls and advance careers, engineers actually need to develop better strategic decision-making skills — not just technical execution skills. In fact, an over-reliance on technical execution skills early in a career leads to untapped impact and stalled growth opportunities down the road.&quot;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://terrycrowley.medium.com/education-of-a-programmer-aaecf2d35312&quot;&gt;&quot;Education of a Programmer&quot;&lt;/a&gt;: &quot;When I left Microsoft in October 2016 after almost 21 years there and almost 35 years in the industry, I took some time to reflect on what I had learned over all those years. This is a lightly edited version of that post.&quot;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://alexewerlof.medium.com/my-guiding-principles-after-20-years-of-programming-a087dc55596c&quot;&gt;&quot;My guiding principles after 20 years of programming&quot;&lt;/a&gt;:&lt;br&gt; 1. Don’t fight the tools: libraries, language, platform, etc. Use as much native constructs as possible. Don’t bend the technology, but don’t bend the problem either. Pick the right tool for the job or you’ll have to find the right job for the tool you got.&lt;br&gt; 2. You don’t write the code for the machines, you write it for your colleagues and your future self (unless it’s a throw away project or you’re writing assembly). Write it for the junior ones as a reference.&lt;br&gt; 3. Any significant and rewarding piece of software is the result of collaboration. Communicate effectively and collaborate openly. Trust others and earn their trust. Respect people more than code. Lead by example. Convert your followers to leaders.&lt;br&gt; 4. Divide and conquer. Write isolated modules with separate concerns which are loosely coupled. Test each part separately and together. Keep the tests close to reality but test the edge cases too.&lt;br&gt; 5. Deprecate yourself. Don’t be the go-to person for the code. Optimize it for people to find their way fixing bugs and adding features to the code. Free yourself to move on to the next project/company. Don’t own the code or you’ll never grow beyond that.&lt;br&gt; 6. Security comes in layers: each layer needs to be assessed individually but also in relation to the whole. Risk is a business decision and has direct relation to vulnerability and probability. Each product/organization has a different risk appetite (the risk they are willing to take for a bigger win). Often these 3 concerns fight with each other: UX, Security, Performance.&lt;br&gt; 7. Realize that every code has a life cycle and will die. Sometimes it dies in its infancy before seeing the light of production. Be OK with letting go. Know the difference between 4 categories of features and where to put your time and energy:&lt;br&gt; * Core: like an engine in a car. The product is meaningless without it.&lt;br&gt; * Necessary: like a car’s spare wheel. It’s rarely used but when needed, its function decides the success of the system.&lt;br&gt; * Added value: like a car’s cup-holder. It’s nice to have but the product is perfectly usable without it.&lt;br&gt; * Unique Selling Point: the main reason people should buy your product instead of your rivals. For example, your car is the best off-road vehicle.&lt;br&gt; 8. Don’t attach your identity to your code. Don’t attach anyone’s identity to their code. Realize that people are separate from the artifacts they produce. Don’t take code criticism personally but be very careful when criticizing others’ code.&lt;br&gt; 9. Tech debt is like fast food. Occasionally it’s acceptable but if you get used to it, it’ll kill the product faster than you think (and in a painful way).&lt;br&gt; 10. When making decisions about the solution all things equal, go for this priority: &lt;strong&gt;Security &amp;gt; Reliability &amp;gt; Usability (Accessibility &amp;amp; UX) &amp;gt; Maintainability &amp;gt; Simplicity (Developer experience/DX) &amp;gt; Brevity (code length) &amp;gt; Finance &amp;gt; Performance&lt;/strong&gt; But don’t follow that blindly because it is dependent on the nature of the product. Like any career, the more experience you earn, the more you can find the right balance for each given situation. For example, when designing a game engine, performance has the highest priority, but when creating a banking app, security is the most important factor.&lt;br&gt; 11. Bugs’ genitals are called copy &amp;amp; paste. That’s how they reproduce. Always read what you copy, always audit what you import. Bugs take shelter in complexity. “Magic” is fine in my dependency but not in my code.&lt;br&gt; 12. Don’t only write code for the happy scenario. Write good errors that answer why it happened, how it was detected and what can be done to resolve it. Validate all system input (including user input): fail early but recover from errors whenever possible. Assume the user hold a gun: put enough effort into your errors to convince them to shoot something other than your head!&lt;br&gt; 13. Don’t use dependencies unless the cost of importing, maintaining, dealing with their edge cases/bugs and refactoring when they don’t satisfy the needs is significantly less than the code that you own.&lt;br&gt; 14. Stay clear from hype-driven development. But learn all you can. Always have pet projects.&lt;br&gt; 15. Get out of your comfort zone. Learn every day. Teach what you learn. If you’re the master, you’re not learning. Expose yourself to other languages, technologies, culture and stay curious.&lt;br&gt; 16. Good code doesn’t need documentation, great code is well documented so that anyone who hasn’t been part of the evolution, trial &amp;amp; error process and requirements that led to the current status can be productive with it. An undocumented feature is a non-existing feature. A non-existing feature shouldn’t have code.&lt;br&gt; 17. Avoid overriding, inheritance and implicit smartness as much as possible. Write pure functions. They are easier to test and reason about. Any function that’s not pure should be a class. Any code construct that has a different function, should have a different name.&lt;br&gt; 18. Never start coding (making a solution) unless you fully understand the problem. It’s very normal to spend more time listening and reading than typing code. Understand the domain before starting to code. A problem is like a maze. You need to progressively go through the code-test-improve cycle and explore the problem space till you reach the end.&lt;br&gt; 19. Don’t solve a problem that doesn’t exist. Don’t do speculative programming. Only make the code extensible if it is a validated assumption that it’ll be extended. Chances are by the time it gets extended, the problem definition looks different from when you wrote the code. Don’t overengineer: focus on solving the problem at hand and an effective solution implemented in an efficient manner.&lt;br&gt; 20. Software is more fun when it’s made together. Build a sustainable community. Listen. Inspire. Learn. Share.&lt;/p&gt; 
&lt;p&gt;&quot;Junior engineer: Take this tightly defined feature &amp;amp; build it&lt;br&gt; Mid-level engineer: Take this vaguely defined feature &amp;amp; build it&lt;br&gt; Senior engineer: Take this known problem &amp;amp; figure out how to solve it&lt;br&gt; Staff engineer: Take this goal &amp;amp; find the problems we should be solving.&quot; --&lt;a href=&quot;https://twitter.com/ZainRzv/status/1502550200396750851&quot;&gt;@ZainRzv&lt;/a&gt;&lt;/p&gt; 
&lt;hr&gt; 
&lt;p&gt;&lt;a href=&quot;https://kellanem.com/notes/new-tech&quot;&gt;&quot;Questions for a new technology.&quot;&lt;/a&gt;:&lt;/p&gt; 
&lt;ol&gt; 
 &lt;li&gt; &lt;p&gt;What problem are we trying to solve? (Tech should never be introduced as an end to itself)&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;How could we solve the problem with our current tech stack? (If the answer is we can’t, then we probably haven’t thought about the problem deeply enough)&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Are we clear on what new costs we are taking on with the new technology? (monitoring, training, cognitive load, etc)&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;What about our current stack makes solving this problem in a cost-effective manner (in terms of money, people or time) difficult?&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;If this new tech is a replacement for something we currently do, are we committed to moving everything to this new technology in the future? Or are we proliferating multiple solutions to the same problem? (aka “Will this solution kill and eat the solution that it replaces?”)&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Who do we know and trust who uses this tech? Have we talked to them about it? What did they say about it? What don’t they like about it? (if they don’t hate it, they haven’t used it in depth yet)&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;What’s a low risk way to get started?&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Have you gotten a mixed discipline group of senior folks together and thrashed out each of the above points? Where is that documented?&lt;/p&gt; &lt;/li&gt; 
&lt;/ol&gt;
	</description>
    </item>
    <item>
      <title>Memory Management and Garbage Collection (reading and references)</title>
      <link>https://tedneward.github.io/Research/reading/development/memory-management/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">reading/development/memory-management/index.html</guid>
      	<description>
	&lt;p&gt;Primary reading: &lt;a href=&quot;https://gchandbook.org/&quot;&gt;&lt;em&gt;Garbage Collection Handbook&lt;/em&gt;&lt;/a&gt;, &lt;a href=&quot;https://www.cs.kent.ac.uk/people/staff/rej/gcbook/&quot;&gt;&lt;em&gt;Garbage Collection&lt;/em&gt;&lt;/a&gt; | &lt;a href=&quot;https://www.iecc.com/gclist/GC-faq.html&quot;&gt;GC FAQ&lt;/a&gt;, &lt;a href=&quot;https://www.iecc.com/gclist/GC-algorithms.html&quot;&gt;GC Techniques and algorithms&lt;/a&gt;, &lt;a href=&quot;https://www.iecc.com/gclist/GC-lang.html&quot;&gt;GC Language Interfaces&lt;/a&gt;, and &lt;a href=&quot;https://www.iecc.com/gclist/GC-harder.html&quot;&gt;&quot;more difficult topics&quot;&lt;/a&gt; | &lt;a href=&quot;http://www.memorymanagement.org/&quot;&gt;Ravenbrook Memory Management Reference&lt;/a&gt;&lt;/p&gt; 
&lt;h2&gt;Concepts/terminology&lt;/h2&gt; 
&lt;h3&gt;Memory&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://people.freebsd.org/~lstewart/articles/cpumemory.pdf&quot;&gt;What Every Programmer Should Know About Memory&lt;/a&gt; (&lt;a href=&quot;/reading/development/cpumemory.pdf&quot;&gt;PDF&lt;/a&gt;): &quot;As CPU cores become both faster and more numerous, the limiting factor for most programs is now, and will be for some time, memory access. Hardware designers have come up with ever more sophisticated memory handling and acceleration techniques–such as CPU caches–but these cannot work optimally without some help from the programmer. Unfortunately, neither the structure nor the cost of using the memory subsystem of a computer or the caches on CPUs is well understood by most programmers. This paper explains the structure of memory subsystems in use on modern commodity hardware, illustrating why CPU caches were developed, how they work, and what programs should do to achieve optimal performance by utilizing them.&quot;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Memory Allocation schemes (high-level)&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Static&lt;/strong&gt;: The compiler, at the time of compilation (or the program&apos;s startup, either approach can work) has knowledge of the desired allocations, and creates space for them out of somewhere in the process&apos; available space. These locations are fixed throughout the lifetime of the program, and cannot be expanded or shrunk--they are literally static throughout the entirety of the application&apos;s life. This is how C/C++ handle &lt;code&gt;static&lt;/code&gt;-modified variable declarations, for example. Most C/C++ globals fall into this category.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Stack&lt;/strong&gt;: The stack is a region of RAM that gets created on every thread that your application is running on. It works in a LIFO (Last In, First Out) manner, meaning that as soon as you allocate – or “push” – memory on to the stack, that chunk of memory will be the first to be deallocated – or “popped.” Every time a function declares a new variable, it is “pushed” onto the stack, and after that variable falls out of scope (such as when the function closes), that variable will be deallocated from the stack automatically. Once a stack variable is freed, that region of memory becomes available for other stack variables.&lt;/p&gt; &lt;p&gt;Due to the pushing and popping nature of the stack, memory management is very logical and is able to be handled completely by the CPU; this makes it very quick, especially since each byte in the stack tends to be reused very frequently which means it tends to be mapped to the processor’s cache. However, there are some cons to this form of strict management. The size of the stack is a fixed value, and allocating more onto the stack than it can hold will result in a stack overflow. The size of the stack is decided when the thread is created, and each variable has a maximum size that it can occupy based on its data type; this prevents certain variables such as integers from ever growing beyond a certain value, and forces more complex data types such as arrays to specify their size prior to runtime since the stack won’t let them be resized. Variables allocated on the stack also are always local in nature because they are always next in line to be popped (unless more variables are pushed prior to the popping of earlier variables).&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Heap&lt;/strong&gt;: The heap is a memory set aside for runtime/dynamic memory allocation. Allocation is handled at runtime, and therefore is up to the program to determine structure, means, etc. Once you allocate space, that space can be accessed at any point in time not only throughout just the thread, but throughout the application’s entire life. Deallocation must occur at some point, if the space is to be reused. Most operating systems will, once an application ends, reclaim that space. (Usually by tearing down the process entirely--we&apos;re long past the days where programs are obtaining exclusive access to physical addresses.)&lt;/p&gt; &lt;p&gt;Interaction with the heap is usually through some form of reference; in languages that support direct access, these are ‘pointers,’ which are variables whose values are the address of another variable, such as a memory location. By creating a pointer, you ‘point’ at a memory location on the heap, which is what signifies the initial location of your variable and tells the program where to access the value. Due to the dynamic nature of the heap, it is completely unmanaged by the CPU aside from initial allocation and heap resizing; in non-garbage collected languages such as C and C++, this requires you as the developer to manage memory and to manually free memory locations when they are no longer needed. Failing to do so can create memory leaks and cause memory to become fragmented, which will cause reads from the heap to take longer and makes it difficult to continuously allocate more memory onto the heap.&lt;/p&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Heap management (aka garbage collection) strategies&lt;/h3&gt; 
&lt;p&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Tracing_garbage_collection&quot;&gt;Wikipedia: Tracing garbage collection&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Automated memory management (GC) almost always refers to heap management; I&apos;ve never heard it applied to any other (static or stack) form of memory allocation and reclamation. Several strategies are possible (and numerous hybrid approaches):&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Allocate without reclamation&lt;/strong&gt;: Technically, this is a legal automatic memory management technique, though obviously it is optimized more for performance of allocation and reclamation (i.e., zero time spent reclamation) than longevity. The JVM has one such allocator, called the Epsilon GC, and is typically used for specific purposes (such as benchmarking or diagnostics).&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Compile-time&lt;/strong&gt;: Compile-time garbage collection is a form of static analysis allowing memory to be reused and reclaimed based on invariants known during compilation.&lt;/p&gt; &lt;p&gt;This form of garbage collection has been studied in the Mercury programming language, and it saw greater usage with the introduction of LLVM&apos;s automatic reference counter (ARC) into Apple&apos;s ecosystem (iOS and OS X) in 2011.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Reference counting&lt;/strong&gt;: Each allocated object has a count associated with it indicating how many references are currently pointing to it. When the reference count drops to zero, the object is eligible for reclamation. Reference counts can either be managed automatically (as in, the language/runtime manage it without programmer intervention required) or manually (programmers must ensure they call some kind of &lt;code&gt;release&lt;/code&gt; method or function to indicate a finished state of use). Reference counting is highly vulnerable to mutually-referencing objects (cyclic object graphs) as a source of memory leaks.&lt;/p&gt; &lt;p&gt;Historical notes:&lt;/p&gt; 
  &lt;ul&gt; 
   &lt;li&gt; &lt;p&gt;Microsoft COM was the first &quot;mainstream&quot; platform to really embrace reference counting as a part of its formal semantics (the &lt;code&gt;IUnknown&lt;/code&gt; interface had three methods, two of which--&lt;code&gt;AddRef&lt;/code&gt; and &lt;code&gt;Release&lt;/code&gt;--managed the reference count of the allocated component), with very mixed results. When COM went distributed (DCOM), reference counts jumped in severity, since now the garbage collection was distributed, and a missed or dropped call could keep an object alive forever.&lt;/p&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;CORBA used reference counting as well, with much the same result.&lt;/p&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;Java RMI chose to use a different form of distributed garbage collection, using a &quot;heartbeat&quot; to keep an object alive, and if no such heartbeat came through every so often, the object was assumed to be unreachable and therefore eligible for reclamation.&lt;/p&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;Objective-C used reference counting, then later moved to &quot;automatic reference counts&quot; (ARC) which was then pushed under the covers by the Swift language.&lt;/p&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;p&gt;Some additional ideas/concepts around ref-counting:&lt;/p&gt; 
  &lt;ul&gt; 
   &lt;li&gt; &lt;p&gt;&lt;strong&gt;Deferred reference counting&lt;/strong&gt;: In deferred reference counts, local updates to the reference count (that is, those arising from assignments to and from local variables) are &quot;deferred&quot;, as long as it is known that the reference count will remain positive when it should be positive. For example, the code to swap the (reference-counted) values contained in two variables a and b naively performs the following operations:&lt;/p&gt; &lt;pre&gt;&lt;code&gt;    incrc(a); tmp := a;
    incrc(b); decrc(a); a := b;
    incrc(tmp); decrc(b); b := tmp
    decrc(tmp); (tmp goes out of scope)
&lt;/code&gt;&lt;/pre&gt; &lt;p&gt;After all the dust has cleared, after six reference count operations, the reference counts of the objects referred to by a and b (now by b and a) are unchanged. It is more efficient to recognize this and leave the reference counts unchanged.&lt;/p&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;&lt;strong&gt;Lazy Freeing&lt;/strong&gt;: Note that naive reference counting can take arbitrarily long to return from a decrement, because freeing one object may recursively trigger the freeing of other objects whose counts drop to zero. Instead, an object whose reference count falls to zero may be placed on a queue/list/stack of objects that are no longer in use, but not yet processed onto the free list. Alternatively, when an object is allocated off the free list, the pointers to objects within it may be scanned. This is also known as &quot;Weizenbauming&quot;, at least in some circles.&lt;/p&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;&lt;strong&gt;One-bit reference counting&lt;/strong&gt;: William Stoye&apos;s trick in his combinator machine. Reference counts are frequently one, and noting this in the pointer, rather than the object, can save space, cut memory references, and allow the easy recycling of vast amounts of garbage. In a combinator machine, the actual primitives can be parameterized by the reference counts of their operands to recycle memory in place. Note, however, that a combinator machine generates vast amounts of garbage to begin with; this technique is unlikely to work as well in general use.&lt;/p&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Smart pointers&lt;/strong&gt;: Most smart pointers are small &quot;wrappers&quot; around native pointers, carrying a reference count that tries to be as automatic as possible. Most popular in C++ implementations, though some languages (Rust) look to incorporate smart-pointer-type semantics directly into the language. These generally try to then utilize stack-based concepts to help automagically manage reference counts for allocated objects, but circular reference counts are still possible (and probable). In languages like Java or C#, one might imagine that all object references are smart, in that they are known to the platform. (Note: the CLR specifically has object reference pointers--what the CLI Spec calls &quot;managed references&quot;--as well as &quot;native pointers&quot;, which are raw locations in memory, without the additional CLR-backed support, for interop with native code.)&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Reachability&lt;/strong&gt;: When moving beyond pointer/reference-based schemes, most automated memory systems need to know which objects are eligible for reclamation, and which aren&apos;t--in essence, which are still under the possibility of being used by code. (An automatic memory system should &lt;strong&gt;&lt;em&gt;never&lt;/em&gt;&lt;/strong&gt; deallocate an object that is in use.) This analysis is usually known as &quot;reachability&quot; analysis, that is, finding which objects are &quot;reachable&quot; by user code, and therefore unsafe to reclaim. Many systems have multiple possibilities of reachability:&lt;/p&gt; 
  &lt;ul&gt; 
   &lt;li&gt;&lt;em&gt;reachable&lt;/em&gt; (in use)&lt;/li&gt; 
   &lt;li&gt;&lt;em&gt;softly reachable&lt;/em&gt;: Softly-reachable objects are eligible for reclamation, but are not reclaimed except and until memory pressure is too great (in other words, the runtime will fail if space is not found). Useful for caching behavior.&lt;/li&gt; 
   &lt;li&gt;&lt;em&gt;weakly reachable&lt;/em&gt;: An object is weakly reachable when the garbage collector finds no strong or soft references, but at least one path to the object with a weak reference. Weakly reachable objects are finalized some time after their weak references have been cleared. The only real difference between a soft reference and a weak reference is that the garbage collector uses algorithms to decide whether or not to reclaim a softly reachable object, but always reclaims a weakly reachable object. Weak references work well in applications that need to, for example, associate extra data with an unchangeable object, such as a thread the application did not create. Systems with weak references usually have some form of notification system when the referent is cleared, such as Java&apos;s &lt;code&gt;ReferenceQueue&lt;/code&gt; mechanic. If you make a weak reference to the thread with a reference queue, your program can be notified when the thread is no longer strongly reachable. Upon receiving this notification, the program can perform any required cleanup of the associated data object. This makes them useful for object-pooling kinds of behavior.&lt;/li&gt; 
   &lt;li&gt;&lt;em&gt;finalizer-reachable&lt;/em&gt; or &lt;em&gt;&quot;f-reachable&quot;&lt;/em&gt;: an object queued by the runtime for reclamation but still requires its finalizer to run; thus it is reachable only by the finalizer thread/mechanism within the runtime.&lt;/li&gt; 
   &lt;li&gt;&lt;em&gt;phantom-reachable&lt;/em&gt;: An object is phantomly reachable when the garbage collector finds no strong, soft, or weak references, but at least one path to the object with a phantom reference. Phantomly reachable objects are objects that have been finalized, but not reclaimed. These are the hardest to use, but offer a mechanism by which to do cleanup after a finalizer has been executed, essentially providing another way to do resource cleanup.&lt;/li&gt; 
   &lt;li&gt;&lt;em&gt;unreachable&lt;/em&gt; (not in use): There is no path from any executing code to this object, so there is no way this object could be used, making it safe to eliminate.&lt;/li&gt; 
  &lt;/ul&gt; &lt;p&gt;Reading: &lt;a href=&quot;http://pawlan.com/monica/articles/refobjs/&quot;&gt;Monica Pawlan&apos;s original article&lt;/a&gt; | &lt;a href=&quot;https://www.kdgregory.com/index.php?page=java.refobj&quot;&gt;Java reference types&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Note: This is using the JVM terminology; the CLR does not have soft or phantom references, and I&apos;ve never heard of Python or Ruby having anything beyond weak references, either. Any GC language has reachable/unreachable, and any language which has some kind of concept of &quot;destructor&quot; or &quot;finalizer&quot; has to have f-reachable (or it goes to great lengths to invoke those destructors/finalizers the moment the last reference is dropped, which usually implies either some very sophisticated compiler analysis or a reference count buried under the surface, as in Swift/Obj-C&apos;s automatic reference counting (ARC).)&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://www.memorymanagement.org/glossary/m.html#term-mark-sweep&quot;&gt;&lt;strong&gt;Mark-Sweep&lt;/strong&gt;&lt;/a&gt;: A garbage collection pass occurs in two phases: a &quot;mark&quot; phase, to identify the difference between collectible objects and non-collectible objects, and a &quot;sweep&quot; phase, in which the collectible objects are finalized and collected. &lt;strong&gt;Pros&lt;/strong&gt;: simple, &lt;strong&gt;Cons&lt;/strong&gt;: tends to lead to major fragmentation of the heap; the mark phase may require all activity in the garbage collector to cease (so as to avoid problems of marking an object collectible if concurrently it&apos;s becoming reachable again--but I think this isn&apos;t possible for a lot of systems; see &quot;concurrent mark-and-sweep&quot; below); as the heap gets larger, taking the time to crawl the heap becomes exponentially greater.&lt;/p&gt; &lt;p&gt;&lt;img src=&quot;https://upload.wikimedia.org/wikipedia/commons/thumb/4/4a/Animation_of_the_Naive_Mark_and_Sweep_Garbage_Collector_Algorithm.gif/330px-Animation_of_the_Naive_Mark_and_Sweep_Garbage_Collector_Algorithm.gif&quot; alt=&quot;&quot;&gt;&lt;/p&gt; &lt;p&gt;Some variations on mark-sweep:&lt;/p&gt; 
  &lt;ul&gt; 
   &lt;li&gt; &lt;p&gt;&lt;strong&gt;Tricolor marking&lt;/strong&gt;: Because of these performance problems, most modern tracing garbage collectors implement some variant of the tri-color marking abstraction, but simple collectors (such as the mark-and-sweep collector) often do not make this abstraction explicit. Tri-color marking works as described below.&lt;/p&gt; &lt;p&gt;Three sets are created – white, black and gray:&lt;/p&gt; &lt;p&gt;&lt;img src=&quot;https://upload.wikimedia.org/wikipedia/commons/thumb/1/1d/Animation_of_tri-color_garbage_collection.gif/330px-Animation_of_tri-color_garbage_collection.gif&quot; alt=&quot;&quot;&gt;&lt;/p&gt; 
    &lt;ul&gt; 
     &lt;li&gt;The white set, or condemned set, is the set of objects that are candidates for having their memory recycled.&lt;/li&gt; 
     &lt;li&gt;The black set is the set of objects that can be shown to have no outgoing references to objects in the white set, and to be reachable from the roots. Objects in the black set are not candidates for collection.&lt;/li&gt; 
     &lt;li&gt;The gray set contains all objects reachable from the roots but yet to be scanned for references to &quot;white&quot; objects. Since they are known to be reachable from the roots, they cannot be garbage-collected and will end up in the black set after being scanned.&lt;/li&gt; 
    &lt;/ul&gt; &lt;p&gt;In many algorithms, initially the black set starts as empty, the gray set is the set of objects which are directly referenced from roots and the white set includes all other objects. Every object in memory is at all times in exactly one of the three sets. The algorithm proceeds as following:&lt;/p&gt; 
    &lt;ol&gt; 
     &lt;li&gt;Pick an object from the gray set and move it to the black set.&lt;/li&gt; 
     &lt;li&gt;Move each white object it references to the gray set. This ensures that neither this object nor any object it references can be garbage-collected.&lt;/li&gt; 
     &lt;li&gt;Repeat the last two steps until the gray set is empty.&lt;/li&gt; 
    &lt;/ol&gt; &lt;p&gt;When the gray set is empty, the scan is complete; the black objects are reachable from the roots, while the white objects are not and can be garbage-collected.&lt;/p&gt; &lt;p&gt;Since all objects not immediately reachable from the roots are added to the white set, and objects can only move from white to gray and from gray to black, the algorithm preserves an important invariant – no black objects reference white objects. This ensures that the white objects can be freed once the gray set is empty. This is called the tri-color invariant. Some variations on the algorithm do not preserve this invariant but use a modified form for which all the important properties hold.&lt;/p&gt; &lt;p&gt;The tri-color method has an important advantage – it can be performed &quot;on-the-fly&quot;, without halting the system for significant periods of time. This is accomplished by marking objects as they are allocated and during mutation, maintaining the various sets. By monitoring the size of the sets, the system can perform garbage collection periodically, rather than as needed. Also, the need to touch the entire working set on each cycle is avoided.&lt;/p&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;&lt;strong&gt;Mark-and-don&apos;t-sweep&lt;/strong&gt;: This might also be regarded as &quot;lazy sweep&quot; or &quot;incremental sweep&quot;. Whenever memory is needed, the allocator scans objects until it discovers one that is marked &quot;unused&quot; and is also large enough for the request. All objects scanned, whether large enough or not, are marked &quot;used&quot;. When the scan pointer reaches the end of memory, the sense of the mark bits is reversed (that is, if the current assignment is 0==used and 1==unused, then the new assignment is 0==unused, 1==used). Temporarily, all objects on the heap are now marked &quot;unused&quot;. Next, a mark phase is run, which tags all reachable objects as &quot;used&quot; so that they will not be reallocated later.&lt;/p&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;&lt;strong&gt;Snapshot mark-and-sweep&lt;/strong&gt;: Snapshot mark-and-sweep uses the observation that the set of unreachable objects does not shrink. It is possible (using, for instance, copy-on-write page mapping) to quickly make a copy of the address space, process it concurrently to determine what is garbage, and send that information back to the running process. More garbage may have been generated in the interim, but that is ok, because it will be found in the next collection.&lt;/p&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;&lt;strong&gt;Concurrent mark-and-sweep&lt;/strong&gt;:&lt;/p&gt; &lt;p&gt;Articles:&lt;/p&gt; 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;http://doc.cat-v.org/inferno/concurrent_gc/&quot;&gt;&quot;Very Concurrent Mark and Sweep Garbage Collection without Fine-Grain Synchronization&quot;&lt;/a&gt; (&lt;a href=&quot;http://doc.cat-v.org/inferno/concurrent_gc/concurrent_gc.pdf&quot;&gt;pdf&lt;/a&gt;): We describe a new incremental algorithm for the concurrent reclamation of a program’s allocated, yet unreachable, data. Our algorithm is a variant of mark-&amp;amp;-sweep collection that—unlike prior designs—runs mutator, marker, and sweeper threads concurrently without explicit fine-grain synchronization on shared-memory multiprocessors. A global, but infrequent, synchronization coordinates the per-object coloring marks used by the three threads; ne-grain synchronization is achieved without locking via the basic memory consistency guarantees commonly provided by multiprocessor hardware. We have implemented two versions of this algorithm (called VCGC): in the Inferno operating system and in the SML/NJ ML compiler. Measurements, compared to a sequential generational collector, indicate that VCGC can substantially reduce worst-case pause latencies as well as reduce overall memory usage. We remark that the degrees of freedom on the rates of marking and sweeping enable exploration of a range of resource tradeoffs, but makes &quot;optimal” tuning for even a small set of applications difficult.&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://www.memorymanagement.org/glossary/m.html#term-mark-compact&quot;&gt;&lt;strong&gt;Mark-Sweep-Compact&lt;/strong&gt;&lt;/a&gt;: A mark-sweep algorithm that also takes the time after the sweep to rearrange the objects in memory so as to put available spaces next to one another, reducing fragmentation and making it easier to satisfy future requests. Takes longer, and requires objects in memory to be movable (either by adding a layer of indirection on access, or by allowing pointers to be &quot;fixed up&quot; later to point to the right location).&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://www.memorymanagement.org/glossary/c.html#term-copying-garbage-collection&quot;&gt;&lt;strong&gt;Copying&lt;/strong&gt;&lt;/a&gt;:&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Generational&lt;/strong&gt;: A form of copying collector. Based on the observation that most objects have short lifetimes, it is useful to restrict garbage collection to the most recently allocated objects. A generational collector maintains several &lt;code&gt;generations&apos;&apos; of objects. Newly created objects are all put in the&lt;/code&gt;youngest&apos;&apos; generation, and when the space allocated for that generation is full, the collector will use the root set (and any pointers from older generations to the youngest generation -- see below) to reclaim dead objects from the youngest generation only, leaving the &lt;code&gt;older&apos;&apos; generations untouched. Objects that survive after several (perhaps just one) collection of the youngest generation are&lt;/code&gt;promoted&apos;&apos; to the next older generation, and when that generation becomes full, it and all the generations younger than it are collected.&lt;/p&gt; &lt;p&gt;The difficulty with generational collectors is the identification of pointers from older generations into younger ones. An observation is that such references are uncommon in most programs: new objects typically point to older objects; this is clearly true in pure functional languages where assignment is prohibited, but is common for many programs and languages. Nonetheless, such references do exist, and a collector must handle them. When a pointer to a younger generation object is written into an old object, the pointer (or just the old object) is recorded so it can be scanned when the younger generation is collected.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Conservative Collection&lt;/strong&gt;: Conservative garbage collection makes use of the observation that if you are not relocating (copying) objects, then you need not be quite so certain about exactly what is a pointer. It suffices to scan the root set (and objects) for any pointer-like bit patterns, and treat those pointer-like bit patterns as actual pointers while marking. The result is that the &quot;true&quot; reachable objects are all found, along with a few others. This works surprisingly well in practice (if a few additional tricks are added) and often permits the use of garbage collection with oblivious source code and compilers.&lt;br&gt; Conservative collection is very important because it permits the use of garbage collection with programs that were not written with garbage collection in mind. That is, it simpifies the use of garbage collection with existing (non-garbage-collected) libraries of code.&lt;/p&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;Ironically, many of these strategies could be used in custom allocation/deallocation schemes in C/C++, but typically aren&apos;t due to the complexity of memory management; specifically, C++&apos;s inability to allow for the &quot;movement&quot; of objects as part of the process. This inability to move objects around in memory (that is, specifically, to track where the object ends up and &quot;backport&quot; the new location to the already-existing pointers pointing to it) leads to excessive fragmentation over time, and that in turn can lead to inability to satisfy an allocation request--no one &quot;hole&quot; in the memory space is large enough to accommodate the request, despite there being enough &lt;em&gt;total&lt;/em&gt; memory to do so.&lt;/p&gt; 
&lt;h3&gt;Additional concepts&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;strong&gt;Finalizers&lt;/strong&gt;: Blocks of code to be run to assist with object reclamation efforts, for those situations in which just releasing the memory occupied is not sufficient to release all allocated resources (files, connections, locks, etc). These need to be run prior to the object&apos;s deallocation, since the variable state inside the object is often necessary as part of the resource-deallocation process, but this is usually running on a thread owned by the runtime, which means this is a scenario in which user code is being run on a runtime-owned thread, which raises all sorts of negative possibilities.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Glossary/Jargon&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;strong&gt;root set&lt;/strong&gt;: The data that is immediately available to a program, without following any pointers. Typically this would include local variables from the activation stack, values in machine registers, and global, static, or module variables.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;reachable data&lt;/strong&gt;: Data that is accessible by following pointers (references) from the root set. Reachability is a conservative approximation of liveness and is used by most garbage collectors.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;live data&lt;/strong&gt;: Data that is reachable, and that the program will actually make use of in the future. Garbage collectors typically cannot tell the difference between live and reachable data, but programmers and compilers sometimes can.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;garbage&lt;/strong&gt;: Data that is not reachable.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;semantic garbage&lt;/strong&gt;: Data that is reachable, but not live.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;precise&lt;/strong&gt;: A garbage collector that can determine unambiguously whether a given value is a pointer or not. This can be seen as a requirement on the run-time the collector operates within that it is possible to identify whether some datum is a pointer.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;conservative&lt;/strong&gt;: A garbage collector which can scan data without needing to determine with certainty whether an object is a pointer.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;semi-conservative&lt;/strong&gt;, &lt;strong&gt;mostly-precise&lt;/strong&gt;: A collector which permits a mixture of precisely and conservatively identified values. For example, values in registers and on the stack might be treated conservatively, but objects on the heap would be fully described and precisely scanned.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;incremental&lt;/strong&gt;: An incremental collector interleaves collection activity with the actual work of the program. The interleaving is usually orderly; that is, the collector and mutator do not simultaneously access and modify data. If the collector and mutator are viewed as separate threads, then they are scheduled as coroutines. However, the sum of the incremental phases takes longer to complete than one batch garbage collection pass, so these garbage collectors may yield lower total throughput.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;concurrent&lt;/strong&gt;: In a concurrent collector, the collector and mutator may simultaneously access and modify data. The interleaving is disorderly, and preemption may occur at any time. However, the sum of the concurrent phases takes longer to complete than one batch garbage collection pass, so these garbage collectors may yield lower total throughput.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;stop-the-world&lt;/strong&gt;, &lt;strong&gt;stop-and-collect&lt;/strong&gt;: Simple stop-the-world garbage collectors completely halt execution of the program to run a collection cycle, thus guaranteeing that new objects are not allocated and objects do not suddenly become unreachable while the collector is running. This has the disadvantage that the program can perform no useful work while a collection cycle is running (sometimes called the &quot;embarrassing pause&quot;). Stop-the-world garbage collection is therefore mainly suitable for non-interactive programs. Its advantage is that it is both simpler to implement and faster than incremental garbage collection.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;real-time&lt;/strong&gt;: A real-time garbage collector (yes, it is possible) guarantees that the garbage collection costs associated with any single operation are bounded by a small time constant. The cost of this guarantee is typically reduced throughput, higher memory overheads, and custom code generation. When hard real-time scheduling is not required, an incremental or concurrent collector is probably a better choice.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;forwarding-pointer&lt;/strong&gt;: In a collector which moves objects, a forwarding pointer is a reference installed by the garbage collector from an old location to the new one. Some systems (notably the Lisp machines) have hardware support for forwarding pointers, which allow both the old and new address to be used interchangably without explicit checks for forwarding pointers.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;flip&lt;/strong&gt;: In a copying collector, when an arena has had all active objects removed from it, and is eligible for refilling, the sense of the arenas is changed -- that is, an &quot;old&quot; arena is now a &quot;new&quot; arena, and some &quot;new&quot; arena becomes &quot;old&quot;. This is referred to as a flip.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;weak reference&lt;/strong&gt;, &lt;strong&gt;weak pointer&lt;/strong&gt;: A pointer to an object which does not prevent the object from being reclaimed. If the only pointers to an object are from weak references, the object may disappear, in which case the reference is replaced with some distinguished value, typically a language&apos;s equivalent of a NULL pointer. Weak references are often used for implementing caches.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;write barrier&lt;/strong&gt;, &lt;strong&gt;read barrier&lt;/strong&gt;: A write barrier is a mechanism for executing some memory management code when a write to some object takes place (that object is then &quot;behind the write barrier&quot;, or - informally - &quot;write barrier-ed&quot;, or - sloppily - &quot;write-protected&quot;). It can take the form of inlined code (if memory management is integral to the compiler), or a memory-protection fault which is handled by the memory management code. There are also &quot;read barriers&quot;, the nature of which is obvious.&lt;br&gt; The roles a write barrier can play in GC are a little trickier to explain to a novice, but I&apos;ll give it a stab. 
  &lt;ol&gt; 
   &lt;li&gt; &lt;p&gt;Consider a simple generational stop-and-collect collector, such as the one which SML/NJ used to have. &quot;Generational&quot; means that data is partitioned into old and new. This partition is useful to the GC for two reasons: (a) because data tends to die young, collecting just new data will probably free a lot of space, and (b) because pointers tend to point from new objects to old objects, and not vice versa, it is cheap to find all the pointers to new objects.&lt;/p&gt; &lt;p&gt;Property (b) is only true if you can tell when a pointer to a new object has been written into an old object. Otherwise you have to scan all the old objects to find pointers to new objects, which loses one of the main advantages of generational GC. So you put the old data behind a write barrier, and record those writes. When you come to GC the new data, you know the only pointers from old to new are those which you have recorded.&lt;/p&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;Consider a tracing GC (see note below) which is incremental or concurrent, i.e. the user&apos;s program (the &apos;mutator&apos;) can run before the GC is complete. Now there is an invariant: black objects do not point to white objects. If the mutator writes a white pointer into a black object, this invariant is broken and the GC can fail. There are two basic solutions: prevent the mutator from seeing white objects (&quot;read barriers&quot;) or prevent the mutator from writing white pointers into black objects (&quot;write barriers&quot;). The write barrier solution puts the black objects behind a write barrier. When a white-on-black write takes place there are various fixes: incrementally grey the white object, regrey the black object, &amp;amp;c.&lt;/p&gt; &lt;p&gt;(note) For a tracing collector (marking or copying), one conceptually colours the data white (not yet seen by the collector), black (alive and scanned by the collector) and grey (alive but not yet scanned by the collector). The collector proceeds by scanning grey objects for pointers to white objects. The white objects found are turned grey, and the grey objects scanned are turned black. When there are no more grey objects, the collection is complete and all the white objects can be recycled.&lt;/p&gt; &lt;/li&gt; 
  &lt;/ol&gt; &lt;p&gt;The overhead of write barriers is more likely to be noticeable in an imperative-style program which frequently writes pointers into existing data structures than in a functional-style program which constructs data only once and never changes them.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;remembered set&lt;/strong&gt;: A list of all the interesting references between two sets of objects maintained separately, so you don&apos;t have to find them by scanning. In generational garbage collection, this technique is used for references from an older generation to a younger one. Typically, remembered sets are maintained by write barriers (q.v.).&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;register set partitioning&lt;/strong&gt;: Garbage-collected languages often partition the set of registers a priori into those always traced and updated (if necessary) by the collector and those ignored by it. The language always maintains the former in a format understood by the collector; and never uses the latter to hold pointers to collectable objects. More complicated schemes are also possible.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;big bag of pages&lt;/strong&gt;: Big Bag of Pages, or BIBOP, is the technique of using an object&apos;s address (page number) to encode information about the object. For example, all objects allocated on a particular page might be the same size, or the same type. This technique can be used to avoided allocating object header bits or header tags.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Papers/articles/notes&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.memorymanagement.org/&quot;&gt;Memory Management Reference (site)&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.cs.cornell.edu/courses/cs4120/2018sp/lectures/39gc/lec39-sp18.pdf&quot;&gt;CS 4120/5120 Lecture notes&lt;/a&gt; (Andrew Myers)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://spin.atomicobject.com/2014/09/03/visualizing-garbage-collection-algorithms/&quot;&gt;Visualizing garbage collection algorithms&lt;/a&gt; (&lt;a href=&quot;https://github.com/kenfox/gc-viz&quot;&gt;Source&lt;/a&gt;): Demonstrates NoGC, ref-counting, mark-sweep, mark-compact, and copying.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.dmitrysoshnikov.education/p/essentials-of-garbage-collectors&quot;&gt;Garbage Collection Algorithms&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;C/C++&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://hboehm.info/gc/&quot;&gt;Boehm-Weiser collector&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;.NET&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://docs.microsoft.com/en-us/dotnet/standard/garbage-collection/weak-references&quot;&gt;.NET Weak References&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://courses.cs.washington.edu/courses/csep521/07wi/prj/rick.pdf&quot;&gt;Garbage Collection Algorithms&lt;/a&gt;: covers mark-sweep, semi-space, variations, and then gets into open problems. General overview, pretty light, feels like somebody&apos;s book report on the subject.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Java&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://plumbr.io/java-garbage-collection-handbook&quot;&gt;Plumbr Handbook Java GC&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.oracle.com/java/technologies/whitepaper.html&quot;&gt;Java HotSpot Architecture&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.overops.com/blog/garbage-collectors-serial-vs-parallel-vs-cms-vs-the-g1-and-whats-new-in-java-8/&quot;&gt;Garbage collectors: Serial vs parallel vs CMS vs G1&lt;/a&gt;; targets Java8, so a little out of date&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.overops.com/blog/improve-your-application-performance-with-garbage-collection-optimization/&quot;&gt;Improve App Performance with These Advanced GC Techniques&lt;/a&gt;; a newer (2021) version of the previous article&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Python&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://stackify.com/python-garbage-collection/&quot;&gt;Python GC&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://devguide.python.org/garbage_collector/&quot;&gt;CPython GC&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://towardsdatascience.com/memory-management-and-garbage-collection-in-python-c1cb51d1612c&quot;&gt;Memory Mgmt and GC in Python&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.python.org/dev/peps/pep-0205/&quot;&gt;Python Weak References&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Dynamic Analysis Sanitizers reading</title>
      <link>https://tedneward.github.io/Research/reading/development/dynamic-analysis-sanitizers/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">reading/development/dynamic-analysis-sanitizers/index.html</guid>
      	<description>
	&lt;ul&gt; 
 &lt;li&gt; &lt;p&gt;Sanitizers: AddressSanitizer, ThreadSanitizer, MemorySanitizer&lt;/p&gt; 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/google/sanitizers&quot;&gt;https://github.com/google/sanitizers&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/google/sanitizers/wiki&quot;&gt;https://github.com/google/sanitizers/wiki&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Compilers&lt;/p&gt; 
  &lt;ul&gt; 
   &lt;li&gt; &lt;p&gt;Clang&lt;/p&gt; 
    &lt;ul&gt; 
     &lt;li&gt;AddressSanitizer - &lt;a href=&quot;https://clang.llvm.org/docs/AddressSanitizer.html&quot;&gt;https://clang.llvm.org/docs/AddressSanitizer.html&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;DataFlowSanitizer - &lt;a href=&quot;https://clang.llvm.org/docs/DataFlowSanitizer.html&quot;&gt;https://clang.llvm.org/docs/DataFlowSanitizer.html&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;Hardware-assisted AddressSanitizer Design Documentation - &lt;a href=&quot;https://clang.llvm.org/docs/HardwareAssistedAddressSanitizerDesign.html&quot;&gt;https://clang.llvm.org/docs/HardwareAssistedAddressSanitizerDesign.html&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;LeakSanitizer - &lt;a href=&quot;https://clang.llvm.org/docs/LeakSanitizer.html&quot;&gt;https://clang.llvm.org/docs/LeakSanitizer.html&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;MemorySanitizer - &lt;a href=&quot;https://clang.llvm.org/docs/MemorySanitizer.html&quot;&gt;https://clang.llvm.org/docs/MemorySanitizer.html&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;SanitizerCoverage - &lt;a href=&quot;https://clang.llvm.org/docs/SanitizerCoverage.html&quot;&gt;https://clang.llvm.org/docs/SanitizerCoverage.html&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;SanitizerStats - &lt;a href=&quot;https://clang.llvm.org/docs/SanitizerStats.html&quot;&gt;https://clang.llvm.org/docs/SanitizerStats.html&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;Sanitizer special case list - &lt;a href=&quot;https://clang.llvm.org/docs/SanitizerSpecialCaseList.html&quot;&gt;https://clang.llvm.org/docs/SanitizerSpecialCaseList.html&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;ThreadSanitizer - &lt;a href=&quot;https://clang.llvm.org/docs/ThreadSanitizer.html&quot;&gt;https://clang.llvm.org/docs/ThreadSanitizer.html&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;UndefinedBehaviorSanitizer - &lt;a href=&quot;https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html&quot;&gt;https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;GCC&lt;/p&gt; 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://gcc.gnu.org/onlinedocs/gcc/Instrumentation-Options.html&quot;&gt;https://gcc.gnu.org/onlinedocs/gcc/Instrumentation-Options.html&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;Address and Thread Sanitizers in GCC 
      &lt;ul&gt; 
       &lt;li&gt;&lt;a href=&quot;https://developers.redhat.com/blog/2014/12/02/address-and-thread-sanitizers-gcc/&quot;&gt;https://developers.redhat.com/blog/2014/12/02/address-and-thread-sanitizers-gcc/&lt;/a&gt;&lt;/li&gt; 
      &lt;/ul&gt; &lt;/li&gt; 
     &lt;li&gt;Useful GCC address sanitizer checks not enabled by default 
      &lt;ul&gt; 
       &lt;li&gt;&lt;a href=&quot;https://kristerw.blogspot.com/2018/06/useful-gcc-address-sanitizer-checks-not.html&quot;&gt;https://kristerw.blogspot.com/2018/06/useful-gcc-address-sanitizer-checks-not.html&lt;/a&gt;&lt;/li&gt; 
      &lt;/ul&gt; &lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Adding Clang Sanitizers to a CMake Build&lt;/p&gt; 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://genbattle.bitbucket.io/blog/2018/01/05/Dev-Santa-Claus-Part-1/&quot;&gt;https://genbattle.bitbucket.io/blog/2018/01/05/Dev-Santa-Claus-Part-1/&lt;/a&gt; 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://old.reddit.com/r/cpp/comments/7qzqlg/dev_santa_claus_pt1_adding_clang_sanitizers_to_a/&quot;&gt;https://old.reddit.com/r/cpp/comments/7qzqlg/dev_santa_claus_pt1_adding_clang_sanitizers_to_a/&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Creating an LLVM Sanitizer from Hopes and Dreams&lt;/p&gt; 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://blog.trailofbits.com/2019/06/25/creating-an-llvm-sanitizer-from-hopes-and-dreams/&quot;&gt;https://blog.trailofbits.com/2019/06/25/creating-an-llvm-sanitizer-from-hopes-and-dreams/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;llvm-sanitizer-tutorial and documentation 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://github.com/trailofbits/llvm-sanitizer-tutorial&quot;&gt;https://github.com/trailofbits/llvm-sanitizer-tutorial&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;GWP-ASan: Sampling heap memory error detection in-the-wild&lt;/p&gt; 
  &lt;ul&gt; 
   &lt;li&gt;2019; Vlad Tsyrklevich&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://sites.google.com/a/chromium.org/dev/Home/chromium-security/articles/gwp-asan&quot;&gt;https://sites.google.com/a/chromium.org/dev/Home/chromium-security/articles/gwp-asan&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Kernel Concurrency Sanitizer (KCSAN)&lt;/p&gt; 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/google/ktsan/wiki/KCSAN&quot;&gt;https://github.com/google/ktsan/wiki/KCSAN&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Concurrency bugs should fear the big bad data-race detector 
    &lt;ul&gt; 
     &lt;li&gt;part 1: &lt;a href=&quot;https://lwn.net/Articles/816850/&quot;&gt;https://lwn.net/Articles/816850/&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;part 2: &lt;a href=&quot;https://lwn.net/Articles/816854/&quot;&gt;https://lwn.net/Articles/816854/&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Kernel Thread Sanitizer (KTSAN)&lt;/p&gt; 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/google/ktsan&quot;&gt;https://github.com/google/ktsan&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/google/ktsan/wiki&quot;&gt;https://github.com/google/ktsan/wiki&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Research&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;A Preliminary Study on Open-Source Memory Vulnerability Detectors 
  &lt;ul&gt; 
   &lt;li&gt;International Conference on Software Analysis, Evolution, and Reengineering (SANER), ERA track, 2020&lt;/li&gt; 
   &lt;li&gt;Yu Nong and Haipeng Cai&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://chapering.github.io/pubs/saner20-a.pdf&quot;&gt;http://chapering.github.io/pubs/saner20-a.pdf&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;AddressSanitizer, CBMC, DrMemory, MemorySanitizer, Valgrind&lt;/li&gt; 
   &lt;li&gt;Research questions: 
    &lt;ul&gt; 
     &lt;li&gt;RQ1: How effective are these detectors in terms of precision, recall, and accuracy?&lt;/li&gt; 
     &lt;li&gt;RQ2: How efficient are the detectors in terms of their cost for detecting vulnerabilities?&lt;/li&gt; 
     &lt;li&gt;RQ3: How do these detectors compare in terms of their detection accuracy?&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;AddressSanitizer: A Fast Address Sanity Checker 
  &lt;ul&gt; 
   &lt;li&gt;2012 USENIX Annual Technical Conference (ATC)&lt;/li&gt; 
   &lt;li&gt;Konstantin Serebryany, Derek Bruening, Alexander Potapenko, Dmitry Vyukov&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.usenix.org/conference/atc12/technical-sessions/presentation/serebryany&quot;&gt;https://www.usenix.org/conference/atc12/technical-sessions/presentation/serebryany&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://research.google/pubs/pub37752/&quot;&gt;https://research.google/pubs/pub37752/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;CastSan: Efficient Detection of Polymorphic C++ Object Type Confusions with LLVM 
  &lt;ul&gt; 
   &lt;li&gt;European Symposium on Research in Computer Security (ESORICS) 2018&lt;/li&gt; 
   &lt;li&gt;Muntean P., Wuerl S., Grossklags J., Eckert C.&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://link.springer.com/chapter/10.1007/978-3-319-99073-6_1&quot;&gt;https://link.springer.com/chapter/10.1007/978-3-319-99073-6_1&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.docdroid.net/INWYBF7/castsan-esorics18.pdf&quot;&gt;https://www.docdroid.net/INWYBF7/castsan-esorics18.pdf&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;CUP: Comprehensive User-Space Protection for C/C++ 
  &lt;ul&gt; 
   &lt;li&gt;AsiaCCS 2018&lt;/li&gt; 
   &lt;li&gt;Nathan Burow, Derrick McKee, Scott A. Carr, Mathias Payer&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://hexhive.github.io/publications/files/18AsiaCCS.pdf&quot;&gt;https://hexhive.github.io/publications/files/18AsiaCCS.pdf&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/HexHive/CUP&quot;&gt;https://github.com/HexHive/CUP&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;DangSan: Scalable Use-after-free Detection 
  &lt;ul&gt; 
   &lt;li&gt;European Conference on Computer Systems (EuroSys) 2017&lt;/li&gt; 
   &lt;li&gt;Erik van der Kouwe, Vinod Nigade, Cristiano Giuffrida&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://www.cs.vu.nl/~giuffrida/papers/dangsan_eurosys17.pdf&quot;&gt;http://www.cs.vu.nl/~giuffrida/papers/dangsan_eurosys17.pdf&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/vusec/dangsan&quot;&gt;https://github.com/vusec/dangsan&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;EffectiveSan: Type and Memory Error Detection using Dynamically Typed C/C++ 
  &lt;ul&gt; 
   &lt;li&gt;PLDI 2018&lt;/li&gt; 
   &lt;li&gt;Gregory J. Duck, Roland H. C. Yap&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://arxiv.org/abs/1710.06125&quot;&gt;https://arxiv.org/abs/1710.06125&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/GJDuck/EffectiveSan&quot;&gt;https://github.com/GJDuck/EffectiveSan&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://pldi18.sigplan.org/event/pldi-2018-papers-effectivesan-type-and-memory-error-detection-using-dynamically-typed-c-c-&quot;&gt;https://pldi18.sigplan.org/event/pldi-2018-papers-effectivesan-type-and-memory-error-detection-using-dynamically-typed-c-c-&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;HexType: Efficient Detection of Type Confusion Errors for C++ 
  &lt;ul&gt; 
   &lt;li&gt;ACM Conference on Computer and Communication Security (CCS) 2017&lt;/li&gt; 
   &lt;li&gt;Yuseok Jeon, Priyam Biswas, Scott A. Carr, Byoungyoung Lee, and Mathias Payer.&lt;/li&gt; 
   &lt;li&gt;Slides (PDF): &lt;a href=&quot;http://nebelwelt.net/publications/files/1734c3-presentation.pdf&quot;&gt;http://nebelwelt.net/publications/files/1734c3-presentation.pdf&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Paper (PDF): &lt;a href=&quot;https://nebelwelt.net/publications/files/17CCS.pdf&quot;&gt;https://nebelwelt.net/publications/files/17CCS.pdf&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;34C3 (2017) 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://media.ccc.de/v/34c3-8848-type_confusion_discovery_abuse_and_protection&quot;&gt;https://media.ccc.de/v/34c3-8848-type_confusion_discovery_abuse_and_protection&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=jbglFfkRYQs&quot;&gt;https://www.youtube.com/watch?v=jbglFfkRYQs&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;HexType: Efficient Detection of Type Confusion Errors for C++ 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://github.com/HexHive/HexType&quot;&gt;https://github.com/HexHive/HexType&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;HexVASAN: Venerable Variadic Vulnerabilities Vanquished 
  &lt;ul&gt; 
   &lt;li&gt;Usenix Security Symposium 2017&lt;/li&gt; 
   &lt;li&gt;Priyam Biswas, Alessandro Di Federico, Scott A. Carr, Prabhu Rajasekaran, Stijn Volckaert, Yeoul Na, Michael Franz, and Mathias Payer.&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://nebelwelt.net/publications/files/17SEC.pdf&quot;&gt;https://nebelwelt.net/publications/files/17SEC.pdf&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://nebelwelt.net/publications/files/17SEC-presentation.pdf&quot;&gt;https://nebelwelt.net/publications/files/17SEC-presentation.pdf&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/HexHive/HexVASAN&quot;&gt;https://github.com/HexHive/HexVASAN&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;MemorySanitizer: fast detector of uninitialized memory use in C++ 
  &lt;ul&gt; 
   &lt;li&gt;Code Generation and Optimization (CGO) 2015&lt;/li&gt; 
   &lt;li&gt;Evgeniy Stepanov and Konstantin Serebryany&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://research.google.com/pubs/archive/43308.pdf&quot;&gt;https://research.google.com/pubs/archive/43308.pdf&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;PartiSan: Fast and Flexible Sanitization via Run-time Partitioning 
  &lt;ul&gt; 
   &lt;li&gt;Research in Attacks, Intrusions and Defenses (RAID) 2018&lt;/li&gt; 
   &lt;li&gt;Julian Lettner, Dokyung Song, Taemin Park, Stijn Volckaert, Per Larsen, Michael Franz&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://arxiv.org/abs/1711.08108&quot;&gt;https://arxiv.org/abs/1711.08108&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;TypeSanitizer: Practical Type Confusion Detection 
  &lt;ul&gt; 
   &lt;li&gt;Computer and Communications Security (CCS) 2016&lt;/li&gt; 
   &lt;li&gt;Istvan Haller, Yuseok Jeon, Hui Peng, Mathias Payer, Herbert Bos, Cristiano Giuffrida, Erik van der Kouwe&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://nebelwelt.net/publications/files/16CCS2.pdf&quot;&gt;https://nebelwelt.net/publications/files/16CCS2.pdf&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;TypeSan checks casts in C++ code - code released for CCS 2016 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://github.com/vusec/typesan&quot;&gt;https://github.com/vusec/typesan&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Projects&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;QASan: QEMU-AddressSanitizer 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/andreafioraldi/qasan&quot;&gt;https://github.com/andreafioraldi/qasan&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Sanitized Emulation with QASan 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://andreafioraldi.github.io/articles/2019/12/20/sanitized-emulation-with-qasan.html&quot;&gt;https://andreafioraldi.github.io/articles/2019/12/20/sanitized-emulation-with-qasan.html&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;sanitizers-cmake: CMake modules to help use sanitizers 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/arsenm/sanitizers-cmake&quot;&gt;https://github.com/arsenm/sanitizers-cmake&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;TypeART: LLVM-based type and memory allocation tracking sanitizer 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/tudasc/TypeART&quot;&gt;https://github.com/tudasc/TypeART&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Compiler-aided Type Tracking for Correctness Checking of MPI Applications 
    &lt;ul&gt; 
     &lt;li&gt;International Workshop on Software Correctness for HPC Applications (Correctness) 2018&lt;/li&gt; 
     &lt;li&gt;Alexander Hück, Jan-Patrick Lehr, Sebastian Kreutzer, Joachim Protze, Christian Terboven, Christian Bischof, Matthias S. Müller&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://doi.org/10.1109/Correctness.2018.00011&quot;&gt;https://doi.org/10.1109/Correctness.2018.00011&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://correctness-workshop.github.io/2018/papers/lehr.pdf&quot;&gt;https://correctness-workshop.github.io/2018/papers/lehr.pdf&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Talks&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;AddressSanitizer, ThreadSanitizer and MemorySanitizer -- Dynamic Testing Tools for C++ 
  &lt;ul&gt; 
   &lt;li&gt;GTAC 2013; Kostya Serebryany&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=Q2C2lP8_tNE&quot;&gt;https://www.youtube.com/watch?v=Q2C2lP8_tNE&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Address and Thread Sanitizer in GCC: State of the Onion 
  &lt;ul&gt; 
   &lt;li&gt;GNU Tools Cauldron 2013; Dodji Seketeli&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://gcc.gnu.org/wiki/cauldron2013?action=AttachFile&amp;amp;do=view&amp;amp;target=asan.pdf&quot;&gt;https://gcc.gnu.org/wiki/cauldron2013?action=AttachFile&amp;amp;do=view&amp;amp;target=asan.pdf&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=41_WZk6AePY&quot;&gt;https://www.youtube.com/watch?v=41_WZk6AePY&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;C++ Sanitizers 
  &lt;ul&gt; 
   &lt;li&gt;C++ Weekly; Ep. 84 (2017)&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=MB6NPkB4YVs&quot;&gt;https://www.youtube.com/watch?v=MB6NPkB4YVs&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Debugging with LLVM: A quick introduction to LLDB and LLVM sanitizers 
  &lt;ul&gt; 
   &lt;li&gt;FOSDEM 2020&lt;/li&gt; 
   &lt;li&gt;Andrzej Warzynski; Graham Hunter&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://fosdem.org/2020/schedule/event/debugging_with_llvm/&quot;&gt;https://fosdem.org/2020/schedule/event/debugging_with_llvm/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Finding races and memory errors with LLVM instrumentation 
  &lt;ul&gt; 
   &lt;li&gt;2011 LLVM Developers’ Meeting; Konstantin Serebryany&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=sJqQTUtV6GY&quot;&gt;https://www.youtube.com/watch?v=sJqQTUtV6GY&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Finding races and memory errors with compiler instrumentation: AddressSanitizer, ThreadSanitizer 
  &lt;ul&gt; 
   &lt;li&gt;GNU Tools Cauldron 2012; Konstantin Serebryany, Dmitry Vyukov&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://gcc.gnu.org/wiki/cauldron2012?action=AttachFile&amp;amp;do=get&amp;amp;target=kcc.pdf&quot;&gt;https://gcc.gnu.org/wiki/cauldron2012?action=AttachFile&amp;amp;do=get&amp;amp;target=kcc.pdf&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://gcc.gnu.org/wiki/cauldron2012#Finding_races_and_memory_errors_with_GCC_instrumentation_.28AddressSanitizer.29&quot;&gt;https://gcc.gnu.org/wiki/cauldron2012#Finding_races_and_memory_errors_with_GCC_instrumentation_.28AddressSanitizer.29&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;MemorySanitizer, ThreadSanitizer: Scalable run-time detection of uninitialized memory reads and data races with LLVM instrumentation 
  &lt;ul&gt; 
   &lt;li&gt;2012 LLVM Developers’ Meeting; Kostya Serebryany&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=HDgttiIvMxA&quot;&gt;https://www.youtube.com/watch?v=HDgttiIvMxA&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;News from Sanitizers 
  &lt;ul&gt; 
   &lt;li&gt;GNU Tools Cauldron 2014; Evgeniy Stepanov, Kostya Serebryany&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://docs.google.com/presentation/d/1QG2qlzpxlsdDsX4uHhTLWAoUmbzbhedFMoMvviud0Us&quot;&gt;https://docs.google.com/presentation/d/1QG2qlzpxlsdDsX4uHhTLWAoUmbzbhedFMoMvviud0Us&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=Ek7z_oC0dak&quot;&gt;https://www.youtube.com/watch?v=Ek7z_oC0dak&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;The Type Sanitizer: Free Yourself from -fno-strict-aliasing 
  &lt;ul&gt; 
   &lt;li&gt;2017 LLVM Developers’ Meeting; Hal Finkel&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=vAXJeN7k32Y&quot;&gt;https://www.youtube.com/watch?v=vAXJeN7k32Y&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;ThreadSanitizer APIs for external libraries 
  &lt;ul&gt; 
   &lt;li&gt;2017 LLVM Developers’ Meeting; Kuba Mracek&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=-J9bMpqfc7A&quot;&gt;https://www.youtube.com/watch?v=-J9bMpqfc7A&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Effective Enterprise Java</title>
      <link>https://tedneward.github.io/Research/reading/development/effective-enterprise-java/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">reading/development/effective-enterprise-java/index.html</guid>
      	<description>
	&lt;p&gt;&lt;em&gt;(by Ted Neward, Addison-Wesley)&lt;/em&gt;&lt;/p&gt; 
&lt;h1&gt;Architecture&lt;/h1&gt; 
&lt;ol&gt; 
 &lt;li&gt; &lt;p&gt;Prefer components as the key element of development,&amp;nbsp;deployment, and reuse&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Prefer loose coupling across component boundaries&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Differentiate layers from tiers&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Keep data and processors close together&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Remember that identity breeds contention&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Use hook points to inject optimizations, customizations,&amp;nbsp;or new functionality&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Be robust in the face of failure&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Deﬁne your performance and scalability goals&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Restrict EJB to transactional processing&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Never optimize without proﬁling ﬁrst&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Recognize the cost of vendor neutrality&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Build in monitoring support&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Build in administration support&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Make deployment as simple as possible&lt;/p&gt; &lt;/li&gt; 
&lt;/ol&gt; 
&lt;h1&gt;Communication&lt;/h1&gt; 
&lt;ol&gt; 
 &lt;li&gt; &lt;p&gt;Understand all your communications options&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Consider your lookup carefully&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Recognize the cost of network access&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Prefer context-complete communication styles&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Prefer data-driven communication over behavior-driven&amp;nbsp;communication&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Avoid waiting for remote service requests to respond&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Consider partitioning components to avoid excessive load&amp;nbsp;on any one machine&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Consider using Web Services for open integration&lt;/p&gt; &lt;/li&gt; 
&lt;/ol&gt; 
&lt;h1&gt;Data&lt;/h1&gt; 
&lt;ol&gt; 
 &lt;li&gt; &lt;p&gt;Pass data in bulk&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Consider rolling your own communication proxies&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Keep it simple&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Prefer rules engines for complex state evaluation and execution&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Prefer transactional processing for implicitly nonatomic&amp;nbsp;failure scenarios&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Differentiate user transactions from system transactions&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Minimize lock windows&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Never cede control outside your component while&amp;nbsp;holding locks&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Understand EJB transactional afﬁnity&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Prefer local transactions to distributed ones&lt;/p&gt; &lt;/li&gt; 
&lt;/ol&gt; 
&lt;h1&gt;Distribution&lt;/h1&gt; 
&lt;ol&gt; 
 &lt;li&gt; &lt;p&gt;Consider using optimistic concurrency for better scalability&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Consider using pessimistic concurrency for explicit&amp;nbsp;concurrency control&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Consider lower isolation levels for better transactional&amp;nbsp;throughput&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Use savepoints to keep partial work in the face of rollback&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Replicate resources when possible to avoid lock regions&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Favor the immutable, for it needs no locks&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Use HttpSession sparingly&lt;/p&gt; &lt;/li&gt; 
&lt;/ol&gt; 
&lt;h1&gt;Persistence&lt;/h1&gt; 
&lt;ol&gt; 
 &lt;li&gt; &lt;p&gt;Use objects-ﬁrst persistence to preserve your domain&amp;nbsp;model&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Use relational-ﬁrst persistence to expose the power&amp;nbsp;of the relational model&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Use procedural-ﬁrst persistence to create an&amp;nbsp;encapsulation layer&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Recognize the object-hierarchical impedance mismatch&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Use in-process or local storage to avoid the network&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Never assume you own the data or the database&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Lazy-load infrequently used data&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Eager-load frequently used data&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Batch SQL work to avoid round-trips&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Know your JDBC provider&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Tune your SQL&lt;/p&gt; &lt;/li&gt; 
&lt;/ol&gt; 
&lt;h1&gt;Presentation&lt;/h1&gt; 
&lt;ol&gt; 
 &lt;li&gt; &lt;p&gt;Consider rich-client UI technologies&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Keep HTML minimal&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Separate presentation from processing&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Keep style separate from content&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Pregenerate content to minimize processing&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Validate early, validate everything&lt;/p&gt; &lt;/li&gt; 
&lt;/ol&gt; 
&lt;h1&gt;Security&lt;/h1&gt; 
&lt;ol&gt; 
 &lt;li&gt; &lt;p&gt;Security is a process, not a product&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Remember that security is not just prevention&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Establish a threat model&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Assume insecurity&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Always validate user input&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Turn on platform security&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Use role-based authorization&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Use SignedObject to provide integrity of Serialized objects&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Use SealedObject to provide conﬁdentiality of Serializable&amp;nbsp;objects&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Use GuardedObject to provide access control on objects&lt;/p&gt; &lt;/li&gt; 
&lt;/ol&gt; 
&lt;h1&gt;System&lt;/h1&gt; 
&lt;ol&gt; 
 &lt;li&gt; &lt;p&gt;Aggressively release resources&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Tune the JVM&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Use independent JREs for side-by-side versioning&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Recognize ClassLoader boundaries&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Understand Java Object Serialization&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Don’t ﬁght the garbage collector&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Prefer container-managed resource management&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Use reference objects to augment garbage collection behavior&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Don’t be afraid of JNI code on the server&lt;/p&gt; &lt;/li&gt; 
&lt;/ol&gt;
	</description>
    </item>
    <item>
      <title>Free programming books</title>
      <link>https://tedneward.github.io/Research/reading/development/free-programming-books/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">reading/development/free-programming-books/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/EbookFoundation/free-programming-books/blob/main/books/free-programming-books-langs.md&quot;&gt;Website/Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Eventually all of these links should move to their respective pages.&lt;/p&gt; 
&lt;h2&gt;BY PROGRAMMING LANGUAGE&lt;/h2&gt; 
&lt;h3&gt;AutoIt&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.autoitscript.com/autoit3/docs/&quot;&gt;AutoIt Docs&lt;/a&gt; - Jonathan Bennett (HTML)&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;BeanShell&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.beanshell.org/manual/bshmanual.pdf&quot;&gt;Beanshell Simple Java Scripting Manual&lt;/a&gt; - beanshell.org (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.beanshell.org/manual/bshmanual.html&quot;&gt;BeanShell User&apos;s Manual&lt;/a&gt; - beanshell.org (HTML)&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Cilk&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://par.tuwien.ac.at/material/manual-5.4.6.pdf&quot;&gt;Cilk 5.4.6 Reference Manual&lt;/a&gt; (PDF)&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;ColdFusion&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/mhenke/CFML-in-100-minutes/blob/master/cfml100mins.markdown&quot;&gt;CFML In 100 Minutes&lt;/a&gt; - J. Casimir&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://learncfinaweek.com&quot;&gt;Learn CF in a Week&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Cool&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.eecis.udel.edu/~cavazos/cisc672/docs/cool-manual.pdf&quot;&gt;CoolAid: The Cool 2013 Reference Manual&lt;/a&gt; (PDF)&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Coq&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;http://adam.chlipala.net/cpdt/html/toc.html&quot;&gt;Certified Programming with Dependent Types&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.cis.upenn.edu/~bcpierce/sf/&quot;&gt;Software Foundations&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;CUDA&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://docs.nvidia.com/pdf/CUDA_C_Best_Practices_Guide.pdf&quot;&gt;CUDA C Best Practices Guide&lt;/a&gt; (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://docs.nvidia.com/pdf/CUDA_C_Programming_Guide.pdf&quot;&gt;CUDA C Programming Guide&lt;/a&gt; (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.nvidia.com/content/cudazone/download/OpenCL/NVIDIA_OpenCL_ProgrammingGuide.pdf&quot;&gt;OpenCL Programming Guide for CUDA Architecture&lt;/a&gt; (PDF)&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;DB2&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;http://public.dhe.ibm.com/software/dw/db2/express-c/wiki/Getting_Started_with_DB2_Express_v9.7_p4.pdf&quot;&gt;Getting started with DB2 Express-C&lt;/a&gt; (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://public.dhe.ibm.com/software/dw/db2/express-c/wiki/Getting_Started_with_IBM_Data_Studio_for_DB2_p3.pdf&quot;&gt;Getting started with IBM Data Studio for DB2&lt;/a&gt; (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://public.dhe.ibm.com/software/dw/db2/express-c/wiki/Getting_Started_with_DB2_App_Dev_p2.pdf&quot;&gt;Getting started with IBM DB2 development&lt;/a&gt; (PDF)&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;DBMS&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.lincoste.com/ebooks/english/pdf/computers/database_management_systems.pdf&quot;&gt;Database Management Systems eBooks For All Edition&lt;/a&gt; (PDF)&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;DTrace&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;http://dtrace.org/guide/preface.html&quot;&gt;IllumOS Dynamic Tracing Guide&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Emacs&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.gnu.org/software/emacs/manual/eintr.html&quot;&gt;An Introduction to Programming in Emacs Lisp&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.finseth.com/craft/&quot;&gt;Emacs for the Modern World&lt;/a&gt; (HTML)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.gnu.org/software/emacs/manual/elisp.html&quot;&gt;GNU Emacs Lisp Reference Manual&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.gnu.org/software/emacs/manual/emacs.html&quot;&gt;GNU Emacs Manual&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Embedded Systems&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.learn-c.com&quot;&gt;Control and Embedded Systems&lt;/a&gt; (HTML)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.cs.indiana.edu/~geobrown/book.pdf&quot;&gt;Discovering the STM32 Microcontroller&lt;/a&gt; (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.phaedsys.com/principals/bytecraft/bytecraftdata/bcfirststeps.pdf&quot;&gt;First Steps with Embedded Systems&lt;/a&gt; - Byte Craft Limited (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://ptolemy.berkeley.edu/books/leeseshia/releases/LeeSeshia_DigitalV2_2.pdf&quot;&gt;Introduction to Embedded Systems, Second Edition&lt;/a&gt; - Edward Ashford Lee, Sanjit Arunkumar Seshia (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.embeddedrelated.com/showarticle/453.php&quot;&gt;Introduction to Microcontrollers&lt;/a&gt; (HTML)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://freertos.org/Documentation/RTOS_book.html&quot;&gt;Mastering the FreeRTOS Real Time Kernel - a Hands On Tutorial Guide&lt;/a&gt; - freertos.org (&lt;a href=&quot;https://freertos.org/fr-content-src/uploads/2018/07/161204_Mastering_the_FreeRTOS_Real_Time_Kernel-A_Hands-On_Tutorial_Guide.pdf&quot;&gt;PDF&lt;/a&gt;)&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;ESP8266&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://leanpub.com/ESP8266_ESP32&quot;&gt;Kolban&apos;s book on the ESP32 &amp;amp; ESP8266&lt;/a&gt; &lt;em&gt;(Leanpub account or valid email requested)&lt;/em&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Firefox OS&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://leanpub.com/quickguidefirefoxosdevelopment/read&quot;&gt;Quick Guide For Firefox OS App Development: Creating HTML5 based apps for Firefox OS&lt;/a&gt; - Andre Garzia&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;FreeBSD&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.freebsd.org/docs/books.html&quot;&gt;Books and Articles from FreeBSD Site&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.lemis.com/grog/Documentation/CFBSD/&quot;&gt;The Complete FreeBSD&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.bitsinthewind.com/about-dac/publications/using-c-on-the-unix-system&quot;&gt;Using C on the UNIX System&lt;/a&gt; - David A. Curry&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Hack&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://docs.hhvm.com/hack/&quot;&gt;Hack Documentation&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Hadoop&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.packtpub.com/free-ebooks/big-data-analytics-hadoop-3&quot;&gt;Big Data Analytics with Hadoop 3&lt;/a&gt; - Sridhar Alla (Packt account &lt;em&gt;required&lt;/em&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://docs.cloudera.com/documentation/enterprise/latest/PDF/cloudera-impala.pdf&quot;&gt;Cloudera Impala&lt;/a&gt; - John Russel (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://lintool.github.io/MapReduceAlgorithms/MapReduce-book-final.pdf&quot;&gt;Data-Intensive Text Processing with MapReduce&lt;/a&gt; (Jimmy Lin and Chris Dyer) (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.syncfusion.com/ebooks/hadoop-for-windows-succinctly&quot;&gt;Hadoop for Windows Succinctly&lt;/a&gt; - Dave Vickers&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://hadoopilluminated.com/index.html&quot;&gt;Hadoop Illuminated&lt;/a&gt; - Mark Kerzner &amp;amp; Sujee Maniyam&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Idris&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://leanpub.com/gidti&quot;&gt;Gentle Introduction to Dependent Types with Idris&lt;/a&gt; - Boro Sitnikovski &lt;em&gt;(Leanpub account or valid email requested)&lt;/em&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Icon&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.cs.arizona.edu/icon/ibsale.htm&quot;&gt;The Implementation of the Icon Programming Language&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;IoT&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/marcozennaro/IPv6-WSN-book/tree/master/Releases&quot;&gt;IoT in five days- V1.1&lt;/a&gt; (PDF, EPUB)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.packtpub.com/free-ebooks/mastering-internet-things&quot;&gt;Mastering Internet of Things&lt;/a&gt; - Peter Waher (Packt account &lt;em&gt;required&lt;/em&gt;)&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Isabelle/HOL&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www21.in.tum.de/~nipkow/Concrete-Semantics/&quot;&gt;Concrete Semantics - A Proof Assistant Approach by Tobias Nipkow and Gerwin Klein&lt;/a&gt; (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://isabelle.in.tum.de/doc/tutorial.pdf&quot;&gt;Isabelle/HOL - A Proof Assistant for Higher-Order Logic by Tobias Nipkow and Lawrence C. Paulson and Markus Wenzel&lt;/a&gt; (PDF)&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;J&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.jsoftware.com/books/pdf/arithmetic.pdf&quot;&gt;Arithmetic by Kenneth E Iverson&lt;/a&gt; (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.jsoftware.com/books/pdf/brief.pdf&quot;&gt;Brief Reference by Chris Burke and Clifford Reiter&lt;/a&gt; (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.jsoftware.com/books/pdf/calculus.pdf&quot;&gt;Calculus by Kenneth E Iverson&lt;/a&gt; (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.jsoftware.com/papers/camn.htm&quot;&gt;Computers and Mathematical Notation by Kenneth E Iverson&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.jsoftware.com/books/pdf/cmc.pdf&quot;&gt;Concrete Math Companion by Kenneth E Iverson&lt;/a&gt; (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.jsoftware.com/books/pdf/easyj.pdf&quot;&gt;Easy J by Linda Alvord, Norman Thomson&lt;/a&gt; (PDF) (&lt;a href=&quot;http://www.jsoftware.com/books/doc/easyj_doc.zip&quot;&gt;Word DOC&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.jsoftware.com/books/pdf/expmath.pdf&quot;&gt;Exploring Math by Kenneth E Iverson&lt;/a&gt; (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.jsoftware.com/help/jforc/contents.htm&quot;&gt;J for C Programmers by Henry Rich&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.jsoftware.com/help/primer/contents.htm&quot;&gt;J Primer&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.jsoftware.com/help/learning/contents.htm&quot;&gt;Learning J by Roger Stokes- online&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.jsoftware.com/books/pdf/mftl.zip&quot;&gt;Math for the Layman by Kenneth E Iverson&lt;/a&gt; (zipped html+images)&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Java&lt;/h3&gt; 
&lt;h4&gt;Java Reporting&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://leanpub.com/itext_pdfabc&quot;&gt;The ABC of PDF with iText: PDF Syntax essentials&lt;/a&gt; - Bruno Lowagie &lt;em&gt;(Leanpub account or valid email requested)&lt;/em&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://jasperreports.sourceforge.net/JasperReports-Ultimate-Guide-3.pdf&quot;&gt;The JasperReports Ultimate Guide, Third Edition&lt;/a&gt; (PDF)&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Solidity&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.tutorialspoint.com/solidity/index.htm&quot;&gt;Introductory guide for Solidity&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://docs.soliditylang.org&quot;&gt;The Solidity Reference Guide&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Jenkins&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.bogotobogo.com/DevOps/Jenkins/images/Intro_install/jenkins-the-definitive-guide.pdf&quot;&gt;Jenkins: The Definitive Guide&lt;/a&gt; (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.jenkins.io/user-handbook.pdf&quot;&gt;Jenkins User Handbook&lt;/a&gt; (PDF)&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;LaTeX / TeX&lt;/h3&gt; 
&lt;h4&gt;LaTeX&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;http://latex.knobs-dials.com&quot;&gt;Arbitrary LaTex Reference&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/VoLuong/Begin-Latex-in-minutes&quot;&gt;Begin Latex in minutes&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://en.wikibooks.org/wiki/LaTeX&quot;&gt;LaTeX&lt;/a&gt; - Wikibooks&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://goalkicker.com/LaTeXBook/&quot;&gt;LaTex Notes for Professionals&lt;/a&gt; - Compiled from StackOverflow documentation (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://tobi.oetiker.ch/lshort/lshort.pdf&quot;&gt;The Not So Short Introduction to LaTeX&lt;/a&gt; (PDF)&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;TeX&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;http://pgfplots.sourceforge.net/TeX-programming-notes.pdf&quot;&gt;Notes On Programming in TeX&lt;/a&gt; - Christian Feursänger (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://eijkhout.net/texbytopic/texbytopic.html&quot;&gt;TeX by Topic, A TeXnician&apos;s Reference&lt;/a&gt; - Victor Eijkhout&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.gnu.org/software/teximpatient/&quot;&gt;TeX for the Impatient&lt;/a&gt; - Paul Abrahams, Kathryn Hargreaves, and Karl Berry&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Language Agnostic&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;free-programming-books-subjects.md&quot;&gt;BY SUBJECT&lt;/a&gt; This section has been moved to its own file.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Limbo&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;http://doc.cat-v.org/inferno/books/inferno_programming_with_limbo/&quot;&gt;Inferno Programming With Limbo&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Livecode&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.scribd.com/doc/216789127/LiveCode-userguide&quot;&gt;LiveCode userguide&lt;/a&gt; (PDF)&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Make&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://makefiletutorial.com&quot;&gt;Makefile tutorial&lt;/a&gt; - Chase Lambert&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.oreilly.com/openbook/make3/book/index.html&quot;&gt;Managing Projects with GNU Make&lt;/a&gt; - Robert Mecklenburg&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Markdown&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.gitbook.com/book/gitbookio/markdown/details&quot;&gt;Learn Markdown&lt;/a&gt; - Sammy P., Aaron O. (PDF) (EPUB) (MOBI)&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Mathematica&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.mathprogramming-intro.org&quot;&gt;Mathematica® programming: an advanced introduction by Leonid Shifrin&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://mathematica.stackexchange.com/questions/16485/are-you-interested-in-purchasing-david-wagners-power-programming-with-mathemat/22724&quot;&gt;Power Programming with Mathematica&lt;/a&gt; - David B. Wagner&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://reference.wolfram.com/legacy/v5_2/&quot;&gt;Stephen Wolfram&apos;s The Mathematica Book&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://chortle.ccsu.edu/VectorLessons/index.html&quot;&gt;Vector Math for 3d Computer Graphics&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.wolfram.com/wolfram-u/catalog/product-training/mathematica/&quot;&gt;Wolfram Mathematica Product Training: Wolfram U&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;MATLAB&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.science.smith.edu/~jcardell/Courses/EGR326/Intro-to-MATLAB.pdf&quot;&gt;An Interactive Introduction to MATLAB&lt;/a&gt; (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.maths.dundee.ac.uk/software/MatlabNotes.pdf&quot;&gt;An Introduction to MATLAB&lt;/a&gt; (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.intechopen.com/books/applications-of-matlab-in-science-and-engineering&quot;&gt;Applications of MATLAB in Science and Engineering&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.mathworks.com/moler/exm/index.html?requestedDomain=www.mathworks.com&amp;amp;nocookie=true&quot;&gt;Experiments with MATLAB&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://cnx.org/exports/3a643c1f-c1ba-4c2a-8065-317a1f2b1add@18.1.pdf/freshman-engineering-problem-solving-with-matlab-18.1.pdf&quot;&gt;Freshman Engineering Problem Solving with MATLAB&lt;/a&gt; (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.mathworks.com/tutorials&quot;&gt;Interactive Tutorials for MATLAB, Simulink, Signal Processing, Controls, and Computational Mathematics&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.mccormick.northwestern.edu/documents/students/undergraduate/introduction-to-matlab.pdf&quot;&gt;Introduction to MATLAB for Engineering Students&lt;/a&gt; - David Houcque (PDF) (1.2, 2005)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.intechopen.com/books/matlab-a-fundamental-tool-for-scientific-computing-and-engineering-applications-volume-1&quot;&gt;MATLAB - A Fundamental Tool for Scientific Computing and Engineering Applications - Volume 1&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.intechopen.com/books/matlab-a-ubiquitous-tool-for-the-practical-engineer&quot;&gt;MATLAB - A Ubiquitous Tool for the Practical Engineer&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.intechopen.com/books/matlab-for-engineers-applications-in-control-electrical-engineering-it-and-robotics&quot;&gt;MATLAB for Engineers: Applications in Control, Electrical Engineering, IT and Robotics&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://goalkicker.com/MATLABBook&quot;&gt;MATLAB Notes for professionals&lt;/a&gt; - Compiled from StackOverflow documentation (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://en.wikibooks.org/wiki/MATLAB_Programming&quot;&gt;MATLAB Programming&lt;/a&gt; - Wikibooks&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.syncfusion.com/resources/techportal/ebooks/matlab&quot;&gt;MATLAB Succinctly, Syncfusion&lt;/a&gt; (PDF, Kindle) (email address &lt;em&gt;requested&lt;/em&gt;, not required)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.mathworks.com/moler/index_ncm.html?requestedDomain=www.mathworks.com&amp;amp;nocookie=true&quot;&gt;Numerical Computing with MATLAB&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://greenteapress.com/matlab/index.html&quot;&gt;Physical Modeling in MATLAB&lt;/a&gt; - Alan B. Downey&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.math.ust.hk/~machas/scientific-computing.pdf&quot;&gt;Scientific Computing&lt;/a&gt; - Jeffrey R. Chasnov (PDF)&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Maven&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://books.sonatype.com/m2eclipse-book/reference/index.html&quot;&gt;Developing with Eclipse and Maven&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://books.sonatype.com/mvnex-book/reference/public-book.html&quot;&gt;Maven by Example&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://books.sonatype.com/mvnref-book/reference/public-book.html&quot;&gt;Maven: The Complete Reference&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://books.sonatype.com/nexus-book/reference/&quot;&gt;Repository Management with Nexus&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Mercurial&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://hginit.github.io&quot;&gt;Hg Init: a Mercurial Tutorial&lt;/a&gt; - Joel Spolsky&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://hgbook.red-bean.com&quot;&gt;Mercurial: The Definitive Guide&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://book.mercurial-scm.org&quot;&gt;Mercurial: The Definitive Guide 2nd edition&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Mercury&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.mercurylang.org/information/doc-release/user_guide.pdf&quot;&gt;The Mercury Users&apos; Guide&lt;/a&gt; (PDF)&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Modelica&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;http://book.xogeny.com&quot;&gt;Modelica by Example&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;.NET Core&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/thangchung/clean-code-dotnet&quot;&gt;Clean Code .NET&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.syncfusion.com/succinctly-free-ebooks/entity-frame-work-core-succinctly&quot;&gt;Entity Framework Core Succinctly&lt;/a&gt; - Ricardo Peres&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://docs.microsoft.com/en-us/dotnet/&quot;&gt;.NET documentation - Microsoft Docs&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.syncfusion.com/ebooks/using-netcore-docker-and-kubernetes-succinctly&quot;&gt;Using .NET Core, Docker, and Kubernetes Succinctly&lt;/a&gt; - Michele Aponte&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;.NET Framework&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.syncfusion.com/ebooks/akka_net_succinctly&quot;&gt;Akka.NET Succinctly&lt;/a&gt; - Zoran Maksimovic&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.syncfusion.com/ebooks/application_security_in_net_succinctly&quot;&gt;Application Security in .NET Succinctly&lt;/a&gt; - Stan Drapkin&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.syncfusion.com/ebooks/cryptography_in_net_succinctly&quot;&gt;Cryptography in .NET Succinctly&lt;/a&gt; - Dirk Strauss&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://weblogs.asp.net/zeeshanhirani/my-christmas-present-to-the-entity-framework-community&quot;&gt;Entity Framework&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://en.wikibooks.org/wiki/Game_Creation_with_XNA&quot;&gt;Game Creation with XNA&lt;/a&gt; - Wikibooks&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.syncfusion.com/ebooks/getting-the-most-from-linqpad-succinctly&quot;&gt;Getting the Most from LINQPad Succinctly&lt;/a&gt; - José Roberto Olivas Mendoza&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.syncfusion.com/ebooks/monogame_succinctly&quot;&gt;MonoGame Succinctly&lt;/a&gt; - Jim Perry&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://foxcentral.net/microsoft/NETforVFPDevelopers.htm&quot;&gt;.NET for Visual FoxPro Developers&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://goalkicker.com/DotNETFrameworkBook/&quot;&gt;.NET Framework Notes for Professionals&lt;/a&gt; - Compiled from StackOverflow Documentation (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.red-gate.com/library/net-performance-testing-and-optimization-the-complete-guide&quot;&gt;.NET Performance Testing and Optimization - The Complete Guide&lt;/a&gt; - Paul Glavich, Chris Farrell (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.syncfusion.com/ebooks/nuget-in-house-succinctly&quot;&gt;NuGet In-House Succinctly&lt;/a&gt; - José Roberto Olivas Mendoza&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.syncfusion.com/ebooks/rider-succinctly&quot;&gt;Rider Succinctly&lt;/a&gt; - Dmitri Nesteruk&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://assets.red-gate.com/community/books/under-the-hood-of-net-memory-management.pdf&quot;&gt;Under the Hood of .NET Memory Management&lt;/a&gt; - Chris Farrell, Nick Harrison (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.infoq.com/minibooks/vsnettt&quot;&gt;Visual Studio .NET Tips and Tricks&lt;/a&gt; (VS 2003-2005 only)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.syncfusion.com/ebooks/visual-studio-2019-succinctly&quot;&gt;Visual Studio 2019 Succinctly&lt;/a&gt; - Alessandro Del Sole&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Oberon&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://inf.ethz.ch/personal/wirth/AD.pdf&quot;&gt;Algorithms and Data-Structures&lt;/a&gt; - Niklaus Wirth (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://ssw.jku.at/Research/Books/Oberon2.pdf&quot;&gt;Object-Oriented Programming in Oberon-2&lt;/a&gt; - Hanspeter Mössenböck (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.inf.ethz.ch/personal/wirth/ProgInOberonWR.pdf&quot;&gt;Programming in Oberon&lt;/a&gt; - Niklaus Wirth (PDF)&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Octave&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://en.wikibooks.org/wiki/Octave_Programming_Tutorial&quot;&gt;Octave Programming&lt;/a&gt; - Wikibooks&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;OpenMP&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;http://bisqwit.iki.fi/story/howto/openmp/&quot;&gt;A Guide To OpenMP&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.openmp.org/mp-documents/OpenMP4.0.0.pdf&quot;&gt;OpenMP Application Programming Interface Standard Version 4.0&lt;/a&gt; (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.openmp.org/wp-content/uploads/OpenMP-API-Specification-5.0.pdf&quot;&gt;OpenMP Application Programming Interface Standard Version 5.0&lt;/a&gt; (PDF)&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;OpenResty&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.gitbook.com/book/openresty/programming-openresty/details&quot;&gt;Programming OpenResty&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;OpenSCAD&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://en.wikibooks.org/wiki/OpenSCAD_User_Manual&quot;&gt;OpenSCAD User Manual&lt;/a&gt; - Wikibooks&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;TrueOS&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.trueos.org/handbook/trueos.html&quot;&gt;TrueOS® Users Handbook&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;PicoLisp&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/tj64/picolisp-by-example&quot;&gt;PicoLisp by Example&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/tj64/picolisp-works&quot;&gt;PicoLisp Works&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;PowerShell&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://leanpub.com/aunixpersonsguidetopowershell&quot;&gt;A Unix Person&apos;s Guide to PowerShell&lt;/a&gt; - The DevOps Collective, Inc. (PDF, ePub, MOBI, HTML) &lt;em&gt;(Leanpub account or valid email requested)&lt;/em&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://leanpub.com/creatinghtmlreportsinwindowspowershell&quot;&gt;Creating HTML Reports in PowerShell&lt;/a&gt; - The DevOps Collective, Inc. (PDF, ePub, MOBI, HTML) &lt;em&gt;(Leanpub account or valid email requested)&lt;/em&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://leanpub.com/devopstheopsperspective&quot;&gt;DevOps: The Ops Perspective&lt;/a&gt; - The DevOps Collective, Inc. (PDF, ePub, MOBI, HTML) &lt;em&gt;(Leanpub account or valid email requested)&lt;/em&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://leanpub.com/ditchexcelmakinghistoricalandtrendreportsinpowershell&quot;&gt;Ditch Excel: Making Historical &amp;amp; Trend Reports in PowerShell&lt;/a&gt; - The DevOps Collective, Inc. (PDF, ePub, MOBI, HTML) &lt;em&gt;(Leanpub account or valid email requested)&lt;/em&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://ravichaganti.com/ebooks/AlaymansguidetoPowerShell2remotingv2.pdf&quot;&gt;Layman’s Guide to PowerShell 2.0 remoting&lt;/a&gt; (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.packtpub.com/free-ebooks/learn-powershell-core-60&quot;&gt;Learn PowerShell Core 6.0&lt;/a&gt; - David das Neves, Jan-Hendrik Peters (Packt account &lt;em&gt;required&lt;/em&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://learnxinyminutes.com/docs/powershell/&quot;&gt;Learn PowerShell in Y Minutes&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://community.idera.com/powershell/powertips/b/ebookv2#pi619PostSortOrder=Ascending&quot;&gt;Mastering PowerShell v2&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://leanpub.com/powershell101&quot;&gt;PowerShell 101: The No-Nonsense Beginner’s Guide to PowerShell&lt;/a&gt; - Mike F. Robbins &lt;em&gt;(Leanpub account or valid email requested)&lt;/em&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.jonathanmedd.net/wp-content/uploads/2010/09/PowerShell_2_One_Cmdlet_at_a_Time.pdf&quot;&gt;PowerShell 2.0 – One CMDLET At A Time&lt;/a&gt; (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://goalkicker.com/PowerShellBook/&quot;&gt;PowerShell Notes for Professionals&lt;/a&gt; - Compiled from StackOverflow documentation (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.syncfusion.com/resources/techportal/ebooks/powershell&quot;&gt;PowerShell Succinctly, Syncfusion&lt;/a&gt; (PDF, Kindle) (email address &lt;em&gt;requested&lt;/em&gt;, not required)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://leanpub.com/powershelltips&quot;&gt;PowerShell Tips to Write By&lt;/a&gt; - Adam Bertram &lt;em&gt;(Leanpub account or valid email requested)&lt;/em&gt; (:construction: &lt;em&gt;in process&lt;/em&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://leanpub.com/secretsofpowershellremoting&quot;&gt;Secrets of PowerShell Remoting&lt;/a&gt; - The DevOps Collective, Inc. (PDF, ePub, MOBI, HTML) &lt;em&gt;(Leanpub account or valid email requested)&lt;/em&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://leanpub.com/thebigbookofpowershellerrorhandling&quot;&gt;The Big Book of PowerShell Error Handling&lt;/a&gt; - The DevOps Collective, Inc. (PDF, ePub, MOBI, HTML) &lt;em&gt;(Leanpub account or valid email requested)&lt;/em&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://leanpub.com/thebigbookofpowershellgotchas&quot;&gt;The Big Book of PowerShell Gotchas&lt;/a&gt; - The DevOps Collective, Inc. (PDF, ePub, MOBI, HTML) &lt;em&gt;(Leanpub account or valid email requested)&lt;/em&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://leanpub.com/themonadmanifestoannotated&quot;&gt;The Monad Manifesto - Annotated&lt;/a&gt; - The DevOps Collective, Inc. (PDF, ePub, MOBI, HTML) &lt;em&gt;(Leanpub account or valid email requested)&lt;/em&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://leanpub.com/windowspowershellnetworkingguide&quot;&gt;The PowerShell + DevOps Global Summit Manual for Summiteers&lt;/a&gt; - The DevOps Collective, Inc. (PDF, ePub, MOBI, HTML) &lt;em&gt;(Leanpub account or valid email requested)&lt;/em&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://leanpub.com/whypowershell&quot;&gt;Why PowerShell?&lt;/a&gt; - The DevOps Collective, Inc. (PDF, ePub, MOBI, HTML) &lt;em&gt;(Leanpub account or valid email requested)&lt;/em&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://leanpub.com/windowspowershellnetworkingguide&quot;&gt;Windows PowerShell Networking Guide&lt;/a&gt; - The DevOps Collective, Inc. (PDF, ePub, MOBI, HTML) &lt;em&gt;(Leanpub account or valid email requested)&lt;/em&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Processing&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;http://natureofcode.com/book/&quot;&gt;The Nature of Code: Simulating Natural Systems with Processing&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;PureScript&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://leanpub.com/purescript/read&quot;&gt;PureScript By Example&lt;/a&gt; - Phil Freeman&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;QML&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;http://qmlbook.github.io&quot;&gt;Qt5 Cadaques&lt;/a&gt; - Juergen Bocklage-Ryannel and Johan Thelin (HTML, PDF, ePub) (:construction: &lt;em&gt;in process&lt;/em&gt;)&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;R&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;http://adv-r.had.co.nz&quot;&gt;Advanced R Programming&lt;/a&gt; - Hadley Wickham&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://cran.r-project.org/doc/manuals/R-intro.html&quot;&gt;An Introduction to R&lt;/a&gt; -David M. Smith and William N. Venables&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://web.stanford.edu/~hastie/ISLR2/ISLRv2_website.pdf&quot;&gt;An Introduction to Statistical Learning with Applications in R&lt;/a&gt; - Gareth James, Daniela Witten, Trevor Hastie and Robert Tibshirani (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://bookdown.org/yihui/blogdown/&quot;&gt;blogdown: Creating Websites with R Markdown&lt;/a&gt; - Yihui Xie, Amber Thomas, Alison Presmanes Hill&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.cookbook-r.com&quot;&gt;Cookbook for R&lt;/a&gt; - Winston Chang&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://rafalab.github.io/dsbook/&quot;&gt;Data Analysis and Prediction Algorithms with R&lt;/a&gt; - Rafael A. Irizarry&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://leanpub.com/dataanalysisforthelifesciences&quot;&gt;Data Analysis for the Life Sciences&lt;/a&gt; - Rafael A Irizarry, Michael I Love &lt;em&gt;(Leanpub account or valid email requested)&lt;/em&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://csgillespie.github.io/efficientR/&quot;&gt;Efficient R programming&lt;/a&gt; - Colin Gillespie, Robin Lovelace&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://leanpub.com/exdata&quot;&gt;Exploratory Data Analysis with R&lt;/a&gt; - Roger D. Peng &lt;em&gt;(Leanpub account or valid email requested)&lt;/em&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://otexts.com/fpp3/&quot;&gt;Forecasting: Principles and Practice&lt;/a&gt; - Rob J Hyndman and George Athanasopoulos&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://dcl-prog.stanford.edu&quot;&gt;Functional Programming&lt;/a&gt; - Sara Altman, Bill Behrman and Hadley Wickham&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/gjkerns/IPSUR&quot;&gt;Introduction to Probability and Statistics Using R&lt;/a&gt; - G. Jay Kerns (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://learningstatisticswithr.com/book/&quot;&gt;Learning Statistics with R&lt;/a&gt; - Danielle Navarro&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://ismayc.github.io/moderndiver-book/&quot;&gt;ModernDive&lt;/a&gt; - Chester Ismay and Albert Y. Kim&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://cran.r-project.org/doc/contrib/Faraway-PRA.pdf&quot;&gt;Practical Regression and Anova using R&lt;/a&gt; - Julian J. Faraway (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://r4ds.had.co.nz&quot;&gt;R for Data Science&lt;/a&gt; - Garrett Grolemund and Hadley Wickham&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.columbia.edu/~cjd11/charles_dimaggio/DIRE/resources/spatialEpiBook.pdf&quot;&gt;R for Spatial Analysis&lt;/a&gt; (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.johndcook.com/blog/r_language_for_programmers&quot;&gt;R Language for Programmers&lt;/a&gt; - John D. Cook&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://goalkicker.com/RBook/&quot;&gt;R Notes for Professionals&lt;/a&gt; - Compiled from StackOverflow Documentation (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://r-pkgs.had.co.nz&quot;&gt;R Packages&lt;/a&gt; - Hadley Wickham&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.columbia.edu/~cjd11/charles_dimaggio/DIRE/resources/R/practicalsBookNoAns.pdf&quot;&gt;R Practicals&lt;/a&gt; (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://en.wikibooks.org/wiki/R_Programming&quot;&gt;R Programming&lt;/a&gt; - Wikibooks&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://leanpub.com/rprogramming&quot;&gt;R Programming for Data Science&lt;/a&gt; - Roger D. Peng &lt;em&gt;(Leanpub account or valid email requested)&lt;/em&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.syncfusion.com/resources/techportal/ebooks/rsuccinctly&quot;&gt;R Succinctly, Syncfusion&lt;/a&gt; (PDF, Kindle) (email address &lt;em&gt;requested&lt;/em&gt;, not required)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://rcompanion.org/handbook/index.html&quot;&gt;Summary and Analysis of Extension Program Evaluation in R&lt;/a&gt; - Salvatore S. Mangiafico&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://topepo.github.io/caret/index.html&quot;&gt;The caret Package&lt;/a&gt; - Max Kuhn&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.burns-stat.com/pages/Tutor/R_inferno.pdf&quot;&gt;The R Inferno&lt;/a&gt; - Patrick Burns (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://stat.ethz.ch/R-manual/R-patched/doc/html&quot;&gt;The R Language&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://cran.r-project.org/manuals.html&quot;&gt;The R Manuals&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://tidytextmining.com&quot;&gt;Tidy Text Mining with R&lt;/a&gt; - Julia Silge and David Robinson&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Racket&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://htdp.org/2019-02-24/&quot;&gt;How to Design Programs&lt;/a&gt; - Matthias Felleisen, Robert Bruce Findler, Matthew Flatt, Shriram Krishnamurthi&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://cs.brown.edu/courses/cs173/2012/book/index.html&quot;&gt;Programming Languages: Application and Interpretation&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://docs.racket-lang.org/guide/index.html&quot;&gt;The Racket Guide&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Raku&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://kyclark.gitbooks.io/metagenomics&quot;&gt;Metagenomics&lt;/a&gt; - Ken Youens-Clark&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://andrewshitov.com/wp-content/uploads/2020/01/Perl-6-at-a-Glance.pdf&quot;&gt;Perl 6 at a Glance&lt;/a&gt; - Andrew Shitov (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://raku.guide&quot;&gt;Raku Guide&lt;/a&gt; (HTML) &lt;a href=&quot;https://github.com/hankache/rakuguide&quot;&gt;(PDF)&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://andrewshitov.com/wp-content/uploads/2020/01/Raku-One-Liners.pdf&quot;&gt;Raku One-Liners&lt;/a&gt; - Andrew Shitov (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://en.wikibooks.org/wiki/Raku_Programming&quot;&gt;Raku Programming&lt;/a&gt; - Wikibooks (HTML)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/LaurentRosenfeld/think_raku/raw/master/PDF/think_raku.pdf&quot;&gt;Think Raku&lt;/a&gt; - Laurent Rosenfeld, with Allen B. Downey (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/perl6/book/&quot;&gt;Using Perl 6&lt;/a&gt; (:construction: &lt;em&gt;project is dead&lt;/em&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://learnxinyminutes.com/docs/raku/&quot;&gt;X=Raku&lt;/a&gt; - Learn X in Y minutes (HTML)&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Raspberry Pi&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://leanpub.com/RPiMRE/read&quot;&gt;Raspberry Pi: Measure, Record, Explore&lt;/a&gt; - Malcolm Maclean (HTML)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.cs.unca.edu/~bruce/Fall14/360/RPiUsersGuide.pdf&quot;&gt;Raspberry Pi Users Guide - (2012)&lt;/a&gt; - Eben Upton (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://magpi.raspberrypi.com/books/projects-1&quot;&gt;The Official Raspberry Pi Project Book 1 (2015)&lt;/a&gt; (PDF)&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;REBOL&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.lulu.com/shop/nick-antonaccio/learn-rebol/ebook/product-17383182.html&quot;&gt;Learn REBOL&lt;/a&gt; - Nick Antonaccio&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Sage&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;http://wstein.org/books/sagebook/sagebook.pdf&quot;&gt;Sage for Power Users&lt;/a&gt; - William Stein (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.sagemath.org/doc/&quot;&gt;The Sage Manuals&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Scilab&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;http://forge.scilab.org/index.php/p/docintrotoscilab/downloads/&quot;&gt;Introduction to Scilab&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://forge.scilab.org/index.php/p/docprogscilab/downloads/&quot;&gt;Programming in Scilab&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://forge.scilab.org/index.php/p/docsciextensions/downloads/&quot;&gt;Writing Scilab Extensions&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Scratch&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;http://scratched.gse.harvard.edu/guide/download.html&quot;&gt;An Introductory Computing Curriculum Using Scratch&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://stwww1.weizmann.ac.il/scratch/scratch_en/&quot;&gt;Computer Science Concepts in Scratch&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://magpi.raspberrypi.com/books/essentials-scratch-v1&quot;&gt;Learn to Code with Scratch&lt;/a&gt; - The MagPi magazine (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://inventwithscratch.com/book/&quot;&gt;Scratch Programming Playground&lt;/a&gt; - Al Sweigart&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Snap&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://snap.berkeley.edu/snapsource/help/SnapManual.pdf&quot;&gt;Snap! Reference Manual&lt;/a&gt; - B. Harvey, J. Mönig (PDF)&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Spark&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.gitbook.com/book/databricks/databricks-spark-knowledge-base/details&quot;&gt;Databricks Spark Knowledge Base&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.gitbook.com/book/databricks/databricks-spark-reference-applications/details&quot;&gt;Databricks Spark Reference Applications&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.gitbook.com/book/jaceklaskowski/mastering-apache-spark/details&quot;&gt;Mastering Apache Spark&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Splunk&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.packtpub.com/free-ebooks/splunk-7x-quick-start-guide&quot;&gt;Splunk 7.x Quick Start Guide&lt;/a&gt; - James H. Baxter (Packt account &lt;em&gt;required&lt;/em&gt;)&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Subversion&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;http://ptgmedia.pearsoncmg.com/images/0131855182/downloads/Nagel_book.pdf&quot;&gt;Subversion Version Control&lt;/a&gt; (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://svnbook.red-bean.com&quot;&gt;Version Control with Subversion&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;TEI&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://books.openedition.org/oep/426&quot;&gt;What is the Text Encoding Initiative?&lt;/a&gt; - Lou Bernard&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Teradata&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.info.teradata.com&quot;&gt;Teradata Books&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Tizen&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://developer.tizen.org/sites/default/files/documentation/guide_to_developing_tizen_native_application_en_2.pdf&quot;&gt;Guide to Developing Tizen Native Application&lt;/a&gt; - Jung, Dong-Geun (Denis.Jung) (PDF)&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;TLA&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;http://research.microsoft.com/en-us/um/people/lamport/tla/book.html&quot;&gt;Specifying Systems: The TLA+ Language and Tools for Hardware and Software Engineers&lt;/a&gt; - Leslie Lamport (Postscript or PDF)&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Deno&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://deno.land/manual&quot;&gt;Deno Manual&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://flaviocopes.com/deno&quot;&gt;FlavioCopes Deno Handbook&lt;/a&gt; - &lt;em&gt;free PDF with registration&lt;/em&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Unix&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.oliverelliott.org/article/computing/tut_unix/&quot;&gt;An Introduction to Unix&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://beej.us/guide/bgipc/&quot;&gt;Beej&apos;s Guide to Unix Interprocess Communication&lt;/a&gt; - B. Hall (HTML,PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.lemis.com/grog/Documentation/Lions/&quot;&gt;Commentary on the Sixth Edition UNIX Operating System&lt;/a&gt; - J. Lions&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://homepages.uc.edu/~thomam/Intro_Unix_Text/TOC.html&quot;&gt;INTRODUCTION TO UNIX&lt;/a&gt; - Mark A. Thomas&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/mrzool/unix-as-ide&quot;&gt;Unix as IDE&lt;/a&gt; - Tom Ryder (epub, mobi)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.cs.bu.edu/teaching/unix/reference/&quot;&gt;UNIX Commands and Concepts&lt;/a&gt; - Robert I. Pitts&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://web.stanford.edu/class/cs124/kwc-unix-for-poets.pdf&quot;&gt;Unix for Poets&lt;/a&gt; - Kenneth Ward Church (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://web.archive.org/web/20210912091852/https://cb.vu/unixtoolbox.xhtml&quot;&gt;Unix Toolbox&lt;/a&gt; - Colin Barschel &lt;em&gt;(:card_file_box: archived)&lt;/em&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.ee.surrey.ac.uk/Teaching/Unix/&quot;&gt;UNIX Tutorial for Beginners&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Vulkan&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://vulkan-tutorial.com&quot;&gt;Vulkan Tutorial&lt;/a&gt; - Alexander Overvoorde (EPUB, HTML, PDF) (C++)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/Naitsirc98/Vulkan-Tutorial-Java&quot;&gt;Vulkan Tutorial Java&lt;/a&gt; - Cristian Herrera et al (Java)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/bwasty/vulkan-tutorial-rs&quot;&gt;Vulkan Tutorial RS&lt;/a&gt; - Benjamin Wasty et al. (:construction: &lt;em&gt;in process&lt;/em&gt;) (Rust)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://vulkano.rs/guide/introduction&quot;&gt;Vulkano&lt;/a&gt; - Tomaka et al. (HTML) (Rust)&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Workflow&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://leanpub.com/declarepeaceonvms/read&quot;&gt;Declare Peace on Virtual Machines. A guide to simplifying vm-based development on a Mac&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;xBase (dBase / Clipper / Harbour)&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://en.wikibooks.org/wiki/Application_Development_with_Harbour&quot;&gt;Application Development with Harbour&lt;/a&gt; - Wikibooks&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://web.archive.org/web/20190516192814/http://www.ousob.com/ng/clguide/&quot;&gt;CA-Clipper 5.2 Norton Guide&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://en.wikibooks.org/wiki/Clipper_Tutorial%3A_a_Guide_to_Open_Source_Clipper(s)&quot;&gt;Clipper Tutorial: a Guide to Open Source Clipper(s)&lt;/a&gt; - Wikibooks&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;BY SUBJECT&lt;/h2&gt; 
&lt;h3&gt;Cellular Automata&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.wolframscience.com/nksonline/toc.html&quot;&gt;A New Kind of Science&lt;/a&gt; - Stephen Wolfram&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Competitive Programming&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://cses.fi/book/book.pdf&quot;&gt;Competitive Programmer&apos;s Handbook&lt;/a&gt; - Antti Laaksonen (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://cpbook.net/#CP1details&quot;&gt;Competitive Programming, 1st Edition&lt;/a&gt; - Steven Halim &lt;a href=&quot;https://www.comp.nus.edu.sg/~stevenha/myteaching/competitive_programming/cp1.pdf&quot;&gt;(PDF)&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://cpbook.net/#CP2details&quot;&gt;Competitive Programming, 2nd Edition&lt;/a&gt; - Steven Halim &lt;a href=&quot;https://www.comp.nus.edu.sg/~stevenha/myteaching/competitive_programming/cp2.pdf&quot;&gt;(PDF)&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.csc.kth.se/~jsannemo/slask/main.pdf&quot;&gt;Principles of Algorithmic Problem Solving&lt;/a&gt; - Johan Sannemo (PDF)&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Computer Organization and Architecture&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.cse.iitd.ac.in/~srsarangi/archbooksoft.html&quot;&gt;Basic Computer Architecture&lt;/a&gt; - Smruti R. Sarangi (HTML, PDF, Slides, Videos)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://faculty.etsu.edu/tarnoff/138292&quot;&gt;Computer Organization and Design Fundamentals&lt;/a&gt; - David Tarnoff (PDF)&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Computer Science&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.cs.cmu.edu/~15110-s13/Wing06-ct.pdf&quot;&gt;Computational Thinking&lt;/a&gt; - Jeannette Wing, Carnegie-Mellon University (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://bitbucket.org/chrisbourke/computersciencei/src&quot;&gt;Computer Science I - Draft&lt;/a&gt; - Dr. Chris Bourke (PDF) (:construction: &lt;em&gt;in process&lt;/em&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://cse.unl.edu/~cbourke/ComputerScienceTwo.pdf&quot;&gt;Computer Science II - Draft&lt;/a&gt; - Dr. Chris Bourke (PDF) (:construction: &lt;em&gt;in process&lt;/em&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.openbookproject.net/books/StudentCSP/&quot;&gt;CS Principles: Big Ideas in Programming&lt;/a&gt; - Mark Guzdial and Barbara Ericson (HTML)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://leanpub.com/whattolookforinacodereview&quot;&gt;What to Look for in a Code Review&lt;/a&gt; - Trisha Gee (HTML, PDF, EPUB, Kindle) &lt;em&gt;(Leanpub account or valid email requested)&lt;/em&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://leanpub.com/firstyearincode&quot;&gt;Your First Year in Code&lt;/a&gt; - Isaac Lyman (HTML, PDF, EPUB, Kindle) &lt;em&gt;(Leanpub account or valid email requested)&lt;/em&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Computer Vision&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;http://homepages.inf.ed.ac.uk/rbf/BOOKS/BANDB/bandb.htm&quot;&gt;Computer Vision&lt;/a&gt; - Dana Ballard, Chris Brown&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://szeliski.org/Book/&quot;&gt;Computer Vision: Algorithms and Applications&lt;/a&gt; - Richard Szeliski&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.computervisionmodels.com&quot;&gt;Computer Vision: Models, Learning, and Inference&lt;/a&gt; - Simon J.D. Prince&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://programmingcomputervision.com&quot;&gt;Programming Computer Vision with Python&lt;/a&gt; - Jan Erik Solem&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Misc&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://ithemes.com/wp-content/uploads/downloads/2012/09/10-keys-to-great-landing-pages-eBook.pdf&quot;&gt;10 Keys to Great Landing Pages&lt;/a&gt; - iThemes Media (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.oreilly.com/radar/2016-european-software-development-salary-survey/&quot;&gt;2016 European Software Development Salary Survey&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.oreilly.com/radar/2016-software-development-salary-survey-report/&quot;&gt;2016 Software Development Salary Survey&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://leanpub.com/97-Things-Every-Programmer-Should-Know-Extended&quot;&gt;97 Things Every Programmer Should Know - Extended&lt;/a&gt; &lt;em&gt;(Leanpub account or valid email requested)&lt;/em&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://ocaml-book.com/s/popbook.pdf&quot;&gt;A MACHINE MADE THIS BOOK ten sketches of computer science&lt;/a&gt; - JOHN WHITINGTON (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.ansible.com/ebooks&quot;&gt;Ansible Up &amp;amp; Running (first three chapters)&lt;/a&gt; &lt;em&gt;(account required)&lt;/em&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://solmu.org/pub/help/Asterisk/3nd_Edition_for_Asterisk_1.8&quot;&gt;Asterisk™: The Definitive Guide&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.tec-it.com/download/PDF/Barcode_Reference_EN.pdf&quot;&gt;Barcode Overview&lt;/a&gt; (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.wisdom.weizmann.ac.il/~playbook/&quot;&gt;Come, Let&apos;s Play: Scenario-Based Programming Using Live Sequence Charts&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.usingcsp.com/cspbook.pdf&quot;&gt;Communicating Sequential Processes&lt;/a&gt; - Tony Hoare (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.jackkinsella.ie/books/confessions_of_an_unintentional_cto&quot;&gt;Confessions of an Unintentional CTO: Lessons in Growing a Web App&lt;/a&gt; - Jack Kinsella&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://hintjens.com/books&quot;&gt;Culture &amp;amp; Empire: Digital Revolution&lt;/a&gt; (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://designwithfontforge.com/en-US/index.html&quot;&gt;Design With FontForge&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://designinginterfaces.com&quot;&gt;Designing Interfaces&lt;/a&gt; - Jennifer Tidwell&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://devdocs.io&quot;&gt;DevDocs&lt;/a&gt; - Documents for Developers in 1 place&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.ibm.com/ibm/devops/us/en/resources/dummiesbooks/&quot;&gt;DevOps For Dummies (IBM Edition)&lt;/a&gt; (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.sp4comm.org&quot;&gt;Digital Signal Processing For Communications&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.dspguide.com&quot;&gt;Digital Signal Processing For Engineers and Scientists&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://greenteapress.com/wp/think-dsp&quot;&gt;Digital Signal Processing in Python&lt;/a&gt; - Allen B. Downey&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.lulu.com/shop/luis-enr%C3%ADquez-a/dynamic-linked-libraries-paradigms-of-the-gpl-license-in-contemporary-software/ebook/product-21419788.html&quot;&gt;&quot;DYNAMIC LINKED LIBRARIES&quot;: Paradigms of the GPL license in contemporary software&lt;/a&gt; - Luis A. Enríquez&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://images.guide&quot;&gt;Essential Image Optimization&lt;/a&gt; - Addy Osmani&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://openmymind.net/FoundationsOfProgramming.pdf&quot;&gt;Foundations of Programming&lt;/a&gt; - Karl Seguin (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://basecamp.com/books/getting-real&quot;&gt;Getting Real&lt;/a&gt; - Basecamp, 37signals (&lt;a href=&quot;https://basecamp.com/gettingreal&quot;&gt;HTML&lt;/a&gt;, &lt;a href=&quot;https://basecamp.com/gettingreal/getting-real.pdf&quot;&gt;PDF&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.syncfusion.com/ebooks/google_maps_api_succinctly&quot;&gt;Google Maps API Succinctly&lt;/a&gt; - Mark Lewin&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.lulu.com/shop/ed-johnson/hacknot-essays-on-software-development/ebook/product-17544641.html&quot;&gt;Hacknot: Essays on Software Development&lt;/a&gt; - Ed Johnson&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://andreask.cs.illinois.edu/Teaching/HPCFall2012&quot;&gt;High-Performance Scientific Computing&lt;/a&gt; (class lectures and slides)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.syncfusion.com/ebooks/hololens_succinctly&quot;&gt;HoloLens Succinctly&lt;/a&gt; - Lars Klint&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.fastchip.net/howcomputerswork/p1.html&quot;&gt;How Computers Work&lt;/a&gt; - R. Young&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://softwarebyrob.wpengine.netdna-cdn.com/assets/Software_by_Rob%20_How_to_Become_a%20_Programmer_1.0.pdf&quot;&gt;How to Become a Programmer&lt;/a&gt; (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.digitalocean.com/community/books/how-to-manage-remote-servers-with-ansible-ebook&quot;&gt;How To Manage Remote Servers with Ansible&lt;/a&gt; - Erika Heidi (PDF, EPUB)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://openbookproject.net/thinkcs/&quot;&gt;How to Think Like a Computer Scientist&lt;/a&gt; - Peter Wentworth, Jeffrey Elkner, Allen B. Downey, and Chris Meyers&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://homepages.inf.ed.ac.uk/rbf/BOOKS/PHILLIPS/&quot;&gt;Image Processing in C: Analyzing and Enhancing Digital Images&lt;/a&gt; - Dwayne Phillips&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://web.archive.org/web/20200731035935/https://florida.theorangegrove.org/og/file/49843a6a-9a9d-4bad-b4d4-d053f9cdf73e/1/InfoTechNetworkedEconomy.pdf&quot;&gt;Information Technology and the Networked Economy&lt;/a&gt; - Patrick McKeown (PDF) &lt;em&gt;(:card_file_box: archived)&lt;/em&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://web.corral.tacc.utexas.edu/CompEdu/pdf/isp/EijkhoutIntroSciProgramming-book.pdf&quot;&gt;Introduction to Scientific Programming in C++ and Fortran&lt;/a&gt; - Victor Eijkhout (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.gitbook.com/book/scemama/irpf90/details&quot;&gt;IRPF90 Fortran code generator&lt;/a&gt; - Anthony Scemama&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://progbook.org&quot;&gt;Learn Programming&lt;/a&gt; - Antti Salonen&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://pine.fm/LearnToProgram/&quot;&gt;Learn to Program&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://blog.openshift.com/learning-30-technologies-in-30-days-a-developer-challenge/&quot;&gt;Learning 30 Technologies in 30 Days: A Developer Challenge&lt;/a&gt; - Shekhar Gulati&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://patterns.dataincubator.org/book/&quot;&gt;Linked Data Patterns: A pattern catalogue for modelling, publishing, and consuming Linked Data&lt;/a&gt; - Leigh Dodds, Ian Davis&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://worrydream.com/#!/MagicInk&quot;&gt;Magic Ink: Information Software and The Graphical Interface&lt;/a&gt; - Bret Victor&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://leanpub.com/mobiledevelopersguide&quot;&gt;Mobile Developer&apos;s Guide to the Galaxy&lt;/a&gt; &lt;em&gt;(Leanpub account or valid email requested)&lt;/em&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.wisdom.weizmann.ac.il/~harel/reactive_systems.html&quot;&gt;Modeling Reactive Systems with Statecharts&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.syncfusion.com/ebooks/msix-succinctly&quot;&gt;MSIX Succinctly&lt;/a&gt; - Matteo Pagani&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.cs.cornell.edu/home/kleinber/networks-book/&quot;&gt;Networks, Crowds, and Markets: Reasoning About a Highly Connected World&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://win.ua.ac.be/~sdemey/&quot;&gt;Object-Oriented Reengineering Patterns&lt;/a&gt; - Serge Demeyer, Stéphane Ducasse and Oscar Nierstrasz&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/oreillymedia/open_government&quot;&gt;Open Government; Collaboration, Transparency, and Participation in Practice&lt;/a&gt; - Daniel Lathrop, Laurel Ruma&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://leanpub.com/PDQ&quot;&gt;PDQ: Pretty Darn Quick: An Agile, All-Purpose Methodology&lt;/a&gt; - Jeff Franz-Lien &lt;em&gt;(Leanpub account or valid email requested)&lt;/em&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.cse.buffalo.edu/~rapaport/Papers/phics.pdf&quot;&gt;Philosophy of Computer Science&lt;/a&gt; (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.libpng.org/pub/png/book/&quot;&gt;PNG: The Definitive Guide&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://cslibrary.stanford.edu/102/PointersAndMemory.pdf&quot;&gt;Pointers And Memory&lt;/a&gt; (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://ocw.mit.edu/resources/res-6-004-principles-of-computer-system-design-an-introduction-spring-2009/online-textbook/part_ii_open_5_0.pdf&quot;&gt;Principles of Computer System Design&lt;/a&gt; (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://press.rebus.community/programmingfundamentals/&quot;&gt;Programming Fundamentals&lt;/a&gt; - Kenneth Leroy Busbee, Dave Braunschweig&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://unicodebook.readthedocs.org&quot;&gt;Programming with Unicode&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.oreilly.com/ideas/real-world-maintainable-software&quot;&gt;Real-World Maintainable Software&lt;/a&gt; - Abraham Marin-Perez&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://leanpub.com/manualToAutomatedWithSeleniumIDEAndSahi&quot;&gt;Record-Playback Test Automation: Sahi &amp;amp; Selenium IDE: Critical Evaluation of Record-Playback Automation Tools&lt;/a&gt; - Shashikant Jagtap &lt;em&gt;(Leanpub account or valid email requested)&lt;/em&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://divakarvi.github.io/bk-spca/spca.html&quot;&gt;Scientific Programming and Computer Architecture&lt;/a&gt; - Divakar Viswanath&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://faculty.washington.edu/stiber/pubs/Signal-Computing/Signal%20Computing.pdf&quot;&gt;Signal Computing: Digital Signals in the Software Domain&lt;/a&gt; - Michael Stiber, Bilin Zhang Stiber, Eric C. Larson (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://smallmemory.charlesweir.com/book.html&quot;&gt;Small Memory Software&lt;/a&gt; - Charles Weir, James Noble (HTML)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://almanac.httparchive.org/static/pdfs/web_almanac_2019_en.pdf&quot;&gt;Web Almanac&lt;/a&gt; (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.syncfusion.com/ebooks/writing_native_mobile_apps_in_a_functional_language_succinctly&quot;&gt;Writing Native Mobile Apps in a Functional Language Succinctly&lt;/a&gt; - Vassili Kaplan&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Open Source Ecosystem&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;http://datajournalismhandbook.org&quot;&gt;Data Journalism Handbook&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://archive.org/details/faif-2.0&quot;&gt;Free as in Freedom: Richard Stallman and the free software revolution&lt;/a&gt; - Sam Williams (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://unglue.it/work/136445/&quot;&gt;Free for All&lt;/a&gt; - Peter Wayner&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://shop.fsf.org/product/free-software-free-society-2/&quot;&gt;Free Software, Free Society: Selected Essays of Richard M. Stallman&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.oreilly.com/programming/free/getting-started-with-innersource.csp&quot;&gt;Getting Started with InnerSource&lt;/a&gt; (email address &lt;em&gt;requested&lt;/em&gt;, not required)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://public.dhe.ibm.com/software/dw/db2/express-c/wiki/Getting_started_with_open_source_development_p2.pdf&quot;&gt;Getting started with Open source development&lt;/a&gt; (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://about.gitlab.com/handbook/&quot;&gt;GitLab Handbook&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://opensource.com/resources/ebook/how-get-started-open-source&quot;&gt;How to get started with open source&lt;/a&gt; (ePub &amp;amp; ODT)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://dreamsongs.com/IHE/IHE.html&quot;&gt;Innovation Happens Elsewhere&lt;/a&gt; - Ron Goldman, Richard P. Gabriel&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://do1.dr-chuck.net/net-intro/EN_us/net-intro.pdf&quot;&gt;Introduction to Networking&lt;/a&gt; - Charles Severance (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://open-advice.org&quot;&gt;Open Advice: FOSS: What We Wish We Had Known When We Started&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.oreilly.com/ideas/open-source-in-brazil&quot;&gt;Open source in Brazil&lt;/a&gt; - Andy Oram&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://producingoss.com&quot;&gt;Producing Open Source Software&lt;/a&gt; - Karl Fogel&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.aosabook.org/en/index.html&quot;&gt;The Architecture of Open Source Applications: Vol. 1: Elegance, Evolution, and a Few Fearless Hacks; Vol. 2: Structure, Scale, and a Few More Feerless Hacks&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://artofcommunityonline.org/Art_of_Community_Second_Edition.pdf&quot;&gt;The Art of Community&lt;/a&gt; - Jono Bacon (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.catb.org/esr/writings/cathedral-bazaar/&quot;&gt;The Cathedral and the Bazaar&lt;/a&gt; - Eric S. Raymond&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://futureoftheinternet.org&quot;&gt;The Future of the Internet&lt;/a&gt; - Jonathan Zittrain&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.theopensourceway.org/book/&quot;&gt;The Open Source Way&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://cyber.law.harvard.edu/wealth_of_networks/Main_Page&quot;&gt;The Wealth of Networks: How Social Production Transforms Markets and Freedom&lt;/a&gt; - Yochai Benkler&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Partial Evaluation&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.itu.dk/people/sestoft/pebook/&quot;&gt;Partial Evaluation and Automatic Program Generation&lt;/a&gt; - (PDF) Jones, Gomard and Sestoft&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Professional Development&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.gitbook.com/book/ccd_school/clean-code-developer-com/details&quot;&gt;Clean Code Developer: An initiative for more professionalism in software development&lt;/a&gt; (:construction: &lt;em&gt;in process&lt;/em&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.red-gate.com/library/confessions-of-an-it-manager&quot;&gt;Confessions of an IT Manager&lt;/a&gt; - Phil Factor (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.red-gate.com/library/dont-just-roll-the-dice&quot;&gt;Don&apos;t Just Roll the Dice&lt;/a&gt; - Neil Davidson (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://leanpub.com/dowhatyoulove/read&quot;&gt;How to Do What You Love &amp;amp; Earn What You’re Worth as a Programmer&lt;/a&gt; - Reginald Braithwaite&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://mixmastamyk.bitbucket.io/pro_soft_dev/intro.html&quot;&gt;Professional Software Development For Students&lt;/a&gt; - Mike G. Miller&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://abseil.io/resources/swe-book&quot;&gt;Software Engineering at Google&lt;/a&gt; - Titus Winters, Tom Manshreck &amp;amp; Hyrum Wright&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://softwareconcepts.vercel.app&quot;&gt;Software Environment Concepts&lt;/a&gt; - Amr Elmohamady (:construction: &lt;em&gt;in process&lt;/em&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://leanpub.com/shippingsoftware/read&quot;&gt;What I&apos;ve Learned From Failure&lt;/a&gt; - Reginald Braithwaite&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Regular Expressions&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://learnbyexample.github.io/learn_js_regexp/&quot;&gt;JavaScript RegExp&lt;/a&gt; - Sundeep Agarwal&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://learnbyexample.github.io/py_regular_expressions/&quot;&gt;Python re(gex)?&lt;/a&gt; - Sundeep Agarwal&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://refrf.shreyasminocha.me&quot;&gt;Regular Expressions for Regular Folk&lt;/a&gt; - Shreyas Minocha&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.rexegg.com&quot;&gt;RexEgg&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://learnbyexample.github.io/Ruby_Regexp/&quot;&gt;Ruby Regexp&lt;/a&gt; - Sundeep Agarwal&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.codeproject.com/Articles/9099/The-Minute-Regex-Tutorial&quot;&gt;The 30 Minute Regex Tutorial&lt;/a&gt; - Jim Hollenhorst&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://leanpub.com/bastards-regexes&quot;&gt;The Bastards Book of Regular Expressions: Finding Patterns in Everyday Text&lt;/a&gt; - Dan Nguyen &lt;em&gt;(Leanpub account or valid email requested)&lt;/em&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Search Engines&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.elastic.co/guide/en/elasticsearch/guide/current/index.html&quot;&gt;Elasticsearch: The Definitive Guide&lt;/a&gt; (&lt;a href=&quot;https://github.com/elastic/elasticsearch-definitive-guide&quot;&gt;fork it on GH&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://ciir.cs.umass.edu/irbook&quot;&gt;Search Engines: Information Retrieval in Practice&lt;/a&gt; - W. Bruce Croft, Donald Metzler, Trevor Strohman (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/hectorcorrea/solr-for-newbies&quot;&gt;Solr for newbies workshop (2019)&lt;/a&gt; - Hector Correa (&lt;a href=&quot;https://github.com/hectorcorrea/solr-for-newbies/blob/master/tutorial.pdf&quot;&gt;PDF&lt;/a&gt;)&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Security&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;http://toc.cryptobook.us&quot;&gt;A Graduate Course in Applied Cryptography&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.crypto101.io&quot;&gt;Crypto 101 - Crypto for everyone&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://en.wikibooks.org/wiki/Cryptography&quot;&gt;Cryptography&lt;/a&gt; - Wikibooks (HTML) (:construction: &lt;em&gt;in process&lt;/em&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://unglue.it/work/141611/&quot;&gt;CryptoParty Handbook&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://cacr.uwaterloo.ca/hac/index.html&quot;&gt;Handbook of Applied Cryptography&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://howhttps.works&quot;&gt;How HTTPS works&lt;/a&gt; - dnsimple&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/MHM5000/pass&quot;&gt;How to deal with Passwords&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://ptgmedia.pearsoncmg.com/images/0131407333/downloads/0131407333.pdf&quot;&gt;Intrusion Detection Systems with Snort&lt;/a&gt; (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.feistyduck.com/library/openssl-cookbook/&quot;&gt;OpenSSL Cookbook&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://mobile-security.gitbook.io/mobile-security-testing-guide/&quot;&gt;OWASP Mobile Security Testing Guide&lt;/a&gt; - Bernhard Mueller et al.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.owasp.org/images/1/19/OTGv4.pdf&quot;&gt;OWASP Testing Guide 4.0&lt;/a&gt; (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.troyhunt.com/2011/12/free-ebook-owasp-top-10-for-net.html&quot;&gt;OWASP Top 10 for .NET Developers&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.cl.cam.ac.uk/~rja14/book.html&quot;&gt;Security Engineering&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://web.engr.oregonstate.edu/~rosulekm/crypto/&quot;&gt;The Joy of Cryptography (2021)&lt;/a&gt; - Mike Rosulek (PDF) (:construction: &lt;em&gt;in process&lt;/em&gt;)&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Standards&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;http://refspecs.linuxfoundation.org/lsb.shtml&quot;&gt;Linux Standard Base&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/geoff-codes/posix-standard&quot;&gt;UNIX - The POSIX Standard - IEEE Std 1003.1&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Theoretical Computer Science&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;http://mfleck.cs.illinois.edu/building-blocks/index.html&quot;&gt;Building Blocks for Theoretical Computer Science&lt;/a&gt; - Margaret M. Fleck&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.tac.mta.ca/tac/reprints/articles/22/tr22.pdf&quot;&gt;Category Theory for Computing Science&lt;/a&gt; (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/hmemcpy/milewski-ctfp-pdf&quot;&gt;Category Theory for Programmers&lt;/a&gt; - Bartosz Milewski (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://textbooks.open.tudelft.nl/textbooks/catalog/book/13&quot;&gt;Delftse Foundations of Computation&lt;/a&gt; - Stefan Hugtenburgand, Neil Yorke-Smith @ TU Delft Open (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.smashwords.com/books/view/639609&quot;&gt;Design of a Programmer&lt;/a&gt; - Prakash Hegade (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://homotopytypetheory.org/book/&quot;&gt;Homotopy Type Theory: Univalent Foundations of Mathematics&lt;/a&gt; (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.cse.iitd.ernet.in/~suban/CSL102/&quot;&gt;Introduction to Computer Science&lt;/a&gt; - Prof. Subhashis Banerjee, IIT Delhi&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.computingbook.org&quot;&gt;Introduction to Computing&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://cglab.ca/~michiel/TheoryOfComputation/&quot;&gt;Introduction to Theory of Computation&lt;/a&gt; - Anil Maheshwari and Michiel Smid (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://cs.brown.edu/people/jes/book/&quot;&gt;Models of Computation&lt;/a&gt; - John E. Savage&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.cs.cmu.edu/~rwh/pfpl/2nded.pdf&quot;&gt;Practical Foundations for Programming Languages, Preview&lt;/a&gt; - Robert Harper (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://web.archive.org/web/20150418034451/http://www.cs.jhu.edu/~scott/pl/book/dist/&quot;&gt;Principles of Programming Languages&lt;/a&gt; - Scott F. Smith&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://papl.cs.brown.edu/2019/&quot;&gt;Programming and Programming Languages&lt;/a&gt; - Shriram Krishnamurthi&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.cse.chalmers.se/research/group/logic/book/&quot;&gt;Programming in Martin-Löf&apos;s Type Theory&lt;/a&gt; - Bengt Nordstroem&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://cs.brown.edu/~sk/Publications/Books/ProgLangs/&quot;&gt;Programming Languages: Application and Interpretation (2nd Edition)&lt;/a&gt; - Shriram Krishnamurthi&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://people.cs.uchicago.edu/~blume/classes/aut2008/proglang/text/offline.pdf&quot;&gt;Programming Languages: Theory and Practice&lt;/a&gt; - Robert Harper (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.cs.ru.nl/~herman/onderwijs/semantics2019/wiley.pdf&quot;&gt;Semantics with Applications: A Formal Introduction&lt;/a&gt; - Hanne Riis Nielson, Flemming Nielson (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://mitpress.mit.edu/sicp/&quot;&gt;Structure and Interpretation of Computer Programs&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://sarabander.github.io/sicp/html/index.xhtml&quot;&gt;Structure and Interpretation of Computer Programs&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://self.gutenberg.org/wplbn0002828847-the-black-art-of-programming-by-mcilroy-mark.aspx?&quot;&gt;The Black Art of Programming&lt;/a&gt; - Mark McIlroy&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://kilthub.cmu.edu/articles/The_Craft_of_Programming/6610514&quot;&gt;The Craft of Programming&lt;/a&gt; - John C. Reynolds&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://joshua.smcvt.edu/computation&quot;&gt;Theory of Computation, Making Connections&lt;/a&gt; - Jim Hefferon (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://greenteapress.com/wp/think-complexity-2e/&quot;&gt;Think Complexity&lt;/a&gt; - - Allen B. Downey (2nd Edition) (PDF, HTML)&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Web Performance&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.bookofspeed.com&quot;&gt;Book of Speed&lt;/a&gt; - Stoyan Stefanov&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://designingforperformance.com&quot;&gt;Designing for Performance&lt;/a&gt; - Lara Hogan&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://thisisyuu.github.io/ebook&quot;&gt;High Performance Accelerated Websites&lt;/a&gt; - Anshul (HTML) (:construction: &lt;em&gt;in process&lt;/em&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://hpbn.co&quot;&gt;High Performance Browser Networking&lt;/a&gt; - Ilya Grigorik&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://carlos.bueno.org/optimization/mature-optimization.pdf&quot;&gt;Mature Optimization&lt;/a&gt; - Carlos Bueno (PDF)&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Web Services&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;http://restfulwebapis.org/RESTful_Web_Services.pdf&quot;&gt;RESTful Web Services&lt;/a&gt; (PDF)&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Workflow&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://leanpub.com/declarepeaceonvms/read&quot;&gt;Declare Peace on Virtual Machines. A guide to simplifying vm-based development on a Mac&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Dynamic Binary Instrumentation (DBI) reading</title>
      <link>https://tedneward.github.io/Research/reading/development/dynamic-binary-instrumentation/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">reading/development/dynamic-binary-instrumentation/index.html</guid>
      	<description>
	&lt;ul&gt; 
 &lt;li&gt;Dynamic Binary Instrumentation Primer 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;http://deniable.org/reversing/binary-instrumentation&quot;&gt;http://deniable.org/reversing/binary-instrumentation&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/fdiskyou/DBI&quot;&gt;https://github.com/fdiskyou/DBI&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Cross-ISA Machine Instrumentation using Fast and Scalable Dynamic Binary Translation 
  &lt;ul&gt; 
   &lt;li&gt;Virtual Execution Environments (VEE) 2019&lt;/li&gt; 
   &lt;li&gt;Emilio G. Cota, Luca P. Carloni&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://www.cs.columbia.edu/~cota/pubs/cota_vee19.pdf&quot;&gt;http://www.cs.columbia.edu/~cota/pubs/cota_vee19.pdf&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.sld.cs.columbia.edu/qemu-vee.html&quot;&gt;https://www.sld.cs.columbia.edu/qemu-vee.html&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Optimization of Naïve Dynamic Binary Instrumentation Tools 
  &lt;ul&gt; 
   &lt;li&gt;2011 Ph.D. Dissertation; Reid Kleckner&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://dspace.mit.edu/handle/1721.1/76984&quot;&gt;https://dspace.mit.edu/handle/1721.1/76984&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Security Evaluation of Dynamic Binary Instrumentation Engines 
  &lt;ul&gt; 
   &lt;li&gt;DBI Engine Detection Tool and all PoC code 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://github.com/zhechkoz/PwIN&quot;&gt;https://github.com/zhechkoz/PwIN&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;2018 Master Thesis; Zhechko Zhechev 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://kirschju.re/static/ma_zhechev_2018.pdf&quot;&gt;https://kirschju.re/static/ma_zhechev_2018.pdf&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;REcon Montreal 2018 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://kirschju.re/static/recon_2018_kirsch_zhechev_pwin.pdf&quot;&gt;https://kirschju.re/static/recon_2018_kirsch_zhechev_pwin.pdf&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://infocondb.org/con/recon/recon-2018/pwning-intel-pin-reconsidering-intel-pin-in-context-of-security&quot;&gt;https://infocondb.org/con/recon/recon-2018/pwning-intel-pin-reconsidering-intel-pin-in-context-of-security&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://recon.cx/2018/montreal/schedule/events/145.html&quot;&gt;https://recon.cx/2018/montreal/schedule/events/145.html&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;Pwning Intel piN – Why DBI is unsuitable for security applications 
    &lt;ul&gt; 
     &lt;li&gt;ESORICS 2018&lt;/li&gt; 
     &lt;li&gt;Julian Kirsch, Zhechko Zhechev, Bruno Bierbaumer, Thomas Kittel&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://link.springer.com/chapter/10.1007/978-3-319-99073-6_18&quot;&gt;https://link.springer.com/chapter/10.1007/978-3-319-99073-6_18&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;SoK: Using Dynamic Binary Instrumentation for Security (And How You May Get Caught Red Handed) 
  &lt;ul&gt; 
   &lt;li&gt;Asia Conference on Computer and Communications Security (AsiaCCS) 2019&lt;/li&gt; 
   &lt;li&gt;Daniele Cono D’Elia, Emilio Coppa, Simone Nicchi, Federico Palmaro, Lorenzo Cavallaro&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://doi.org/10.1145/3321705.3329819&quot;&gt;https://doi.org/10.1145/3321705.3329819&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.diag.uniroma1.it/~delia/papers/asiaccs2019.pdf&quot;&gt;https://www.diag.uniroma1.it/~delia/papers/asiaccs2019.pdf&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/season-lab/sok-dbi-security/&quot;&gt;https://github.com/season-lab/sok-dbi-security/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Using Binary Instrumentation for Vulnerability Discovery (or even mitigation!) 
  &lt;ul&gt; 
   &lt;li&gt;EuskalHack 2018; Joxean Koret&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/joxeankoret/membugtool/blob/master/docs/Using%20Binary%20Instrumentation%20for%20Vulnerability%20Discovery%20(or%20even%20mitigation!).pdf&quot;&gt;https://github.com/joxeankoret/membugtool/blob/master/docs/Using%20Binary%20Instrumentation%20for%20Vulnerability%20Discovery%20(or%20even%20mitigation!).pdf&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://docs.google.com/presentation/d/e/2PACX-1vQYw4HJ3kzdmjnxklyBK2nyoMV3Iftx5G6IQmaas7z1cJdP04sX9WsWZmZKqtcTOsqbYukDdUyovhXb/pub&quot;&gt;https://docs.google.com/presentation/d/e/2PACX-1vQYw4HJ3kzdmjnxklyBK2nyoMV3Iftx5G6IQmaas7z1cJdP04sX9WsWZmZKqtcTOsqbYukDdUyovhXb/pub&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Essays on Programming</title>
      <link>https://tedneward.github.io/Research/reading/development/essays/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">reading/development/essays/index.html</guid>
      	<description>
	&lt;ul&gt; 
 &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://www.codemotion.com/magazine/dev-life/a-great-programmer-removes-doesnt-add/?ref=dailydev&quot;&gt;A Great Programmer Removes, Doesn’t Add&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://jv-la.com/journal/2022/lessons-earlier-professional-career/&quot;&gt;4 Lessons I wish I knew earlier on in my professional career&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://andrewkelley.me/post/why-we-cant-have-nice-software.html&quot;&gt;Why we can&apos;t have nice software&lt;/a&gt;: We keep improving past perfection.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://arstechnica.com/information-technology/2012/11/how-team-obamas-tech-efficiency-left-romney-it-in-dust/&quot;&gt;How Team Obama&apos;s tech efficiency left Romney IT in dust&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://jonathanadams.pro/blog-articles/how-good-was-nasa-at-fortran-in-the-1960s.php&quot;&gt;How Good was NASA at FORTRAN in the 1960s?&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://biology.stackexchange.com/questions/30116/does-dna-have-the-equivalent-of-if-statements-while-loops-or-function-calls-h&quot;&gt;&quot;Does DNA have the equivalent of IF-statements, WHILE loops, or function calls? How about GOTO?&quot;&lt;/a&gt;: Short answer, sort of:&lt;/p&gt; &lt;p&gt;&quot;Molecular biological processes cannot be directly compared to a computer code. It is the underlying logic that is important and not the statement construct itself and these examples should not be taken as absolute analogies. It is also to be noted that DNA is just a set of instructions and not really a fully functional entity (it is functional to some extent). However, even being just a code it is comparable to a HLL code that has to be compiled to execute its functions. See this post too.&lt;/p&gt; &lt;p&gt;&quot;It is also important to note that the cell, like many other physical systems, is analog in nature. Therefore, in most situations there is no 0/1 (binary) value of variables. Consider gene expression. If a transcriptional activator is present, the gene will be transcribed. However, if you keep increasing the concentration of the activator, the expression of that gene will increase until it reaches a saturation point. So there is no digital logic here. Having said that, I would add that switching behaviour is possible in biological systems (including gene expression) and is also used in many cases. Certain kinds of regulatory network structures can give rise to such dynamics. Co-operativity with or without positive feedback is one of the mechanisms that can implement switching behaviour.&quot;&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;a href=&quot;http://doc.cat-v.org/programming/worse_is_better&quot;&gt;The Rise of &quot;Worse is Better&quot;&lt;/a&gt; by Richard P. Gabriel&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://workweave.dev/blog/the-price-of-mandatory-code-reviews&quot;&gt;The Price of Mandatory Code Reviews&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Steve Yegge&apos;s rants&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;http://steve-yegge.blogspot.com/2008/10/universal-design-pattern.html&quot;&gt;Universal Design Pattern&lt;/a&gt;: &quot;Today I thought I&apos;d talk about a neat design pattern that doesn&apos;t seem to get much love: the Properties Pattern. In its fullest form it&apos;s also sometimes called the Prototype Pattern.&quot; Talks about three forms of modeling: 
  &lt;ul&gt; 
   &lt;li&gt;Class modeling: &quot;Class-based OO design is the 800-pound gorilla of domain modeling these days. Its appeal is that it&apos;s a natural match for the way we already model things in everyday life. Although the industry loves OO design, it&apos;s not especially well liked as an academic topic. This is because OO design has no real mathematical foundation to support it — at least, not until someone comes along and creates a formal model for side effects. The concepts of OOP stem not from mathematics but from fuzzy intuition. This in some sense explains its popularity, and it also explains why OOP has so many subtly different flavors in practice: whether (and how) to support multiple inheritance, static members, method overloading vs. rich signatures, and so on. Industry folks can never quite agree on what OOP is, but we love it all the same.&quot;&lt;/li&gt; 
   &lt;li&gt;Relational modeling: &quot;Relational database modeling is a bit harder and takes more practice, because its strength stems from its mathematical foundation. Relational modeling can be intuitive, depending on the problem domain, but most people would agree that it is not necessarily so: it takes some real skill to learn how to model arbitrary problems as relational schemas. Object modeling and relational modeling produce very different designs, each with its strengths and weaknesses, and one of the trickiest problems we face in our industry has always been the object-relational mapping (ORM) problem. It&apos;s a big deal. Some people may have let you to believe that it&apos;s simple, or that it&apos;s automatically handled by frameworks such as Rails or Hibernate. Those who know better know just how hard ORM is in real-world production schemas and systems.&lt;/li&gt; 
   &lt;li&gt;XML (hierarchical) modeling: &quot;XML provides yet another technique for modeling problems. Usually XML is used to model data, but it can also be used to model code. For instance, XML-based frameworks such as Apache Ant and XSLT offer computational facilities: loops or recursion, conditional expressions and setting variables.&quot; (He goes on to say that this is a &quot;mostly solved problem&quot; and he basically loses any respect I have for this essay at that point. Mostly.)&lt;/li&gt; 
  &lt;/ul&gt; &lt;p&gt;&quot;Two other obvious candidates are Functional modeling (in the sense of Functional Programming, with roots in the lambda calculus) and Prolog-style logical modeling. Both are mature problem-modeling strategies, each with its pros and cons, and each having varying degrees of overlap with other strategies. And there are still other schools, perhaps dozens of them.&quot;&lt;/p&gt; &lt;p&gt;(TODO: Fill in the rest: Hofstadter, properties modeling, etc)&lt;/p&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;&lt;a href=&quot;https://www.benkuhn.net/progessays/&quot;&gt;Essays on programming I think about a lot&lt;/a&gt;:&lt;/h2&gt; 
&lt;h3&gt;&lt;a href=&quot;https://blog.nelhage.com/post/computers-can-be-understood/&quot;&gt;Computers can be understood&lt;/a&gt;:&lt;/h3&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;I approach software with a deep-seated belief that computers and software systems can be understood. …&lt;/p&gt; 
 &lt;p&gt;In some ways, this belief feels radical today. Modern software and hardware systems contain almost unimaginable complexity amongst many distinct layers, each building atop each other. …&lt;/p&gt; 
 &lt;p&gt;In the face of this complexity, it’s easy to assume that there’s just too much to learn, and to adopt the mental shorthand that the systems we work with are best treated as black boxes, not to be understood in any detail.&lt;/p&gt; 
 &lt;p&gt;I argue against that approach. You will never understand every detail of the implementation of every level on that stack; but you can understand all of them to some level of abstraction, and any specific layer to essentially any depth necessary for any purpose.&lt;/p&gt; 
&lt;/blockquote&gt; 
&lt;h3&gt;&lt;a href=&quot;https://mcfunley.com/choose-boring-technology&quot;&gt;Choose Boring Technology&lt;/a&gt;:&lt;/h3&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;Let’s say every company gets about three innovation tokens. You can spend these however you want, but the supply is fixed for a long while. You might get a few more after you achieve a certain level of stability and maturity, but the general tendency is to overestimate the contents of your wallet. Clearly this model is approximate, but I think it helps.&lt;/p&gt; 
 &lt;p&gt;If you choose to write your website in NodeJS, you just spent one of your innovation tokens. If you choose to use MongoDB, you just spent one of your innovation tokens. If you choose to use service discovery tech that’s existed for a year or less, you just spent one of your innovation tokens. If you choose to write your own database, oh god, you’re in trouble.&lt;/p&gt; 
&lt;/blockquote&gt; 
&lt;h3&gt;&lt;a href=&quot;https://www.sandimetz.com/blog/2016/1/20/the-wrong-abstraction&quot;&gt;The Wrong Abstraction&lt;/a&gt;:&lt;/h3&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;Time passes. A new requirement appears for which the current abstraction is almost perfect. Programmer B gets tasked to implement this requirement. Programmer B feels honor-bound to retain the existing abstraction, but since isn’t exactly the same for every case, they alter the code to take a parameter.... ... Loop until code becomes incomprehensible. You appear in the story about here, and your life takes a dramatic turn for the worse.&lt;/p&gt; 
&lt;/blockquote&gt; 
&lt;h3&gt;&lt;a href=&quot;https://www.kalzumeus.com/2010/06/17/falsehoods-programmers-believe-about-names/&quot;&gt;Falsehoods Programmers Believe About Names&lt;/a&gt;&lt;/h3&gt; 
&lt;h3&gt;&lt;a href=&quot;https://sockpuppet.org/blog/2015/03/06/the-hiring-post/&quot;&gt;The Hiring Post&lt;/a&gt;:&lt;/h3&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;Nothing in Alex’s background offered a hint that this would happen. He had Walter White’s resume, but Heisenberg’s aptitude. None of us saw it coming. My name is Thomas Ptacek and I endorse this terrible pun. Alex was the one who nonced.&lt;/p&gt; 
 &lt;p&gt;A few years ago, Matasano couldn’t have hired Alex, because we relied on interviews and resumes to hire. Then we made some changes, and became a machine that spotted and recruited people like Alex: line of business .NET developers at insurance companies who pulled Rails core CVEs out of their first hour looking at the code. Sysadmins who hardware-reversed assembly firmware for phone chipsets. Epiphany: the talent is out there, but you can’t find it on a resume.&lt;/p&gt; 
 &lt;p&gt;Our field selects engineers using a process that is worse than reading chicken entrails. Like interviews, poultry intestine has little to tell you about whether to hire someone. But they’re a more pleasant eating experience than a lunch interview.&lt;/p&gt; 
&lt;/blockquote&gt; 
&lt;h3&gt;&lt;a href=&quot;https://blog.pragmaticengineer.com/the-product-minded-engineer/&quot;&gt;The Product-Minded Engineer&lt;/a&gt;:&lt;/h3&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;Proactive with product ideas/opinions • Interest in the business, user behavior and data on this • Curiosity and a keen interest in &quot;why?&quot; • Strong communicators and great relationships with non-engineers • Offering product/engineering tradeoffs upfront • Pragmatic handling of edge cases • Quick product validation cycles • End-to-end product feature ownership • Strong product instincts through repeated cycles of learning&lt;/p&gt; 
&lt;/blockquote&gt; 
&lt;h3&gt;&lt;a href=&quot;https://programmingisterrible.com/post/139222674273/write-code-that-is-easy-to-delete-not-easy-to&quot;&gt;Write code that is easy to delete, not easy to extend&lt;/a&gt;:&lt;/h3&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;If we see ‘lines of code’ as ‘lines spent’, then when we delete lines of code, we are lowering the cost of maintenance. Instead of building re-usable software, we should try to build disposable software.&lt;/p&gt; 
 &lt;p&gt;Business logic is code characterised by a never ending series of edge cases and quick and dirty hacks. This is fine. I am ok with this. Other styles like ‘game code’, or ‘founder code’ are the same thing: cutting corners to save a considerable amount of time.&lt;/p&gt; 
 &lt;p&gt;The reason? Sometimes it’s easier to delete one big mistake than try to delete 18 smaller interleaved mistakes. A lot of programming is exploratory, and it’s quicker to get it wrong a few times and iterate than think to get it right first time.&lt;/p&gt; 
&lt;/blockquote&gt; 
&lt;h3&gt;&lt;a href=&quot;https://www.joelonsoftware.com/2002/11/11/the-law-of-leaky-abstractions/&quot;&gt;The Law of Leaky Abstractions&lt;/a&gt;:&lt;/h3&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;Back to TCP. Earlier for the sake of simplicity I told a little fib, and some of you have steam coming out of your ears by now because this fib is driving you crazy. I said that TCP guarantees that your message will arrive. It doesn’t, actually. If your pet snake has chewed through the network cable leading to your computer, and no IP packets can get through, then TCP can’t do anything about it and your message doesn’t arrive. If you were curt with the system administrators in your company and they punished you by plugging you into an overloaded hub, only some of your IP packets will get through, and TCP will work, but everything will be really slow.&lt;/p&gt; 
 &lt;p&gt;This is what I call a leaky abstraction. TCP attempts to provide a complete abstraction of an underlying unreliable network, but sometimes, the network leaks through the abstraction and you feel the things that the abstraction can’t quite protect you from. This is but one example of what I’ve dubbed the Law of Leaky Abstractions:&lt;/p&gt; 
 &lt;p&gt;&lt;strong&gt;All non-trivial abstractions, to some degree, are leaky.&lt;/strong&gt;&lt;/p&gt; 
 &lt;p&gt;Abstractions fail. Sometimes a little, sometimes a lot. There’s leakage. Things go wrong. It happens all over the place when you have abstractions. Here are some examples.&lt;/p&gt; 
&lt;/blockquote&gt; 
&lt;h3&gt;&lt;a href=&quot;https://blog.nelhage.com/post/reflections-on-performance/&quot;&gt;Reflections on software performance&lt;/a&gt;:&lt;/h3&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;It’s probably fairly intuitive that users prefer faster software, and will have a better experience performing a given task if the tools are faster rather than slower.&lt;/p&gt; 
 &lt;p&gt;What is perhaps less apparent is that having faster tools changes how users use a tool or perform a task. Users almost always have multiple strategies available to pursue a goal — including deciding to work on something else entirely — and they will choose to use faster tools more and more frequently. Fast tools don’t just allow users to accomplish tasks faster; they allow users to accomplish entirely new types of tasks, in entirely new ways. I’ve seen this phenomenon clearly while working on both Sorbet and Livegrep:&lt;/p&gt; 
&lt;/blockquote&gt; 
&lt;h3&gt;Brandur Leach’s series on using databases to ensure correct edge-case behavior:&lt;/h3&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;I want to convince you that ACID databases are one of the most important tools in existence for ensuring maintainability and data correctness in big production systems. Lets start by digging into each of their namesake guarantees.&lt;/p&gt; 
 &lt;p&gt;There’s a surprising symmetry between an HTTP request and a database’s transaction. Just like the transaction, an HTTP request is a transactional unit of work – it’s got a clear beginning, end, and result. The client generally expects a request to execute atomically and will behave as if it will (although that of course varies based on implementation). Here we’ll look at an example service to see how HTTP requests and transactions apply nicely to one another.&lt;/p&gt; 
 &lt;p&gt;In APIs &lt;em&gt;idempotency&lt;/em&gt; is a powerful concept. An idempotent endpoint is one that can be called any number of times while guaranteeing that the side effects will occur only once. In a messy world where clients and servers that may occasionally crash or have their connections drop partway through a request, it’s a huge help in making systems more robust to failure. Clients that are uncertain whether a request succeeded or failed can simply keep retrying it until they get a definitive response.&lt;/p&gt; 
&lt;/blockquote&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://brandur.org/acid&quot;&gt;Building Robust Systems with ACID and Constraints&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://brandur.org/http-transactions&quot;&gt;Using Atomic Transactions to Power an Idempotent API&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;[Transactionally Staged Job Drains in Postgres](&lt;a href=&quot;https://brandur.org/job-drain&quot;&gt;https://brandur.org/job-drain&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://brandur.org/idempotency-keys&quot;&gt;Implementing Stripe-like Idempotency Keys in Postgres&lt;/a&gt;:&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;&lt;a href=&quot;http://web.mit.edu/Saltzer/www/publications/endtoend/endtoend.pdf&quot;&gt;End-to-End Arguments in System Design&lt;/a&gt;:&lt;/h3&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;This paper presents a design principle that helps guide placement of functions among the modules of a distributed computer system. The principle, called the end-to-end argument, suggests that functions placed at low levels of a system may be redundant or of little value when compared with the cost of providing them at that low level. Examples discussed in the paper include bit error recovery, security using encryption, duplicate message suppression, recovery from system crashes, and delivery acknowledgement. Low level mechanisms to support these functions are justified only as performance enhancements.&lt;/p&gt; 
&lt;/blockquote&gt; 
&lt;h3&gt;&lt;a href=&quot;https://vimeo.com/36579366&quot;&gt;Inventing on Principle&lt;/a&gt;:&lt;/h3&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;I’ve spent a lot of time over the years making creative tools, using creative tools, thinking about them a lot, and here’s something I’ve come to believe: Creators need an immediate connection to what they’re creating.&lt;/p&gt; 
&lt;/blockquote&gt;
	</description>
    </item>
    <item>
      <title>Dynamic Binary Translation (DBT) reading</title>
      <link>https://tedneward.github.io/Research/reading/development/dynamic-binary-translation/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">reading/development/dynamic-binary-translation/index.html</guid>
      	<description>
	&lt;ul&gt; 
 &lt;li&gt;A Retargetable System-Level DBT Hypervisor 
  &lt;ul&gt; 
   &lt;li&gt;2019 USENIX Annual Technical Conference&lt;/li&gt; 
   &lt;li&gt;Tom Spink, Harry Wagstaff, Björn Franke&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.usenix.org/conference/atc19/presentation/spink&quot;&gt;https://www.usenix.org/conference/atc19/presentation/spink&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Unleashing the Power of Learning: An Enhanced Learning-Based Approach for Dynamic Binary Translation 
  &lt;ul&gt; 
   &lt;li&gt;2019 USENIX Annual Technical Conference&lt;/li&gt; 
   &lt;li&gt;Changheng Song, Wenwen Wang, Pen-Chung Yew, Antonia Zhai, Weihua Zhang&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.usenix.org/conference/atc19/presentation/song&quot;&gt;https://www.usenix.org/conference/atc19/presentation/song&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Acceleration of memory accesses in dynamic binary translation 
  &lt;ul&gt; 
   &lt;li&gt;2018 PhD Dissertation; Antoine Faravelon&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://tel.archives-ouvertes.fr/tel-02004524/&quot;&gt;https://tel.archives-ouvertes.fr/tel-02004524/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Cross-ISA Machine Emulation for Multicores 
  &lt;ul&gt; 
   &lt;li&gt;Code Generation and Optimization (CGO) 2017&lt;/li&gt; 
   &lt;li&gt;Emilio G. Cota, Paolo Bonzini, Alex Bennée, Luca P. Carloni&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://sld.cs.columbia.edu/pubs/cota_cgo17.pdf&quot;&gt;https://sld.cs.columbia.edu/pubs/cota_cgo17.pdf&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Dynamic Binary Modification: Tools, Techniques, and Applications 
  &lt;ul&gt; 
   &lt;li&gt;2011 Book; Kim Hazelwood&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://www.morganclaypool.com/doi/abs/10.2200/S00345ED1V01Y201104CAC015&quot;&gt;http://www.morganclaypool.com/doi/abs/10.2200/S00345ED1V01Y201104CAC015&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Dynamically Translating x86 to LLVM using QEMU 
  &lt;ul&gt; 
   &lt;li&gt;2010 Technical Report; Vitaly Chipounov and George Candea&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://infoscience.epfl.ch/record/149975/files/x86-llvm-translator-chipounov_&quot;&gt;https://infoscience.epfl.ch/record/149975/files/x86-llvm-translator-chipounov_&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Efficient and Retargetable SIMD Translation in a Dynamic Binary Translator 
  &lt;ul&gt; 
   &lt;li&gt;Software: Practice and Experience, 48(6) 2018&lt;/li&gt; 
   &lt;li&gt;Sheng-Yu Fu, Ding-Yong Hong, Yu-Ping Liu, Jan-Jan Wu, Wei-Chung Hsu&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://onlinelibrary.wiley.com/doi/abs/10.1002/spe.2573?af=R&quot;&gt;https://onlinelibrary.wiley.com/doi/abs/10.1002/spe.2573?af=R&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Hermes: A fast cross-ISA binary translator with post-optimization 
  &lt;ul&gt; 
   &lt;li&gt;Code Generation and Optimization (CGO) 2015&lt;/li&gt; 
   &lt;li&gt;Xiaochun Zhang, Qi Guo, Yunji Chen, Tianshi Chen, Weiwu Hu&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://ieeexplore.ieee.org/document/7054204/&quot;&gt;http://ieeexplore.ieee.org/document/7054204/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://dl.acm.org/citation.cfm?id=2738631&quot;&gt;https://dl.acm.org/citation.cfm?id=2738631&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Improving Dynamically-Generated Code Performance on Dynamic Binary Translators 
  &lt;ul&gt; 
   &lt;li&gt;Virtual Execution Environments VEE 2018&lt;/li&gt; 
   &lt;li&gt;Wenwen Wang, Jiacheng Wu, Xiaoli Gong, Tao Li, Pen-Chung Yew&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://dl.acm.org/citation.cfm?id=3186413&quot;&gt;https://dl.acm.org/citation.cfm?id=3186413&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Improving SIMD Parallelism via Dynamic Binary Translation 
  &lt;ul&gt; 
   &lt;li&gt;Ding-Yong Hong, Yu-Ping Liu, Sheng-Yu Fu, Jan-Jan Wu, Wei-Chung Hsu&lt;/li&gt; 
   &lt;li&gt;ACM Transactions on Embedded Computing Systems (TECS) 17(3) 2018&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.researchgate.net/publication/323149934_Improving_SIMD_Parallelism_via_Dynamic_Binary_Translation&quot;&gt;https://www.researchgate.net/publication/323149934_Improving_SIMD_Parallelism_via_Dynamic_Binary_Translation&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.researchgate.net/publication/323865399_Improving_Dynamically-Generated_Code_Performance_on_Dynamic_Binary_Translators&quot;&gt;https://www.researchgate.net/publication/323865399_Improving_Dynamically-Generated_Code_Performance_on_Dynamic_Binary_Translators&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;libdetox: A Framework for Online Program Transformation 
  &lt;ul&gt; 
   &lt;li&gt;Forming an Ecosystem Around Software Transformation FEAST 2016&lt;/li&gt; 
   &lt;li&gt;Mathias Payer&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://nebelwelt.net/publications/files/16FEAST.pdf&quot;&gt;https://nebelwelt.net/publications/files/16FEAST.pdf&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/HexHive/libdetox&quot;&gt;https://github.com/HexHive/libdetox&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Optimizing Binary Translation of Dynamically Generated Code 
  &lt;ul&gt; 
   &lt;li&gt;Code Generation and Optimization (CGO) 2015&lt;/li&gt; 
   &lt;li&gt;Byron Hawkins, Brian Demsky, Derek Bruening, Qin Zhao&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://research.google.com/pubs/archive/46470.pdf&quot;&gt;https://research.google.com/pubs/archive/46470.pdf&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://demsky.eecs.uci.edu/~bhawkins/papers/cgo-2015.slides.pdf&quot;&gt;http://demsky.eecs.uci.edu/~bhawkins/papers/cgo-2015.slides.pdf&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Optimizing indirect branches in a system-level dynamic binary translator 
  &lt;ul&gt; 
   &lt;li&gt;SYSTOR 2012&lt;/li&gt; 
   &lt;li&gt;Toshihiko Koju, Xin Tong, Ali Ijaz Sheikh, Moriyoshi Ohara, Toshio Nakatani&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://doi.acm.org/10.1145/2367589.2367599&quot;&gt;http://doi.acm.org/10.1145/2367589.2367599&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Processor-Tracing Guided Region Formation in Dynamic Binary Translation 
  &lt;ul&gt; 
   &lt;li&gt;ACM Transactions on Architecture and Code Optimization, Vol. 15, No. 4, Article 52, 2018&lt;/li&gt; 
   &lt;li&gt;Ding-Yong Hong, Jan-Jan Wu, Yu-Ping Liu, Sheng-Yu Fu, Wei-Chung Hsu&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://dl.acm.org/citation.cfm?id=3281664&quot;&gt;http://dl.acm.org/citation.cfm?id=3281664&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Requirements for Fast Binary Translation 
  &lt;ul&gt; 
   &lt;li&gt;Mathias Payer, Thomas R. Gross&lt;/li&gt; 
   &lt;li&gt;AMAS-BT: Workshop on Architectural and Microarchitectural Support for Binary Translation 2009&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://nebelwelt.net/publications/files/09AMAS-BT.pdf&quot;&gt;https://nebelwelt.net/publications/files/09AMAS-BT.pdf&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://nebelwelt.net/publications/files/09AMAS-BT-presentation.pdf&quot;&gt;https://nebelwelt.net/publications/files/09AMAS-BT-presentation.pdf&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;rv8: a high performance RISC-V to x86 binary translator 
  &lt;ul&gt; 
   &lt;li&gt;Workshop on Computer Architecture Research with RISC-V (CARRV) 2017&lt;/li&gt; 
   &lt;li&gt;Michael Clark and Bruce Hoult&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://anarch128.org/~mclark/rv8-carrv.pdf&quot;&gt;https://anarch128.org/~mclark/rv8-carrv.pdf&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://carrv.github.io/papers/clark-rv8-carrv2017.pdf&quot;&gt;https://carrv.github.io/papers/clark-rv8-carrv2017.pdf&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://rv8.io/&quot;&gt;https://rv8.io/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/rv8-io/rv8&quot;&gt;https://github.com/rv8-io/rv8&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Scalable Emulation of Heterogeneous Systems 
  &lt;ul&gt; 
   &lt;li&gt;2019 Ph.D. Dissertation; Luca Carloni&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://academiccommons.columbia.edu/doi/10.7916/d8-a78j-z392&quot;&gt;https://academiccommons.columbia.edu/doi/10.7916/d8-a78j-z392&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&quot;in this dissertation we first present a novel machine emulator design based on dynamic binary translation that makes the following improvements over the state of the art: it scales on multicore hosts while remaining memory efficient, correctly handles cross-ISA differences in atomic instruction semantics, leverages the host floating point (FP) unit to speed up FP emulation without sacrificing correctness, and can be efficiently instrumented to---among other possible uses---drive the execution of a full-system, cross-ISA simulator with support for accelerators.&quot;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Executable and object file format reading</title>
      <link>https://tedneward.github.io/Research/reading/development/executables/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">reading/development/executables/index.html</guid>
      	<description>
	&lt;p&gt;Executable files, debugging data, object code, shared libraries - file formats information, specifications, software - with relevance to compiler toolchains, debuggers, and general program analysis.&lt;/p&gt; 
&lt;p&gt;Organization: Preference given to the most specific category; e.g., if an article discusses DLL-specific information, then it belongs to the DLL section (in preference to the more general PE).&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Comparison of executable file formats - &lt;a href=&quot;https://en.wikipedia.org/wiki/Comparison_of_executable_file_formats&quot;&gt;https://en.wikipedia.org/wiki/Comparison_of_executable_file_formats&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;Executable and object file formats - &lt;a href=&quot;https://en.wikipedia.org/wiki/Template:Executables&quot;&gt;https://en.wikipedia.org/wiki/Template:Executables&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;From Hack to Elaborate Technique—A Survey on Binary Rewriting 
  &lt;ul&gt; 
   &lt;li&gt;ACM Computing Surveys 52(3) 2019&lt;/li&gt; 
   &lt;li&gt;Matthias Wenzl, Georg Merzdovnik, Johanna Ullrich, and Edgar Weippl&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://dl.acm.org/citation.cfm?doid=3341324.3316415&quot;&gt;https://dl.acm.org/citation.cfm?doid=3341324.3316415&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://publications.sba-research.org/publications/201906%20-%20GMerzdovnik%20-%20From%20hack%20to%20elaborate%20technique.pdf&quot;&gt;https://publications.sba-research.org/publications/201906%20-%20GMerzdovnik%20-%20From%20hack%20to%20elaborate%20technique.pdf&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Linux Foundation Referenced Specifications: ABI, ELF, DWARF - &lt;a href=&quot;https://refspecs.linuxfoundation.org/&quot;&gt;https://refspecs.linuxfoundation.org/&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;Type Inference on Executables 
  &lt;ul&gt; 
   &lt;li&gt;ACM Computing Surveys, Vol. 48, No. 4, Article 65, 2016&lt;/li&gt; 
   &lt;li&gt;Juan Caballero and Zhiqiang Lin&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.utdallas.edu/~zxl111930/file/CSUR16.pdf&quot;&gt;https://www.utdallas.edu/~zxl111930/file/CSUR16.pdf&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://web.cse.ohio-state.edu/~lin.3021/file/CSUR16.pdf&quot;&gt;http://web.cse.ohio-state.edu/~lin.3021/file/CSUR16.pdf&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Visual Documentation - File formats - Executables: ELF, Mach-O, PE (SVG and PDF available) 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/corkami/pics/blob/master/binary/README.md#executables&quot;&gt;https://github.com/corkami/pics/blob/master/binary/README.md#executables&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;elf101: &lt;a href=&quot;https://github.com/corkami/pics/tree/master/binary/elf101&quot;&gt;https://github.com/corkami/pics/tree/master/binary/elf101&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;macho101: &lt;a href=&quot;https://github.com/corkami/pics/tree/master/binary/macho101&quot;&gt;https://github.com/corkami/pics/tree/master/binary/macho101&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;pe101: &lt;a href=&quot;https://github.com/corkami/pics/tree/master/binary/pe101&quot;&gt;https://github.com/corkami/pics/tree/master/binary/pe101&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;pe102: &lt;a href=&quot;https://github.com/corkami/pics/tree/master/binary/pe102&quot;&gt;https://github.com/corkami/pics/tree/master/binary/pe102&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Talks&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;Reverse Engineering Binaries 
  &lt;ul&gt; 
   &lt;li&gt;DevConf.CZ 2019; Divya Basant Kumar&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=TZVBK5hu0sk&quot;&gt;https://www.youtube.com/watch?v=TZVBK5hu0sk&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;My Little Object File: How Linkers Implement C++ 
  &lt;ul&gt; 
   &lt;li&gt;CppCon 2017; Michael Spencer&lt;/li&gt; 
   &lt;li&gt;(ELF, MachO, COFF)&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=a5L66zguFe4&quot;&gt;https://www.youtube.com/watch?v=a5L66zguFe4&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;The Life of Binaries 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;http://www.opensecuritytraining.info/LifeOfBinaries.html&quot;&gt;http://www.opensecuritytraining.info/LifeOfBinaries.html&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/playlist?list=PLUFkSN0XLZ-n_Na6jwqopTt1Ki57vMIc3&quot;&gt;https://www.youtube.com/playlist?list=PLUFkSN0XLZ-n_Na6jwqopTt1Ki57vMIc3&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Designing Data-Intensive Applications</title>
      <link>https://tedneward.github.io/Research/reading/development/designing-data-intensive-apps/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">reading/development/designing-data-intensive-apps/index.html</guid>
      	<description>
	&lt;p&gt;&lt;em&gt;(by Martin Kleppmann)&lt;/em&gt;&lt;/p&gt; 
&lt;h3&gt;Chapter 1: Reliable, Scalable, and Maintainable Applications&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;Many applications are data-intensive and not compute intensive, meaning the biggest problems are usually the amount of data, the complexity of data, and the speed at which it is changing.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Thinking About Data Systems&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;No single tool can meet all data processing and storage needs. Instead work is broken down into tasks that can be performed efficiently on a single tool, and application code stitches those tools together.&lt;/li&gt; 
 &lt;li&gt;When you create an API in front of several tools, you have created a new, special-purpose data system from smaller, general-purpose components.&lt;/li&gt; 
 &lt;li&gt;This book focuses on three main concerns: reliability, scalability, and maintainability.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Reliability&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;Reliability means the system continues to work correctly, even when things go wrong.&lt;/li&gt; 
 &lt;li&gt;Things that can go wrong are called &lt;em&gt;faults&lt;/em&gt;, and systems that anticipate faults and can cope with them are called &lt;em&gt;fault-tolerant&lt;/em&gt; or &lt;em&gt;resilient&lt;/em&gt;.&lt;/li&gt; 
 &lt;li&gt;A &lt;em&gt;fault&lt;/em&gt; is when one component of the system deviates from its spec, whereas a &lt;em&gt;failure&lt;/em&gt; is when the system as a whole stops providing the required service to the user.&lt;/li&gt; 
 &lt;li&gt;You cannot reduce the possibility of a fault to zero, and so you must design fault-tolerance mechanisms that prevent faults from causing failures.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;Hardware Faults&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;Hard disks have a MTTF of 10 to 50 years, and so on a storage cluster with 10,000 disks, we should expect on average one disk to die per day.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;Software Errors&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;Systemic errors, such as leap second bugs or cascading failures, are correlated across nodes and so tend to cause more system failures than uncorrelated hardware faults.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;Human Errors&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;Allow quick recovery from human errors, such as making it fast to rollback configuration changes, and to roll out code gradually.&lt;/li&gt; 
 &lt;li&gt;Set up detailed and clear monitoring, such as performance metrics and error rates.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Scalability&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;Scalability is the term we use to describe a system&apos;s ability to cope with increased load.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;Describing Load&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;Load can be described with a few numbers that we call &lt;em&gt;load parameters&lt;/em&gt;. The best choice of parameters depends on the architecture of your system.&lt;/li&gt; 
 &lt;li&gt;For Twitter, the distribution of followers per user is a key load parameter for describing scalability, as it determines the fan-out load.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;Describing Performance&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;You can look at what happens when load increases in two ways:&lt;/li&gt; 
 &lt;li&gt;When you increase a load parameter and keep system resources fixed, how is the performance of your system affected?&lt;/li&gt; 
 &lt;li&gt;When you increase a load parameter, how much do you need to increase the resources if you want to keep performance unchanged?&lt;/li&gt; 
 &lt;li&gt;Response time what the client sees, including the time to process the request (the service time) and network delays and queuing delays.&lt;/li&gt; 
 &lt;li&gt;Latency is the duration that a request is waiting to be handled – during which it is &lt;em&gt;latent&lt;/em&gt;, awaiting service.&lt;/li&gt; 
 &lt;li&gt;The mean is not a good metrics to describe the &quot;typical&quot; response time, as it doesn&apos;t tell you how many users experienced that delay. Prefer percentiles instead.&lt;/li&gt; 
 &lt;li&gt;High percentiles of response times, or tail latencies, are important because they directly affect users&apos; experience of the service.&lt;/li&gt; 
 &lt;li&gt;Reducing response times at high percentiles is difficult because they are easily affected by random events outside your control, and the benefits are diminishing.&lt;/li&gt; 
 &lt;li&gt;When artificially generating load to test scalability, the client must send requests independently of the response time, or else it will artificially keep the queues shorter than in reality, thereby skewing the measurements.&lt;/li&gt; 
 &lt;li&gt;Even if you call multiple backend services in parallel, the end-user request must wait for the slowest of the parallel calls to complete.&lt;/li&gt; 
 &lt;li&gt;Averaging percentiles, such as when combining data from several machines, is mathematically meaningless. The right way of aggregating response time data is to add the histograms.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;Approaches for Coping with Load&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;Scaling up, or vertical scaling, is moving to a more powerful machine. Scaling out, or horizontal scaling, distributes the load across multiple smaller machines.&lt;/li&gt; 
 &lt;li&gt;An architecture that scales well for a particular application is built around assumptions of operations will be common and which will be rare&amp;nbsp;– the load parameters.&lt;/li&gt; 
 &lt;li&gt;In an early-stage startup it&apos;s more important to be able to iterate quickly on product features than to scale beyond some hypothetical future load.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Maintainability&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;The majority of the cost of software is not in its initial development, but its ongoing maintenance.&lt;/li&gt; 
 &lt;li&gt;Three important design principles for maintainability are:&lt;/li&gt; 
 &lt;li&gt;Operability: Make it easy for the operations teams to keep the system running smoothly.&lt;/li&gt; 
 &lt;li&gt;Simplicity: Make it easy for new engineers to understand the system by removing complexity.&lt;/li&gt; 
 &lt;li&gt;Evolvability (or extensibility): Make it easy for engineers to adapt the system to unanticipated use cases as requirements change.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;Operability: Making Life Easy for Operations&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;Good operations can work around the limitations of bad software, but good software cannot run reliably with bad operations.&lt;/li&gt; 
 &lt;li&gt;A good operations team works to preserve the organization&apos;s knowledge about the system, even as individuals come and go.&lt;/li&gt; 
 &lt;li&gt;Data systems with good operability provide good default behavior but allow overriding, and exhibit predictable behavior to minimize surprises.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;Simplicity: Managing Complexity&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;Making a system simpler does not necessarily mean reducing its functionality; it can also mean removing &lt;em&gt;accidental complexity&lt;/em&gt;.&lt;/li&gt; 
 &lt;li&gt;Accidental complexity is complexity that is not inherent in the problem that the software solves, but arises only from the implementation.&lt;/li&gt; 
 &lt;li&gt;Good abstractions are one of the best tools for removing accidental complexity by hiding implementation details, but finding good abstractions is very hard.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;Evolvability: Making Change Easy&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;Simple and easy-to-understand systems are usually easier to modify than complex ones.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Summary&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;Functional requirements are what an application should do.&lt;/li&gt; 
 &lt;li&gt;Nonfunctional requirements are general properties like security, reliability, compliance, scalability, compatibility, and maintainability.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Chapter 2: Data Models and Query Languages&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;Data models are the most important part of developing software, because they affect not only how the software is written, but how we think about the problem that we&apos;re solving.&lt;/li&gt; 
 &lt;li&gt;Layered software abstractions allow different groups of people to work together effectively.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Relational Model Versus Document Model&lt;/h4&gt; 
&lt;h5&gt;The Birth of NoSQL&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;The term NoSQL has been retroactively reinterpreted as &lt;em&gt;Not Only SQL&lt;/em&gt;.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;The Object-Relational Mismatch&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;Impedance mismatch is the disconnect between objects in the application code and the database model of tables, rows, and columns.&lt;/li&gt; 
 &lt;li&gt;A JSON representation of a document-oriented database has better locality than an equivalent multi-table schema.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;Many-to-One and Many-to-Many Relationships&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;In a document-oriented database, if information is duplicated and that information is changed, then all redundant copies need to be updated. Normalization is the key idea behind removing such duplication.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;Are Document Databases Repeating History?&lt;/h5&gt; 
&lt;h6&gt;The relational model&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;A key insight of the relational model was that you only need to build a query optimizer once, and then all database clients can benefit from it.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Comparison to document databases&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;For many-to-one and many-to-many relationships, a related item is referenced by a &lt;em&gt;foreign key&lt;/em&gt; in the relational model, and a &lt;em&gt;document reference&lt;/em&gt; in the document model.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;Relational Versus Document Databases Today&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;The document data model offers greater schema flexibility, better performance from locality, and for some applications it is closer to the data structures used by the application.&lt;/li&gt; 
 &lt;li&gt;The relational model offers better support for joins, and many-to-one and many-to-many relationships.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Which data model leads to simpler application code?&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;If your application data has a document-like structure (i.e. a tree of one-to-many relationships, where typically the entire tree is loaded at once), then a document model is likely a good idea.&lt;/li&gt; 
 &lt;li&gt;But if your application uses many-to-many relationships, the document model becomes less appealing.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Schema flexibility in the document model&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;Document databases are sometimes called &lt;em&gt;schemaless&lt;/em&gt;, but that&apos;s misleading – there is an implicit schema assumed by the application, but not enforced by the database.&lt;/li&gt; 
 &lt;li&gt;A more accurate term is &lt;em&gt;schema-on-read&lt;/em&gt; in contrast with &lt;em&gt;schema-on-write&lt;/em&gt;.&lt;/li&gt; 
 &lt;li&gt;Schema-on-read is similar to dynamic (runtime) type checking in programming languages, whereas schema-on-write is similar to static (compile-type) type checking.&lt;/li&gt; 
 &lt;li&gt;In cases where all records are expected to have the same structure, schemas are a useful mechanism for documenting and enforcing a data structure.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Data locality for queries&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;The locality advantage only applies if you need large parts of the document at the same time.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Query Languages for Data&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;An imperative language tells the computer to perform certain operations in a certain order.&lt;/li&gt; 
 &lt;li&gt;In a declarative query language like SQL or relational algebra, you specify the pattern of the data you want, but not &lt;em&gt;how&lt;/em&gt; to achieve that goal.&lt;/li&gt; 
 &lt;li&gt;A declarative query language also hides implementation details of the database engine, allowing it to add performance improvements without requiring changes to queries.&lt;/li&gt; 
 &lt;li&gt;Declarative languages are more amenable to parallel execution because they specify the pattern of the results, but not the algorithm used to determine them.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;MapReduce Querying&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;MapReduce is based on a &lt;code&gt;map&lt;/code&gt; (or &lt;code&gt;collect&lt;/code&gt;) and &lt;code&gt;reduce&lt;/code&gt; (or &lt;code&gt;fold&lt;/code&gt; or &lt;code&gt;inject&lt;/code&gt;) functions that exist in many functional languages.&lt;/li&gt; 
 &lt;li&gt;The &lt;code&gt;map&lt;/code&gt; and &lt;code&gt;reduce&lt;/code&gt; functions must be pure, thereby allowing the database to run them anywhere, and to rerun them on failure.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Graph-Like Data Models&lt;/h4&gt; 
&lt;h5&gt;Property Graphs&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;A property graph model, each vertex and edge has a collection of properties (i.e. key-value pairs), and each edge has a label to describe the relationship between its vertices.&lt;/li&gt; 
 &lt;li&gt;To get the set of incoming and outgoing edges for a vertex, you can query the &lt;code&gt;edges&lt;/code&gt; table by &lt;code&gt;head_vertex&lt;/code&gt; or &lt;code&gt;tail_vertex&lt;/code&gt; respectively.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;Graph Queries in SQL&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;In a relational database, you usually know in advance which joins you need in your query.&lt;/li&gt; 
 &lt;li&gt;In a graph query, you may need to traverse a variable number of edges before you find the vertex you&apos;re looking for –&amp;nbsp;i.e. the number of joins is not fixed in advance.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;Triple-Stores and SPARQL&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;In a triple-store, all information is stored in the form of very simple three-part statements: (&lt;em&gt;subject&lt;/em&gt;, &lt;em&gt;predicate&lt;/em&gt;, &lt;em&gt;object&lt;/em&gt;).&lt;/li&gt; 
 &lt;li&gt;The object is one of two things:&lt;/li&gt; 
 &lt;li&gt;A value in a primitive data type, and so the predicate and object are equivalent to the key and value of a property on the subject vertex. (E.g. (&lt;em&gt;lucy&lt;/em&gt;, &lt;em&gt;age&lt;/em&gt;, &lt;em&gt;33&lt;/em&gt;) is like a vertex &lt;code&gt;lucy&lt;/code&gt; with properties &lt;code&gt;{&quot;age&quot;: 33}&lt;/code&gt;.)&lt;/li&gt; 
 &lt;li&gt;Another vertex in the graph, and so the predicate is an edge, the subject is the tail vertex, and the object is the head vertex. (E.g. (&lt;em&gt;alice&lt;/em&gt;, &lt;em&gt;married_to&lt;/em&gt;, &lt;em&gt;bob&lt;/em&gt;) has an edge &lt;em&gt;married_to&lt;/em&gt; between &lt;em&gt;alice&lt;/em&gt; and &lt;em&gt;bob&lt;/em&gt;.)&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;The Foundation: Datalog&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;Datalog generalizes the triple-store model, writing the triple as &lt;em&gt;predicate(subject, object)&lt;/em&gt;.&lt;/li&gt; 
 &lt;li&gt;A Datalog rule applies if the system can find a match for &lt;em&gt;all&lt;/em&gt; predicates on the right side of the &lt;code&gt;:-&lt;/code&gt; operator.&lt;/li&gt; 
 &lt;li&gt;When a rule applies, it&apos;s as though the left side of the &lt;code&gt;:-&lt;/code&gt; was added to the database, with variables replaced by the values they matched.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Chapter 3: Storage and Retrieval&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;There is a big difference between storage engines optimized for transactional workloads and those optimized for analytics.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Data Structures That Power Your Database&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;em&gt;Log&lt;/em&gt; is defined as an append-only sequence of records. It doesn&apos;t have to be human-readable, and instead might be binary.&lt;/li&gt; 
 &lt;li&gt;Well-chosen indexes speed up read queries, but every index slows down writes, because the index also needs to be updated every time data is written.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;Hash Indexes&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;If new and updated values are blindly written to a log, that log can be divided into segments. Compacting a segment keeps only the most recent value for each key, discarding the older ones.&lt;/li&gt; 
 &lt;li&gt;Since compaction makes segments much smaller (assuming a key is updated several times in one segment), compaction can also merge several segments together.&lt;/li&gt; 
 &lt;li&gt;A background thread can merge and compact segments. While it happens, the database can still serve reads from old segment files, and write requests to the latest segment file.&lt;/li&gt; 
 &lt;li&gt;A &lt;em&gt;tombstone&lt;/em&gt; marks a deleted key. When segments are merged, the tombstone tells the merging process to discard all previous values for the key.&lt;/li&gt; 
 &lt;li&gt;Data file segments are append-only and otherwise immutable, and so they can be read concurrently by multiple threads.&lt;/li&gt; 
 &lt;li&gt;Append-only design is advantageous in several ways:&lt;/li&gt; 
 &lt;li&gt;Appending and segment merging are sequential write operations, which are generally much faster than random writes.&lt;/li&gt; 
 &lt;li&gt;Crash recovery are much simpler if segment files are append-only or immutable, e.g. you avoid crashing while overwriting a value and leaving old and new data spliced together.&lt;/li&gt; 
 &lt;li&gt;Merging old segments avoids the problem of data files getting fragmented over time.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;SSTables and LSM-Trees&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;Segment files sorted by key is a format called &lt;em&gt;Sorted String Table&lt;/em&gt;, or &lt;em&gt;SSTable&lt;/em&gt; for short.&lt;/li&gt; 
 &lt;li&gt;This has several advantages over log segments with hash indexes:&lt;/li&gt; 
 &lt;li&gt;Merging segments is efficient even if the files exceed available memory, by using an algorithm similar to mergesort.&lt;/li&gt; 
 &lt;li&gt;Your in-memory index of keys to file offsets can be sparse, and so the total size of your keys can exceed available memory.&lt;/li&gt; 
 &lt;li&gt;If your in-memory index of keys is sparse, reads may scan over several key-value pairs on disk anyway, which can be compressed. This reduces disk space and I/O bandwidth use.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Constructing and maintaining SSTables&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;Writes update a &lt;em&gt;memtable&lt;/em&gt;, or an in-memory balanced tree. When its size exceeds some threshold, it can be written to disk as an SSTable file.&lt;/li&gt; 
 &lt;li&gt;Read requests first query the memtable and then query on-disk segments in order from newest to oldest.&lt;/li&gt; 
 &lt;li&gt;We can append every update to a log before updating the memtable. The log is not in sorted order, but can be used to restore the memtable after a crash.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Making an LSM-tree out of SSTables&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;Storage engines based on the principle of merging and compacting sorted files are called LSM (Log-Structured Merge) storage engines.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Performance optimizations&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;An LSM storage engine can use bloom filters to avoid querying the memtable and all segments for a key that does not exist.&lt;/li&gt; 
 &lt;li&gt;Since data is stored in sorted order, you can efficiently perform range queries, and because disk writes are essential the LSM-tree can support remarkably high write throughput.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;B-Trees&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;B-trees remain the standard index implementation in almost all relational databases, and many non-relational databases use them too.&lt;/li&gt; 
 &lt;li&gt;B-trees break down the database into fixed-size &lt;em&gt;blocks&lt;/em&gt; or &lt;em&gt;pages&lt;/em&gt; (usually 4KB) and read or write one page at a time. This maps closely to the underlying disk hardware.&lt;/li&gt; 
 &lt;li&gt;The number of references to child pages in one page of the B-tree is called its &lt;em&gt;branching factor&lt;/em&gt;, and is typically several hundred.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Making B-trees reliable&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;To make the database resilient to crashes, many B-tree implementations also persist to an append-only log called the &lt;em&gt;write-ahead log&lt;/em&gt; (WAL, or &lt;em&gt;redo log&lt;/em&gt;).&lt;/li&gt; 
 &lt;li&gt;When the database comes back up after a crash, the write-ahead log is used to restore the B-tree back to a consistent state.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;B-tree optimizations&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;In pages in the interior of a tree, we do not need to store full keys, but only enough information to act as boundaries between key ranges.&lt;/li&gt; 
 &lt;li&gt;B-trees try to ensure leaf pages are in sequential order on disk. This is easier for LSM-trees, which rewrite large segments of the storage in one go during merging.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;Comparing B-Trees and LSM-Trees&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;LSM-trees are typically faster for writes, whereas B-trees are thought to be faster for reads.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Advantages of LSM-trees&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;em&gt;Write amplification&lt;/em&gt; is where one write results in multiple writes over the database&apos;s lifetime, such as when compacting and merging SSTables.&lt;/li&gt; 
 &lt;li&gt;Write amplification is of concern with SSDs, which can only overwrite blocks a limited number of times before wearing out.&lt;/li&gt; 
 &lt;li&gt;LSM-trees typically sustain higher write throughput than B-trees because they sometimes have lower write-amplification, and because they sequentially write data.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Downsides of LSM-trees&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;The bigger the database gets, the more disk bandwidth is required for compaction. But this bandwidth is limited and can increase response times at higher percentiles.&lt;/li&gt; 
 &lt;li&gt;Relational databases implement transaction isolation using locks on ranges of keys. Because each key exists at exactly one place in a B-tree index, those locks can be attached directly to the tree.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;Other Indexing Structures&lt;/h5&gt; 
&lt;h6&gt;Storing values within the index&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;With secondary indexes, each index references a location in the &lt;em&gt;heap file&lt;/em&gt; that belongs to the corresponding row.&lt;/li&gt; 
 &lt;li&gt;A &lt;em&gt;clustered index&lt;/em&gt; stores the indexed row directly within an index, to avoid the performance penalty upon reads of hopping from the index to the heap file.&lt;/li&gt; 
 &lt;li&gt;A compromise between a clustered index and a non-clustered index is a &lt;em&gt;covering index&lt;/em&gt;, which stores &lt;em&gt;some&lt;/em&gt; of the table&apos;s columns within the index (the index &lt;em&gt;covers&lt;/em&gt; the query).&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Multi-column indexes&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;Multi-dimensional indexes allow querying several columns at once, which is important for geospatial data. But more commonly indexes like R-trees are used.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Full-text search and fuzzy indexes&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;In Lucene, the in-memory index is a finite state automaton over the characters in the keys, similar to a trie.&lt;/li&gt; 
 &lt;li&gt;This automaton can be transformed into a &lt;em&gt;Levenshtein automaton&lt;/em&gt;, which supports efficient search for words within a given edit distance.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Keeping everything in memory&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;In-memory databases are faster because they avoid the overheads of encoding in-memory data structures in a form that can be written to disk.&lt;/li&gt; 
 &lt;li&gt;In-memory databases are not faster because they don&apos;t need to read from disk – the operating system caches recently used disk blocks in memory anyway.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Transaction Processing or Analytics?&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;em&gt;Transaction processing&lt;/em&gt; just means allowing clients to make low-latency reads and writes, as opposed to &lt;em&gt;batch-processing&lt;/em&gt; jobs which only run periodically.&lt;/li&gt; 
 &lt;li&gt;OLTP, or &lt;em&gt;online transaction processing&lt;/em&gt;, is the access pattern for &quot;interactive applications&quot; driven by the user&apos;s input.&lt;/li&gt; 
 &lt;li&gt;OLAP, or &lt;em&gt;online analytic processing&lt;/em&gt;, scans over a huge number of records, reading only a few columns per record, and computes aggregates (e.g. sum, count, or average).&lt;/li&gt; 
 &lt;li&gt;The separate database on which OLAP queries are run is called the &lt;em&gt;data warehouse&lt;/em&gt;.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;Data Warehousing&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;em&gt;Extract-Transform-Load&lt;/em&gt; or ETL is the process of extracting data from the OLTP database, transforming it into an analysis-friendly schema, and loading it into the data warehouse.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;The divergence between OLTP databases and data warehouses&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;OLTP and OLAP are increasingly becoming two separate storage and query engines, which happen to be accessible through a common SQL interface.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;Stars and Snowflakes: Schemas for Analytics&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;Many data warehouses are used in a formulaic style known as &lt;em&gt;star schema&lt;/em&gt; (also known as &lt;em&gt;dimensional modeling&lt;/em&gt;).&lt;/li&gt; 
 &lt;li&gt;The center of the schema is a &lt;em&gt;fact table&lt;/em&gt; where each row represents an event that occurred at a particular time.&lt;/li&gt; 
 &lt;li&gt;Columns in the fact table are attributes or foreign keys into &lt;em&gt;dimension tables&lt;/em&gt;, which represent the &lt;em&gt;who&lt;/em&gt;, &lt;em&gt;what&lt;/em&gt;, &lt;em&gt;where&lt;/em&gt;, &lt;em&gt;when&lt;/em&gt;, &lt;em&gt;why&lt;/em&gt;, and &lt;em&gt;how&lt;/em&gt; of the event.&lt;/li&gt; 
 &lt;li&gt;The name &lt;em&gt;star schema&lt;/em&gt; comes from visualizing the fact table in the middle, connected to its surrounding dimension tables like rays in a star.&lt;/li&gt; 
 &lt;li&gt;A variation of this is the &lt;em&gt;snowflake schema&lt;/em&gt;, where dimensions are further broken down into subdimensions.&lt;/li&gt; 
 &lt;li&gt;In a typical data warehouse, tables are often very wide: fact tables have over 100 columns, and sometimes several hundred.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Column-Oriented Storage&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;Although fact tables are often over 100 columns wide, a typical data warehouse query only accesses 4 or 5 of them at one time.&lt;/li&gt; 
 &lt;li&gt;&lt;em&gt;Column-oriented storage&lt;/em&gt; stores all the values from each column together, instead of all the values from each row together.&lt;/li&gt; 
 &lt;li&gt;The column-oriented storage layout relies on each column file containing the rows in the same order.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;Column Compression&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;We can convert a column with &lt;em&gt;n&lt;/em&gt; distinct values into n separate bitmaps, with one bitmap for each distinct value, and one bit for each row.&lt;/li&gt; 
 &lt;li&gt;If &lt;em&gt;n&lt;/em&gt; is large, then the bitmaps will be sparse, and the bitmaps can additionally be run-length encoded to make them very compact.&lt;/li&gt; 
 &lt;li&gt;An &lt;code&gt;IN&lt;/code&gt; SQL query can be implemented by a bitwise &lt;em&gt;OR&lt;/em&gt; of bitmaps, while an &lt;code&gt;AND&lt;/code&gt; SQL query can be implemented by a bitwise &lt;em&gt;AND&lt;/em&gt; of bitmaps.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Memory bandwidth and vectorized processing&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;em&gt;Vectorized processing&lt;/em&gt; is where operators like bitwise &lt;em&gt;AND&lt;/em&gt; and &lt;em&gt;OR&lt;/em&gt; operate on chunks of compressed column data directly.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;Sort Order in Column Storage&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;In column store, the ordering of rows is irrelevant, and so inserting a new row requires simply appending to each of the column files.&lt;/li&gt; 
 &lt;li&gt;If after choosing an order, the primary sort column does not have many distinct values, then a simple run-length encoding can compress it efficiently.&lt;/li&gt; 
 &lt;li&gt;Run-length encoding compresses the first sort key best, as subsequent sort keys will not have such long runs of repeated values.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Several different sort orders&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;In a column store, there normally aren&apos;t pointers to data elsewhere, only columns containing values.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;Writing to Column-Oriented Storage&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;Unlike B-trees, which use an update-in-place approach, LSM-trees allow inserting a row with compressed columns without rewriting all the column files.&lt;/li&gt; 
 &lt;li&gt;When using an LSM-tree, it doesn&apos;t matter whether the in-memory store is row-oriented or column-oriented.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;Aggregation: Data Cubes and Materialized Views&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;A materialized view is an actual copy of the query results written to disk, while a virtual view is just a shortcut for writing queries.&lt;/li&gt; 
 &lt;li&gt;A &lt;em&gt;data cube&lt;/em&gt; or &lt;em&gt;OLAP cube&lt;/em&gt; is a materialized view. It is a grid of aggregates grouped by different dimensions.&lt;/li&gt; 
 &lt;li&gt;The advantage of a materialized data cube is that certain queries become very fast because they have effectively been precomputed.&lt;/li&gt; 
 &lt;li&gt;The disadvantage is that a data cube doesn&apos;t have the same flexibility as querying the raw data.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Summary&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;Analytic workloads require sequentially scanning across a large number of rows, and so indexes are much less relevant.&lt;/li&gt; 
 &lt;li&gt;Instead it is more important to encode data compactly, in order to minimize the amount of data that the query needs to read from disk.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Chapter 4: Encoding and Evolution&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;Backward compatibility means newer code can read data written by older code. Forward compatibility means older code can read data written by newer code.&lt;/li&gt; 
 &lt;li&gt;Forward compatibility is trickier because it requires older code to ignore additions made by a newer version of the code.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Formats for Encoding Data&lt;/h4&gt; 
&lt;h5&gt;Language-Specific Formats&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;Using a language&apos;s built-in encoding functionality is bad from interoperability, security, efficiency, and versioning perspectives.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;JSON, XML, and Binary Variants&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;JSON distinguishes strings and numbers, but it doesn&apos;t distinguish integers and floating-point numbers, and it doesn&apos;t specify a precision.&lt;/li&gt; 
 &lt;li&gt;Base64-encoding a binary string to use it in XML or JSON increases the data size by 33%.&lt;/li&gt; 
 &lt;li&gt;Simply having different organizations agree on a single format is far more important than the aesthetics or efficiency of a format.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Binary encoding&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;Because JSON and XML don&apos;t prescribe a schema, they need to include all the object field names within the encoded data.&lt;/li&gt; 
 &lt;li&gt;It&apos;s not clear whether the small space reduction by MessagePack, a binary encoding for JSON, is worth the loss of human-readability.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;Thrift and Protocol Buffers&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;Confusingly, Thrift has two binary encoding formats, called &lt;em&gt;BinaryProtocol&lt;/em&gt; and &lt;em&gt;CompactProtocol&lt;/em&gt;.&lt;/li&gt; 
 &lt;li&gt;Field tags are like aliases for fields –&amp;nbsp;they are a compact way of saying what field we&apos;re talking about without spelling out its name.&lt;/li&gt; 
 &lt;li&gt;Variable length integers use the top bit of each byte to specify whether there are still more bytes to come.&lt;/li&gt; 
 &lt;li&gt;With variable length integers, the numbers -64 to 63 are encoded in one byte, -8192 to 8191 are encoded in two bytes, etc. Bigger numbers use more bytes.&lt;/li&gt; 
 &lt;li&gt;The &lt;code&gt;required&lt;/code&gt; keyword of Protocol Buffers enables a runtime check that fails if the field is not set, which is useful for catching bugs.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Field tags and schema evolution&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;With Thrift and Protocol Buffers, you can change a field name, but changing its tag renders all existing encoded data invalid.&lt;/li&gt; 
 &lt;li&gt;If old code reads data written by new code, including a new field with an unrecognized tag, it can simply ignore that field. This maintains forward compatibility.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Datatypes and schema evolution&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;With Protocol Buffers, it&apos;s okay to change an &lt;code&gt;optional&lt;/code&gt; (single-valued) field into a &lt;code&gt;repeated&lt;/code&gt; (multi-valued) field.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;Avro&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;Avro has two schema languages: Avro IDL is intended for human editing, and a JSON equivalent that is more easily machine-readable.&lt;/li&gt; 
 &lt;li&gt;An encoded byte string specifies nothing to identify fields or their data types. It simply consists of values concatenated together.&lt;/li&gt; 
 &lt;li&gt;Consequently the binary data can only be decoded correctly if the code reading the data is using the &lt;em&gt;exact same schema&lt;/em&gt; as the code that wrote the data.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;The writer&apos;s schema and the reader&apos;s schema&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;While decoding data, Avro resolves the differences between the &lt;em&gt;writer&apos;s schema&lt;/em&gt; and the &lt;em&gt;reader&apos;s schema&lt;/em&gt;, and translates read data from the former to the latter. This enables schema evolution.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Schema evolution rules&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;Adding a field that has no default value breaks backward compatibility. Removing a field that has no default value breaks forward compatibility.&lt;/li&gt; 
 &lt;li&gt;Avro doesn&apos;t have &lt;code&gt;optional&lt;/code&gt; or &lt;code&gt;required&lt;/code&gt; keywords like Thrift and Protocol buffers, but instead allows defining union types with &lt;code&gt;null&lt;/code&gt; as a value.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Dynamically generated schemas&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;Because an Avro schema doesn&apos;t define tag numbers, it is friendlier to dynamically generated schemas, e.g. creating an Avro schema from a relational database schema.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;The Merits of Schemas&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;Database vendors provide a driver (e.g. using the ODBC or JDBC APIs) that decode responses from a database&apos;s network protocol into in-memory data structures.&lt;/li&gt; 
 &lt;li&gt;Schema evolution allows the same flexibility as schemaless/schema-on-read JSON databases, while also providing better guarantees about your data and better tooling.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Modes of Dataflow&lt;/h4&gt; 
&lt;h5&gt;Dataflow through Databases&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;In an environment where the application is changing, it&apos;s likely that some processes accessing the database will be running newer code and some will be running older code.&lt;/li&gt; 
 &lt;li&gt;Consequently a value in the database might be written by a newer version of the code, and then later read by an older version. And so forward compatibility is required.&lt;/li&gt; 
 &lt;li&gt;If an application decodes a database value into model objects, and then later re-encodes those model objects, the unknown fields may be lost in that translation process.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Different values written at different times&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;Data outlives code: While deploys may replace older code with newer code within minutes, data in the database may have last been encoded and written years ago.&lt;/li&gt; 
 &lt;li&gt;Rewriting (migrating) data into a new schema is possible, but it is expensive on a large data set, and so most databases avoid it if possible.&lt;/li&gt; 
 &lt;li&gt;Schema evolution allows a database to appear as if it was encoded with a single schema, although the underlying storage may contain records encoded with various historical schema versions.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;Dataflow Through Services: REST and RPC&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;The application-specific APIs of services provide encapsulation, by restricting what clients can and cannot do.&lt;/li&gt; 
 &lt;li&gt;A key design goal of service-oriented/microservices architecture is to make the application easier to change and maintain by making services independently deployable and evolvable.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Web services&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;The two popular approaches to web services are REST and SOAP.&lt;/li&gt; 
 &lt;li&gt;REST emphasizes data formats, using URLs for identifying resources and using HTTP features for cache-control, authentication, and content-type negotiation.&lt;/li&gt; 
 &lt;li&gt;SOAP is an XML protocol for API requests, and comes with a sprawling set of related standards (the &lt;em&gt;web standards framework&lt;/em&gt;, or &lt;em&gt;WS-&lt;/em&gt;) that add various features.&lt;/li&gt; 
 &lt;li&gt;The API of a SOAP web service is described using an XML-based language called the Web Services Descriptive Language, or WSDL. WSDL enables code generation so that a client can access a remote service using local classes and method calls.&lt;/li&gt; 
 &lt;li&gt;WSDL is not designed to be human-readable, and SOAP messages are often too complex to construct manually, so tooling, code generation, and IDEs fill in the gaps.&lt;/li&gt; 
 &lt;li&gt;Despite the ostensible standards, interoperability between different vendors&apos; implementations often causes problems in practice.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;The problems with remote procedure calls (RPCs)&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;The RPC model tries to make a request to a remote service look the same as calling a method within the same process –&amp;nbsp;an abstraction called &lt;em&gt;location transparency&lt;/em&gt;.&lt;/li&gt; 
 &lt;li&gt;Variable latency, timeouts, retries and idempotence semantics, and serialization all mean there&apos;s no point in location transparency. Calling a remote service is fundamentally different.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Current directions for RPC&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;The new generation of RPC frameworks is more explicit about the fact that a remote request is different from a local function call.&lt;/li&gt; 
 &lt;li&gt;RESTful APIs have the advantage of being good for experimentation and debugging, support by all mainstream programming languages and platforms, and a vast ecosystem of available tools.&lt;/li&gt; 
 &lt;li&gt;For these reasons, REST is used for public APIs, while RPC frameworks mostly focus on requests between services owned by the same organization.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Data encoding and evolution for RPC&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;Between services using RPC, we assume servers will be updated first, and clients second. You therefore need backward compatibility on requests, and forward compatibility on responses.&lt;/li&gt; 
 &lt;li&gt;The backward and forward compatibility properties of an RPC scheme are inherited from whatever encoding it uses, such as Thrift or gRPC.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;Message-Passing Dataflow&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;In &lt;em&gt;asynchronous message-passing&lt;/em&gt; systems, messages are delivered to an intermediary called a &lt;em&gt;message broker&lt;/em&gt; which stores the message temporarily.&lt;/li&gt; 
 &lt;li&gt;Message brokers can act as a buffer if the recipient is unavailable or overloaded, redeliver messages to crashed processes, deliver messages to multiple recipients, and decouple producers and consumers.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Message brokers&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;A process sends a message to a named &lt;em&gt;queue&lt;/em&gt; or &lt;em&gt;topic&lt;/em&gt;, and the broker ensures delivery of the message to one or more &lt;em&gt;consumers&lt;/em&gt; or &lt;em&gt;subscribers&lt;/em&gt; of that queue or topic.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Distributed actor frameworks&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;In the &lt;em&gt;actor model&lt;/em&gt;, logic is encapsulated by actors that communicate via asynchronous messages, where delivery of each message is not guaranteed (even within the same process).&lt;/li&gt; 
 &lt;li&gt;In a &lt;em&gt;distributed actor framework&lt;/em&gt;, location transparency works better than with RPC, because the actor model already assumes that messages may be lost.&lt;/li&gt; 
 &lt;li&gt;A distributed actor framework essentially integrates a message broker and the actor programming model into a single framework.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Chapter 5: Replication&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;Reasons to replicate data include reducing access latency by moving data geographically close to users, increasing availability, and increasing read throughput.&lt;/li&gt; 
 &lt;li&gt;All the difficulty in replication lies in handling &lt;em&gt;changes&lt;/em&gt; to replicated data.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Leaders and Followers&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;em&gt;Leader-based replication&lt;/em&gt;, or &lt;em&gt;active/passive replication&lt;/em&gt;, is the most common solution to ensuring that data is persisted to all replicas.&lt;/li&gt; 
 &lt;li&gt;Whenever the leader writes new data to its local storage, it also sends the data change to each of its followers via a &lt;em&gt;replication log&lt;/em&gt; or &lt;em&gt;change stream&lt;/em&gt;.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;Synchronous Versus Asynchronous Replication&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;With &lt;em&gt;synchronous&lt;/em&gt; replication, the leader waits until a follower has confirmed it received a write before reporting success to the user and making it visible to other clients.&lt;/li&gt; 
 &lt;li&gt;With &lt;em&gt;asynchronous&lt;/em&gt; replication, the leader sends the write to a follower, but doesn&apos;t wait for a response.&lt;/li&gt; 
 &lt;li&gt;If a synchronous follower does not respond because of a crash, network fault, etc. then no writes can be processed, and so fully synchronous replication is impractical.&lt;/li&gt; 
 &lt;li&gt;In practice replication may be &lt;em&gt;semi-synchronous&lt;/em&gt;, where one of the followers is synchronous and the rest are asynchronous.&lt;/li&gt; 
 &lt;li&gt;Leader-based replication is often completely asynchronous:&lt;/li&gt; 
 &lt;li&gt;As an advantage, if the leader fails and is not recoverable, any writes that have not yet been replicated are lost.&lt;/li&gt; 
 &lt;li&gt;As a disadvantage, the leader can continue processing writes, even if all of its followers have fallen behind.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;Setting Up New Followers&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;A new follower must ingest a consistent snapshot of the leader&apos;s database, and then consume all updates from the replication log since that time.&lt;/li&gt; 
 &lt;li&gt;A position in the leader&apos;s replication log is called the &lt;em&gt;log sequence number&lt;/em&gt; in PostgreSQL, and the &lt;em&gt;binlog coordinates&lt;/em&gt; in MySQL.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;Handling Node Outages&lt;/h5&gt; 
&lt;h6&gt;Follower failure: Catch-up recovery&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;The follower can connect to the leader and, via the replication log, consume all data changes that occurred while the follower was disconnected.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Leader failure: Failover&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;A &lt;em&gt;failover&lt;/em&gt; requires promoting one follower as the new leader, reconfiguring clients to send data to the new leader, and reconfiguring other followers to consume data changes from the new leader.&lt;/li&gt; 
 &lt;li&gt;Most systems simply rely on a timeout to determine that the leader has failed.&lt;/li&gt; 
 &lt;li&gt;The best candidate for leadership is usually the replica with the most up-to-date changes from the old leader, to minimize any data loss.&lt;/li&gt; 
 &lt;li&gt;If asynchronous replication is used, the new leader may not have received all writes from the old leader before it failed. If the former leader later rejoins the cluster after the new leader has processed new writes, it usually discards the un-replicated writes.&lt;/li&gt; 
 &lt;li&gt;In a &lt;em&gt;split brain&lt;/em&gt;, two nodes both believe they are the leader. If there is no process for resolving conflicting writes, this leads to data loss or corruption.&lt;/li&gt; 
 &lt;li&gt;Because failovers are fraught with things that can go wrong, some operations teams prefer to perform them manually.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;Implementation of Replication Logs&lt;/h5&gt; 
&lt;h6&gt;Statement-based replication&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;Replicating every write request (statement) from a leader to its followers has many edge cases (e.g. non-determinism from &lt;code&gt;NOW()&lt;/code&gt; or &lt;code&gt;RAND()&lt;/code&gt;) and is not preferred.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Write-ahead log (WAL) shipping&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;The WAL details which bytes were changed in which blocks. It&apos;s thus a poor choice for a replication log, e.g. you cannot run different versions of the database on leaders and followers.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Logical (row-based) log replication&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;A logical log is a sequence of records describing writes to database tables with row granularity. This is the approach MySQL&apos;s binlog uses.&lt;/li&gt; 
 &lt;li&gt;Logical logs are decoupled from storage engine internals and therefore backward compatible, and are also easier for external applications to parse.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Trigger-based replication&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;A trigger can log data changes into a separate table for reading by an external process.&lt;/li&gt; 
 &lt;li&gt;Trigger-based replication has greater overhead than other replication methods and is more error-prone, but offers increased flexibility.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Problems with Replication Lag&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;If an application reads from an asynchronous follower, it may see outdated information if the follower has fallen behind. This effect is known as &lt;em&gt;eventual consistency&lt;/em&gt;.&lt;/li&gt; 
 &lt;li&gt;The &lt;em&gt;replication lag&lt;/em&gt; to a follower may usually be only a fraction of a second, but given high load or network problems, it can increase to several minutes.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;Reading Your Own Writes&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;em&gt;Read-your-writes&lt;/em&gt; consistency is also known as &lt;em&gt;read-after-write&lt;/em&gt; consistency.&lt;/li&gt; 
 &lt;li&gt;If data is accessed from multiple devices, you may want to provide a stronger guarantee of &lt;em&gt;cross-device&lt;/em&gt; read-after-write consistency.&lt;/li&gt; 
 &lt;li&gt;If your replicas are distributed across different data centers, there is no guarantee that connections from different devices will be routed to the same data center.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;Monotonic Reads&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;If the first query by a user goes to an up-to-date replica, but the second query goes to a stale replica, then the user may observe data &lt;em&gt;moving backward in time&lt;/em&gt;.&lt;/li&gt; 
 &lt;li&gt;&lt;em&gt;Monotonic reads&lt;/em&gt; ensures this anomaly does not happen. It is a weaker guarantee than strong consistency, but a stronger guarantee than eventual consistency.&lt;/li&gt; 
 &lt;li&gt;One way of achieving monotonic reads is to ensure that each user always queries data from the same replica, e.g. using the hash of the user ID.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;Consistent Prefix Reads&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;em&gt;Consistent prefix reads&lt;/em&gt; guarantees that if a sequence of writes happen in a certain order, then anyone reading those writes will see them appear in the same order.&lt;/li&gt; 
 &lt;li&gt;In a sharded database, partitions operate independently, and so there is no global ordering of writes. A user&apos;s query might return some parts of the database in an older state, and some in a newer state.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;Solutions for Replication Lag&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;When working with an eventually consistent system, it&apos;s worth thinking about how the application behaves if replication lag increases to several minutes or hours.&lt;/li&gt; 
 &lt;li&gt;Pretending that replication is synchronous when it is in fact asynchronous is a recipe for problems later.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Multi-Leader Replication&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;In a &lt;em&gt;multi-leader&lt;/em&gt; configuration, or &lt;em&gt;active-active replication&lt;/em&gt;, there are multiple leaders accepting writes, with each acting as a follower to the other leaders.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;Use Cases for Multi-Leader Replication&lt;/h5&gt; 
&lt;h6&gt;Multi-datacenter operation&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;You can have a leader in each data center. Within a datacenter, regular leader-follower replication is used; between datacenters, leaders replicate changes to each other.&lt;/li&gt; 
 &lt;li&gt;With multiple datacenters, the inter-datacenter network delay is hidden from users, which means the perceived performance may be better.&lt;/li&gt; 
 &lt;li&gt;The biggest downside of multi-leader replication is the need to resolve write conflicts if the same data is concurrently modified in two different datacenters.&lt;/li&gt; 
 &lt;li&gt;Auto-incrementing keys, triggers, and integrity constraints are problematic, and so multi-leader replication is considered dangerous territory to be avoided if possible.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Clients with offline operation&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;Clients with offline operation are like multi-leader replication between datacenters, but each device is a &quot;datacenter&quot; and network connections between them are highly unreliable.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;Handling Write Conflicts&lt;/h5&gt; 
&lt;h6&gt;Synchronous versus asynchronous conflict detection&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;With synchronous conflict detection, you lose the advantage of each replica accepting writes independently, and so you might as well just use single-leader replication.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Converging toward a consistent state&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;In a multi-leader configuration there is no defined ordering of writes. But the database must resolve each conflict in a &lt;em&gt;convergent way&lt;/em&gt;, yielding a single final value across all replicas.&lt;/li&gt; 
 &lt;li&gt;Approaches to achieving convergent conflict resolution include:&lt;/li&gt; 
 &lt;li&gt;&lt;em&gt;Last write wins&lt;/em&gt; (LWW): Append the timestamp to each write, and apply the write with the largest value, discarding the others. This is dangerously prone to data loss.&lt;/li&gt; 
 &lt;li&gt;Somehow merge the values together.&lt;/li&gt; 
 &lt;li&gt;Record the conflict in an explicit data structure that preserves all information, and write application code to resolve the conflict later.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Custom conflict resolution logic&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;em&gt;Conflict-free replicated data types&lt;/em&gt; (CDRTs) are data structures (e.g. sets, maps, ordered lists, etc) that automatically resolve conflicts in sensible ways.&lt;/li&gt; 
 &lt;li&gt;&lt;em&gt;Mergeable persistent data structures&lt;/em&gt; track history explicitly and use a three-way merge function (similar to Git).&lt;/li&gt; 
 &lt;li&gt;&lt;em&gt;Operational transformations&lt;/em&gt; are for concurrent editing of an ordered list of items, and are used by Etherpad and Google Docs.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;Multi-Leader Replication Topologies&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;The most general topology is all-to-all in which every leader sends its writes to every other leader.&lt;/li&gt; 
 &lt;li&gt;The fault tolerance of a more densely connected topology is better because it allows messages to travel along different paths, avoiding a single point of failure.&lt;/li&gt; 
 &lt;li&gt;One problem with all-to-all topologies is that if some network links are faster than others, some messages can overtake others, e.g. an update arriving before the preceding insert.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Leaderless Replication&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;Amazon&apos;s Dynamo has popularized abandoning the concept of a leader and allowing any replica to directly accept writes from clients.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;Writing to the Database When a Node is Down&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;Writes are sent to all nodes in parallel. To account for a node being down and missing a write, clients read from nodes in parallel, and rely on version numbers to retain the latest value.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Read repair and anti-entropy&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;With &lt;em&gt;read repair&lt;/em&gt;, a client reads from several nodes in parallel and then writes the latest value back to any replicas from which it received stale data. This works well for values that are frequently read.&lt;/li&gt; 
 &lt;li&gt;An &lt;em&gt;anti-entropy process&lt;/em&gt; runs in the background, comparing data between replicas and fixing stale data. This does not copy writes in any particular order and may be slow to fix differences.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Quorums for reading and writing&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;If there are &lt;em&gt;n&lt;/em&gt; replicas, every write must be confirmed by &lt;em&gt;w&lt;/em&gt; nodes to be considered successful, and we must query at least &lt;em&gt;r&lt;/em&gt; nodes for each read.&lt;/li&gt; 
 &lt;li&gt;As long as &lt;em&gt;w + r &amp;gt; n&lt;/em&gt;, we expect to get an up-to-date value when reading, because at least one of the &lt;em&gt;r&lt;/em&gt; nodes we&apos;re reading from must be up-to-date.&lt;/li&gt; 
 &lt;li&gt;Reads and writes that obey these &lt;em&gt;r&lt;/em&gt; and &lt;em&gt;w&lt;/em&gt; parameters are called &lt;em&gt;quorum&lt;/em&gt; reads and writes.&lt;/li&gt; 
 &lt;li&gt;Normally reads and writes are always sent to all &lt;em&gt;n&lt;/em&gt; nodes in parallel, and &lt;em&gt;r&lt;/em&gt; and &lt;em&gt;w&lt;/em&gt; determine how many nodes we wait for.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;Limitations of Quorum Consistency&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;Often &lt;em&gt;r&lt;/em&gt; and &lt;em&gt;w&lt;/em&gt; are chosen to be more than &lt;em&gt;n/2&lt;/em&gt; nodes, because that ensures &lt;em&gt;w + r &amp;gt; n&lt;/em&gt; while tolerating up to &lt;em&gt;n/2&lt;/em&gt; (rounded down) node failures.&lt;/li&gt; 
 &lt;li&gt;If you choose &lt;em&gt;w + r ≤ n&lt;/em&gt; you are more likely to read stale values, but this configuration allows for lower latency and higher availability.&lt;/li&gt; 
 &lt;li&gt;Even with &lt;em&gt;w + r &amp;gt; n&lt;/em&gt; there are edge cases where stale values are returned:&lt;/li&gt; 
 &lt;li&gt;If two writes occur concurrently, it is not clear which one happened first. You must merge the concurrent writes.&lt;/li&gt; 
 &lt;li&gt;If a write happens concurrently with a read, the write may be reflected only on some of the replicas.&lt;/li&gt; 
 &lt;li&gt;If a write failed on some nodes and overall succeeded on fewer than &lt;em&gt;w&lt;/em&gt; replicas, it is not rolled back on the replicas where it succeeded.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Monitoring staleness&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;In leader-based replication, the replication lag is computed by subtracting the follower&apos;s replication log position from that of the leader.&lt;/li&gt; 
 &lt;li&gt;In systems with leaderless replication, there is no fixed order in which writes are applied, which makes monitoring difficult.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;Sloppy Quorums and Hinted Handoff&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;Network interruptions may cut off a client from a large number of database nodes, such that a quorum for reads and writes cannot be reached.&lt;/li&gt; 
 &lt;li&gt;In a &lt;em&gt;sloppy quorum&lt;/em&gt;, writes and reads still require &lt;em&gt;w&lt;/em&gt; and &lt;em&gt;r&lt;/em&gt; successful responses, but those may include nodes not among the &lt;em&gt;n&lt;/em&gt; &quot;home&quot; nodes for a value.&lt;/li&gt; 
 &lt;li&gt;&lt;em&gt;Hinted handoff&lt;/em&gt; is when, upon the network interruption being fixed, any writes that nodes temporarily accepted are sent to the appropriate &quot;home&quot; nodes.&lt;/li&gt; 
 &lt;li&gt;Even when &lt;em&gt;w + r &amp;gt; n&lt;/em&gt;, a client cannot be sure it read the latest value for a key, because the latest value may be temporarily written to nodes outside of &lt;em&gt;n&lt;/em&gt;.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;Detecting Concurrent Writes&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;When concurrently writing to a Dynamo-style database with the same key, events may arrive in a different order at different nodes due to variable network delays and partial failures.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Last write wins (discarding concurrent writes)&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;If we have some unambiguous way to determine which write is more &quot;recent,&quot; and if every write is copied to every replica, then replicas will eventually converge to the same value.&lt;/li&gt; 
 &lt;li&gt;Concurrent writes do not have a natural ordering, and so &lt;em&gt;last write wins&lt;/em&gt; (LWW) imposes an ordering by associating each write with a timestamp.&lt;/li&gt; 
 &lt;li&gt;LWW trades durability for convergence: Several concurrent writes to the same key may be reported as successful to the client, but only one of the writes will survive.&lt;/li&gt; 
 &lt;li&gt;If losing data is not acceptable, then LWW is a poor choice for conflict resolution.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;The &quot;happens-before&quot; relationship and concurrency&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;An operation A &lt;em&gt;happens before&lt;/em&gt; another operation B if B knows about A, or depends on A, or builds on A in some way.&lt;/li&gt; 
 &lt;li&gt;We can simply say that two operations are &lt;em&gt;concurrent&lt;/em&gt; if neither happens before the other (i.e. neither knows about the other).&lt;/li&gt; 
 &lt;li&gt;Exact time does not matter: If the network is slow, two operations can occur some time apart but still appear to be concurrent, because the network prevented one operation from being able to know about the other.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Capturing the happens-before relationship&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;A server can determine whether two operations are concurrent by looking at version numbers&amp;nbsp;–&amp;nbsp;it does not need to interpret the value itself.&lt;/li&gt; 
 &lt;li&gt;When the server receives a write with a particular version number:&lt;/li&gt; 
 &lt;li&gt;It can overwrite all values with that version number or below, since the client must have merged them into the new value.&lt;/li&gt; 
 &lt;li&gt;It must keep all values with a higher version number, because those values are concurrent with the incoming write.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Merging concurrently written values&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;If several operations happen concurrently, clients must clean up afterward by merging the concurrently written &lt;em&gt;sibling&lt;/em&gt; values.&lt;/li&gt; 
 &lt;li&gt;Merging sibling values is essentially the same problem as conflict resolution in multi-leader replication.&lt;/li&gt; 
 &lt;li&gt;Merging sibling values is complex and error prone, while CRDTs can automatically merge siblings in sensible ways.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Version vectors&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;With multiple replicas, we need to use a version number &lt;em&gt;per replica&lt;/em&gt; as well as per key, so that we know which values to overwrite and which to preserve as siblings.&lt;/li&gt; 
 &lt;li&gt;The collection of version numbers from all the replicas is called a &lt;em&gt;version vector&lt;/em&gt;. It is also sometimes called a &lt;em&gt;vector clock&lt;/em&gt;, even though they are not the same.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Chapter 6: Partitioning&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;Partitioning enables scalability: By distributing data across many disks, the query load can be distributed across many processors.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Partitioning and Replication&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;Partitioning is usually combined with replication so that copies of each partition are stored on multiple nodes for fault tolerance.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Partitioning of Key-Value Data&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;If some partitions have more data or queries than others, then the partitioning is &lt;em&gt;skewed&lt;/em&gt; and is less effective.&lt;/li&gt; 
 &lt;li&gt;A partition with a disproportionately high load is called a &lt;em&gt;hot spot&lt;/em&gt;.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;Partitioning by Key Range&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;When assigning a contiguous range of keys to each partition, the ranges are not necessarily evenly spaced, because your data may not be evenly distributed.&lt;/li&gt; 
 &lt;li&gt;Certain access patterns can lead to hot spots with key range partitioning, e.g. partitioning by timestamp and then always writing to the partition for today.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;Partitioning by Hash of Key&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;When using a hash function to determine the partition for a given key, the hash function does not need to be cryptographically strong.&lt;/li&gt; 
 &lt;li&gt;Each partition is responsible for a range of hashes of keys. Assuming the hash function is uniform, the partition boundaries can be evenly spaced.&lt;/li&gt; 
 &lt;li&gt;Keys that were once adjacent are now scattered across all the partitions, so their sort order is lost.&lt;/li&gt; 
 &lt;li&gt;In Cassandra, the first part of the key is hashed to determine the partition, while the remaining columns are used as a concatenated index into Cassandra&apos;s SSTables.&lt;/li&gt; 
 &lt;li&gt;Cassandra achieves a compromise between the partitioning strategies: If a query specifies a fixed value for the first column, it can perform an efficient range scan over the other columns.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;Skewed Workloads and Relieving Hot Spots&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;Most systems are not able to automatically compensate for a highly skewed workload, and so it&apos;s the responsibility of the application reduce the skew.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Partitioning and Secondary Indexes&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;The problem with secondary indexes is that they don&apos;t map neatly to partitions.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;Partitioning Secondary Indexes by Document&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;Each partition can maintain its own secondary indexes, covering only the documents in the partition. Such a document-partitioned index is called a &lt;em&gt;local index&lt;/em&gt;.&lt;/li&gt; 
 &lt;li&gt;Querying such a partitioned database requires a &lt;em&gt;scatter/gather&lt;/em&gt; operation. Even if querying the partitions in parallel, scatter/gather is prone to tail latency amplification.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;Partitioning Secondary Indexes by Term&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;Rather than each partition having its own secondary index, we can construct a &lt;em&gt;global index&lt;/em&gt; that covers data in all partitions.&lt;/li&gt; 
 &lt;li&gt;Such an index is &lt;em&gt;term-partitioned&lt;/em&gt; because the term you&apos;re looking for determines the partition of the index.&lt;/li&gt; 
 &lt;li&gt;A client needs to query only the partition containing the term it wants, but a write to a single document may update multiple terms and in turn update multiple partitions of the index.&lt;/li&gt; 
 &lt;li&gt;In practice, updates to global secondary indexes are often asynchronous.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Rebalancing Partitions&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;The process of moving load from one node to another is called &lt;em&gt;rebalancing&lt;/em&gt;.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;Strategies for Rebalancing&lt;/h5&gt; 
&lt;h6&gt;How not to do it: hash mod N&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;The problem with the &lt;em&gt;mod N&lt;/em&gt; approach is that if the number of nodes &lt;em&gt;N&lt;/em&gt; changes, then most keys will need to be moved from one node to another.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Fixed number of partitions&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;We can create more partitions than nodes, and then assign multiple partitions to each node. As nodes are added or removed, this assignment changes.&lt;/li&gt; 
 &lt;li&gt;In this configuration, the number of partitions does not change, nor does the assignment of keys to partitions.&lt;/li&gt; 
 &lt;li&gt;By assigning more partitions to nodes that are more powerful, you can force these nodes to take a greater share of the load.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Dynamic partitioning&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;With &lt;em&gt;dynamic partitioning&lt;/em&gt;, partitions are split and merged dynamically based on their size, similar to interior nodes in a B-tree.&lt;/li&gt; 
 &lt;li&gt;An advantage of dynamic partitioning is that the number of partitions adapts to the total data volume.&lt;/li&gt; 
 &lt;li&gt;Dynamic partitioning can be used with both key range-partitioned data, as well as with hash-partitioned data.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Partitioning proportionally to nodes&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;With dynamic partitioning, the number of partitions is proportional to the size of the data set. With a fixed number of partitions, the size of each partition is.&lt;/li&gt; 
 &lt;li&gt;A third option is a fixed number of partitions per node. Since a larger data volume generally requires a larger number of nodes to store, this also keeps the size of each partition stable.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;Operations: Automatic or Manual Rebalancing&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;If not done correctly, rebalancing can overload the network or the nodes and harm the performance of other requests while it is happening.&lt;/li&gt; 
 &lt;li&gt;If a node is overloaded, then automated rebalancing may lead other nodes to conclude the node is dead and move load away from it. This increases load on the other nodes and the network, potentially causing a cascading failure.&lt;/li&gt; 
 &lt;li&gt;While fully automated rebalancing can be convenient, it&apos;s good to have a human in the loop to prevent operational surprises.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Request Routing&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;em&gt;Service discovery&lt;/em&gt; addresses which node a client should connect to, and is a critical requirement for software accessible over a network with high availability.&lt;/li&gt; 
 &lt;li&gt;Any component making the routing decision (a random node, a routing tier, or a client) must learn about changes in the assignment of partitions to nodes.&lt;/li&gt; 
 &lt;li&gt;Many distributed systems rely on a separate coordination service such as ZooKeeper to track this cluster metadata.&lt;/li&gt; 
 &lt;li&gt;Cassandra and Riak use a &lt;em&gt;gossip protocol&lt;/em&gt; among the nodes to disseminate any changes in cluster state.&lt;/li&gt; 
 &lt;li&gt;When a random node or a routing tier makes the routing decision, clients can use DNS to find their IP addresses as their assignment changes slowly.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Chapter 7: Transactions&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;Transactions &lt;em&gt;simplify the programming model&lt;/em&gt; for applications accessing a database.&lt;/li&gt; 
 &lt;li&gt;A &lt;em&gt;safety guarantee&lt;/em&gt; is when the database prevents a potential error and concurrency issue, and so the application does not have to compensate for it.&lt;/li&gt; 
 &lt;li&gt;Sometimes there are advantages to weakening transaction guarantees or abandoning them entirely, e.g. for higher performance or higher availability.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;The Slippery Concept of a Transaction&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;Transactions are not the antithesis of stability. But like every other technical design choice, they come with trade-offs.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;The Meaning of ACID&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;In practice, one database&apos;s implementation of &lt;em&gt;ACID&lt;/em&gt; does not equal that of another. ACID has become mostly a marketing term.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Atomicity&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;Atomicity is not about concurrency, but about ensuring that when a transaction is aborted, that no data was changed and the operation can be safely retried.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Consistency&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;Consistency means that there exist invariants about your data, but it is the application&apos;s responsibility to define its transactions so that they preserve consistency.&lt;/li&gt; 
 &lt;li&gt;Atomicity, isolation, and durability are properties of the database, whereas consistency is actually a property of the application.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Isolation&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;Isolation means that concurrently executing transactions do not step on each other&apos;s toes.&lt;/li&gt; 
 &lt;li&gt;Isolation is sometimes formalized as &lt;em&gt;serializability&lt;/em&gt;, where each transaction can pretend like it&apos;s the only transaction running, but this carries a large performance penalty.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Durability&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;Durability means that once a transaction has committed successfully, its written data will not be forgotten, even if there is a hardware fault or the database crashes.&lt;/li&gt; 
 &lt;li&gt;To provide durability, a database must wait until writing to non-volatile storage or replication has completed before reporting a transaction as committed.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;Single-Object and Multi-Object Operations&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;Atomicity gives all-or-nothing guarantees when writing data in a transaction, and isolation ensures concurrently running transactions don&apos;t interfere with each other.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Single-object writes&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;For a single object in a storage engine, atomicity can be implemented using a log for crash recovery, and isolation can be implemented using a lock on each object.&lt;/li&gt; 
 &lt;li&gt;Compare-and-set and other single-object operations are not transactions, because they do not allow grouping multiple operations on multiple objects.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;The need for multi-object transactions&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;Use cases where writes to several different objects need to be coordinated include:&lt;/li&gt; 
 &lt;li&gt;Inserting several records that refer to one another and ensuring that their foreign keys are valid.&lt;/li&gt; 
 &lt;li&gt;Updating denormalized data across several documents together.&lt;/li&gt; 
 &lt;li&gt;Updating secondary indexes to reflect a changed value.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Handling errors and aborts&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;If the database is in danger of violating its guarantee of atomicity, isolation, or durability, then it would rather abandon the transaction than half-finish.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Weak Isolation Levels&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;Concurrency issues happen when one transaction reads data that is concurrently modified by another, or when two transactions try to concurrently modify the same data.&lt;/li&gt; 
 &lt;li&gt;Databases try to hide concurrency issues from application developers by providing &lt;em&gt;transaction isolation&lt;/em&gt;.&lt;/li&gt; 
 &lt;li&gt;&lt;em&gt;Serializable&lt;/em&gt; isolation means the database guarantees that transactions have the same effect as if they ran &lt;em&gt;serially&lt;/em&gt;.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;Read Committed&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;The most basic level of transaction isolation is &lt;em&gt;read committed&lt;/em&gt;, which guarantees &lt;em&gt;no dirty reads&lt;/em&gt; and &lt;em&gt;no dirty writes&lt;/em&gt;.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;No dirty reads&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;em&gt;No dirty reads&lt;/em&gt; means when reading from the database, you will only see data that has been committed.&lt;/li&gt; 
 &lt;li&gt;Any writes by a transaction only become visible to others when that transaction commits, and then all its writes become visible at once.&lt;/li&gt; 
 &lt;li&gt;No dirty reads means transactions won&apos;t see data in a partially updated state, and that a transaction won&apos;t see data that is later rolled back.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;No dirty writes&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;em&gt;No dirty writes&lt;/em&gt; means when writing to the database, you will only overwrite data that has been committed.&lt;/li&gt; 
 &lt;li&gt;Instead of allowing overwriting of uncommitted data, databases usually delay the second write until the first write&apos;s transaction has committed or aborted.&lt;/li&gt; 
 &lt;li&gt;If transactions update multiple objects, dirty writes allow interleaving the writes to the multiple objects.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Implementing read committed&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;Read committed is the default setting in Oracle 11g, PostgreSQL, SQL Server 2012, MemSQL, and many other databases.&lt;/li&gt; 
 &lt;li&gt;To prevent dirty reads, a transaction must acquire a row-level lock before writing and then relinquish it upon committing or aborting.&lt;/li&gt; 
 &lt;li&gt;When a transaction updates a object, other transactions read the old value until the transaction commits, at which point they begin reading the updated value.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;Snapshot Isolation and Repeatable Read&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;em&gt;Read skew&lt;/em&gt; is an example of a &lt;em&gt;non-repeatable read&lt;/em&gt;, where a transaction querying an object at different times sees different values because of concurrent updates.&lt;/li&gt; 
 &lt;li&gt;&lt;em&gt;Read skew&lt;/em&gt; is considered acceptable under read committed isolation, as the client is indeed reading only committed data.&lt;/li&gt; 
 &lt;li&gt;&lt;em&gt;Snapshot isolation&lt;/em&gt; provides a consistent snapshot of the database, so the transaction sees all data that was committed at the start of the transaction.&lt;/li&gt; 
 &lt;li&gt;Snapshot isolation is a boon for long-running read-only queries such as backups and analytics.&lt;/li&gt; 
 &lt;li&gt;Snapshot isolation is supported by PostgreSQL, MySQL with the InnoDB storage engine, Oracle, SQL Server, and others.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Implementing snapshot isolation&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;A key principle of snapshot isolation is that readers never block writers, and writers never block readers. Reads do not require any locks.&lt;/li&gt; 
 &lt;li&gt;With &lt;em&gt;multi-version concurrency control&lt;/em&gt;, the database keeps several different versions of a committed object so that various in-progress transactions can see the database state at different points in time.&lt;/li&gt; 
 &lt;li&gt;When a transaction deletes a row, a garbage collector deletes it later, only when it is certain no transaction can any longer access the deleted data.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Visibility rules for observing a consistent snapshot&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;When a transaction starts, the database enumerates all the IDs of in-progress transactions, and their writes are ignored even if they subsequently commit.&lt;/li&gt; 
 &lt;li&gt;Any writes made by transactions with a later transaction ID – which are strictly increasing, and therefore started after the current transaction –&amp;nbsp;are ignored.&lt;/li&gt; 
 &lt;li&gt;An object is visible if both of the following conditions are true:&lt;/li&gt; 
 &lt;li&gt;When the reader&apos;s transaction started, the transaction that created the object had already committed.&lt;/li&gt; 
 &lt;li&gt;The object is not marked for deletion, or if it is, the transaction that requested deletion had not yet committed when the reader&apos;s transaction started.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Indexes and snapshot isolation&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;With a &lt;em&gt;copy-on-write&lt;/em&gt; strategy for B-tree indexes, parent pages&amp;nbsp;– up to the root of the tree&amp;nbsp;– are copied and updated to point to the new versions of their child pages.&lt;/li&gt; 
 &lt;li&gt;With this strategy, any pages that are not affected by a write do not need to be copied, and remain immutable.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Repeatable read and naming confusion&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;The SQL standard&apos;s definition of isolation levels is flawed – it is ambiguous, imprecise, and not an implementation-independent standard.&lt;/li&gt; 
 &lt;li&gt;No one really knows what repeatable read means: Databases implementing it provide very different guarantees, and most don&apos;t satisfy a formal definition.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;Preventing Lost Updates&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;The &lt;em&gt;lost update&lt;/em&gt; can occur if an application reads some value, modifies it, and writes back the modified value (a &lt;em&gt;read-modify-write&lt;/em&gt; operation).&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Atomic write operations&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;Atomic operations are usually implemented by acquiring an exclusive lock on the object to update. This technique is known as &lt;em&gt;cursor stability&lt;/em&gt;.&lt;/li&gt; 
 &lt;li&gt;Object-relational mapping frameworks make it easy to accidentally perform unsafe read-modify-write operations instead of relying on atomic operations provided by the database.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Explicit locking&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;The &lt;code&gt;FOR UPDATE&lt;/code&gt; clause in SQL indicates that the database should take a lock on all rows returned by the query.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Automatically detecting lost updates&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;PostgreSQL&apos;s repeatable read, Oracle&apos;s serializable, and SQL Server&apos;s snapshot isolation levels automatically detect a lost update and abort the corresponding transaction.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Compare-and-set&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;An update statement with a &lt;code&gt;WHERE&lt;/code&gt; clause specifying the old value may not stop a lost update if it reads from an old snapshot while a concurrent write occurs.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Conflict resolution and replication&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;Locks and compare-and-set operations assume a single up-to-date copy of the data, but multi-leader or leaderless replication does not guarantee this.&lt;/li&gt; 
 &lt;li&gt;But atomic operations can work well in a replicated context, especially if they are commutative.&lt;/li&gt; 
 &lt;li&gt;While the &lt;em&gt;last write wins&lt;/em&gt; (LWW) conflict resolution strategy is prone to lost updates, it is the default in many replicated databases.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;Write Skew and Phantoms&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;em&gt;Write skew&lt;/em&gt; generalizes the lost update problem: Two transactions read the same objects, and then concurrently update some of those objects.&lt;/li&gt; 
 &lt;li&gt;In the special case where different transactions update the same object, you a lost update or a dirty write anomaly, depending on the timing.&lt;/li&gt; 
 &lt;li&gt;If you cannot use a serializable isolation level to prevent write skew, the second-best option is to explicitly lock rows that the transaction depends on.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Phantoms causing write skew&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;In all cases of write skew, a &lt;code&gt;SELECT&lt;/code&gt; query finds rows that match some condition, and then an &lt;code&gt;UPDATE&lt;/code&gt; statement changes the set of rows matching that condition.&lt;/li&gt; 
 &lt;li&gt;If the &lt;code&gt;SELECT&lt;/code&gt; query checks for the &lt;em&gt;absence&lt;/em&gt; of rows matching a search condition, and the write adds a matching row, then &lt;code&gt;SELECT FOR UPDATE&lt;/code&gt; returning no rows can&apos;t attach locks to anything.&lt;/li&gt; 
 &lt;li&gt;A &lt;em&gt;phantom&lt;/em&gt; is when a write in one transaction changes the result of a query in another transaction.&lt;/li&gt; 
 &lt;li&gt;Snapshot isolation avoids phantoms for read-only queries, but in read-write transactions, phantoms can lead to tricky cases of write skew.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Materializing conflicts&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;em&gt;Materializing conflicts&lt;/em&gt; takes a phantom and turns it into a lock conflict on a concrete set of rows that exist in the database.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Serializability&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;Serializable isolation is the strongest isolation level, guaranteeing that transactions executing in parallel yield the same result as if they ran serially.&lt;/li&gt; 
 &lt;li&gt;This means that the database prevents &lt;em&gt;all&lt;/em&gt; possible race conditions.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;Actual Serial Execution&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;Redis, VoltDB, and more use a single-threaded execution model with all data in RAM, which allows transactions to execute much faster than if they had to load data from disk.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Encapsulating transactions in stored procedures&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;Almost all OLTP applications keep transactions short by avoiding interactively waiting for a user within a transaction, because we&apos;re slow at making up our minds.&lt;/li&gt; 
 &lt;li&gt;Even after removing the user, an interactive style between the application and database would yield dreadful throughput in a database without concurrency.&lt;/li&gt; 
 &lt;li&gt;Instead, single-threaded transaction processing requires the application to submit the entire transaction code to the database as a &lt;em&gt;stored procedure&lt;/em&gt;.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Pros and cons of stored procedures&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;With stored procedures and in-memory data, executing all transactions on a single thread become feasible.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Partitioning&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;For applications with high write throughput, the single-threaded transaction processor can become a serious bottleneck.&lt;/li&gt; 
 &lt;li&gt;If you can ensure that each transaction only reads and writes data within some partition, then each partition to have its own independent transaction processing thread.&lt;/li&gt; 
 &lt;li&gt;Since cross-partition transactions have additional coordination overhead, they are much slower than single-partition transactions.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;Two-Phase Locking (2PL)&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;Two-phase &lt;em&gt;locking&lt;/em&gt; sounds very similar to two-phase &lt;em&gt;commit&lt;/em&gt;, but they are completely different things.&lt;/li&gt; 
 &lt;li&gt;In 2PL, writers don&apos;t just block other writers, but they also block readers. Additionally, readers can block writers.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Implementation of two-phase locking&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;2PL is used by the serializable isolation level in MySQL (InnoDB) and SQL Server, and is the repeatable read isolation level in DB2.&lt;/li&gt; 
 &lt;li&gt;Each object in the database has a lock that can be acquired in &lt;em&gt;shared mode&lt;/em&gt; or &lt;em&gt;exclusive mode&lt;/em&gt;:&lt;/li&gt; 
 &lt;li&gt;Multiple readers can hold the lock in shared mode simultaneously, but they must wait for any transaction with an exclusive lock.&lt;/li&gt; 
 &lt;li&gt;A writer must first acquire the lock in exclusive mode. A transaction that first reads and then writes can upgrade its shared lock to an exclusive lock.&lt;/li&gt; 
 &lt;li&gt;The &quot;two-phase&quot; name comes from a transaction acquiring locks in the first phase, and then releasing its locks in the second phase (at the end of the transaction).&lt;/li&gt; 
 &lt;li&gt;The database automatically detects deadlocks betweens transactions and aborts one so that the others can make progress.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Performance of two-phase locking&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;Transaction throughput and query latency with 2PL is worse than under weak isolation because the locking and exclusive access reduces concurrency.&lt;/li&gt; 
 &lt;li&gt;Databases running 2PL have unstable latencies and can be very slow at high percentiles if there is contention in the workload.&lt;/li&gt; 
 &lt;li&gt;Deadlocks happen much more frequently with 2PL, and so clients can waste significant effort retrying transactions repeatedly.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Predicate locks&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;To prevent phantoms, a &lt;em&gt;predicate lock&lt;/em&gt; allows locking all objects that match some search condition.&lt;/li&gt; 
 &lt;li&gt;A predicate lock applies even to objects that don&apos;t yet exist in the database, but which might be added in the future (phantoms).&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Index-range locks&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;Checking for matching locks is time consuming, so most databases with 2PL implement a simplified approximation of predicate locking called &lt;em&gt;index-range locking&lt;/em&gt;.&lt;/li&gt; 
 &lt;li&gt;It&apos;s safe to simplify a predicate by making it match a larger set of objects, as any write that matches the original predicate will also match the approximations.&lt;/li&gt; 
 &lt;li&gt;If there is no suitable index where a range lock can be attached, the database can fall back to a shared lock on the entire table.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;Serializable Snapshot Isolation (SSI)&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;em&gt;Serializable snapshot isolation&lt;/em&gt; (SSI) provides full serializability, but has only a small performance penalty compared to snapshot isolation.&lt;/li&gt; 
 &lt;li&gt;SSI is the serializable isolation level in PostgreSQL since 9.1, and FoundationDB uses a similar algorithm.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Pessimistic versus optimistic concurrency control&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;2PL uses &lt;em&gt;pessimistic&lt;/em&gt; concurrency control: if anything can go wrong (as indicated by another transaction holding a lock), then a transaction must wait.&lt;/li&gt; 
 &lt;li&gt;SSI uses &lt;em&gt;optimistic&lt;/em&gt; concurrency control: a transaction will always forge ahead, but the database will abort it before committing if anything bad happened (i.e. isolation was violated).&lt;/li&gt; 
 &lt;li&gt;Given enough capacity, and if contention between transactions is not too high, optimistic concurrency control techniques perform better than pessimistic ones.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Decisions based on an outdated premise&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;Under snapshot isolation, the result of a query before updating may no longer be up-to-date when the transaction commits, because it may have been concurrently modified.&lt;/li&gt; 
 &lt;li&gt;We say the transaction was based on a &lt;em&gt;premise&lt;/em&gt;, or a fact that was true at the start of the transaction, but may no longer be true by the end.&lt;/li&gt; 
 &lt;li&gt;To provide serializable isolation, the database must detect when a transaction may have acted on an outdated premise and consequently abort it.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Detecting stale MVCC reads&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;When a transaction wants to commit, the database checks whether other transactions have committed writes that it ignored earlier because of MVCC visibility rules. If so, the database aborts the transaction.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Detecting writes that affect prior reads&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;When a transaction writes to the database, it notifies transactions that recently read the affected data that what they read may no longer be up to date.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Performance of serializable snapshot isolation&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;Less detailed tracking of reads and writes is faster but less precise, and consequently may lead to more transactions being aborted than necessary.&lt;/li&gt; 
 &lt;li&gt;The big advantage of SSI over 2PL is that a transaction doesn&apos;t need to block waiting for locks held by another transaction, thereby making query latency more predictable and less variable.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Summary&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;Transactions are an abstraction layer allowing applications to pretend that certain concurrency problems and certain kinds of faults don&apos;t exist.&lt;/li&gt; 
 &lt;li&gt;Only serializable isolation protects against all types of anomalies and race conditions in a database.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Chapter 8: The Trouble with Distributed Systems&lt;/h3&gt; 
&lt;h4&gt;Faults and Partial Failures&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;An individual computer with good software is either fully functional or completely broken, but not something in between.&lt;/li&gt; 
 &lt;li&gt;If an internal fault occurs, we prefer to crash completely rather than returning a wrong result, which are confusing and difficult to debug.&lt;/li&gt; 
 &lt;li&gt;A &lt;em&gt;partial failure&lt;/em&gt; in a distributed system is where some parts break in an unpredictable way, even though other parts of the system are working fine.&lt;/li&gt; 
 &lt;li&gt;The possibility of partial failures and their non-determinism is what makes distributed systems hard to work with.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;Cloud Computing and Supercomputing&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;In a system with thousands of nodes, it&apos;s reasonable to assume that &lt;em&gt;something&lt;/em&gt; is always broken.&lt;/li&gt; 
 &lt;li&gt;We must accept the possibility of partial failure and incorporate fault-tolerance, thereby building a reliable system from unreliable components.&lt;/li&gt; 
 &lt;li&gt;Suspicion, pessimism, and paranoia pay off in distributed systems, so consider and test for a wide range of possible faults in your environment.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Unreliable Networks&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;We focus on &lt;em&gt;shard-nothing distributed systems&lt;/em&gt;, which are a collection of machines connected by a network.&lt;/li&gt; 
 &lt;li&gt;In this kind of network, one node can send a message to another node, but the node makes no guarantees when it will arrive, or if it will arrive at all.&lt;/li&gt; 
 &lt;li&gt;If you send a request to another node and don&apos;t receive a response, it is impossible to tell why.&lt;/li&gt; 
 &lt;li&gt;When a timeout occurs, you still don&apos;t know whether the remote node got your request or not.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;Network Faults in Practice&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;A &lt;em&gt;network partition&lt;/em&gt; or &lt;em&gt;netsplit&lt;/em&gt; is when one part of the network is cut off from the rest due to a network fault.&lt;/li&gt; 
 &lt;li&gt;Whenever any communication happens over a network, it may fail – there is no avoiding it.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;Detecting Faults&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;Many systems need to automatically detect faulty nodes, but the uncertainty about the network makes it difficult to tell whether a node is working or not.&lt;/li&gt; 
 &lt;li&gt;Even if TCP acknowledges that a packet was delivered, the application may have crashed before processing it. The client needs a positive response from the application itself to confirm its processing.&lt;/li&gt; 
 &lt;li&gt;Conversely, if something goes wrong, you have to assume that you will get no response at all.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;Timeouts and Unbounded Delays&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;Prematurely declaring a node as dead is problematic because if it&apos;s actually alive and in the middle of performing some action, having another node take over may perform the action twice.&lt;/li&gt; 
 &lt;li&gt;If the system is struggling with high load, declaring nodes dead prematurely can transfer their load to other nodes, causing a cascading failure.&lt;/li&gt; 
 &lt;li&gt;Asynchronous networks have unbounded delays and most server implementations cannot guarantee handling a request within some maximum time.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Network congestion and queueing&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;em&gt;Network congestion&lt;/em&gt; is when a packet experiences delay because it is queued up for sending onto a busy network link.&lt;/li&gt; 
 &lt;li&gt;When a VM is paused while another VM runs in a virtualized environment, it cannot consume data from the network, and so any incoming data is queued by the virtual machine monitor.&lt;/li&gt; 
 &lt;li&gt;Because UDP does not perform control flow and does not retransmit lost packets, it is a better choice than TCP when delayed data is worthless.&lt;/li&gt; 
 &lt;li&gt;Queueing delays have an especially wide range when a system is close to its maximum capacity, as long queues build up quickly.&lt;/li&gt; 
 &lt;li&gt;In multi-tenant environments, a &lt;em&gt;noisy neighbor&lt;/em&gt; can use a lot of the resources without your knowledge and introduce highly variable network delays.&lt;/li&gt; 
 &lt;li&gt;Rather than using fixed timeouts, systems can continually measure the distribution of response times and their variability and adjust their timeouts accordingly.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;Synchronous Versus Asynchronous Networks&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;A &lt;em&gt;synchronous&lt;/em&gt; network with reserved resources for communication has no queueing, and so the maximum end-to-end latency is fixed. We call this a &lt;em&gt;bounded delay&lt;/em&gt;.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Can we not simply make network delays predictable?&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;Ethernet an IP are packet-switched protocols, which suffer from queueing and thus unbounded delays in the network.&lt;/li&gt; 
 &lt;li&gt;Protocols using packet switching is optimized for &lt;em&gt;bursty traffic&lt;/em&gt;, and dynamically adapt the rate of data transfer to the available network capacity.&lt;/li&gt; 
 &lt;li&gt;With careful use of &lt;em&gt;quality of service&lt;/em&gt; (prioritization of packets) and &lt;em&gt;admission control&lt;/em&gt; (rate limiting senders) we can provide statistically bounded delay.&lt;/li&gt; 
 &lt;li&gt;There is no &quot;correct&quot; value for timeouts - they need to be determined experimentally.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Unreliable Clocks&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;The quartz crystal oscillator powering a clock on a node is not perfectly accurate, and may be faster or slower than those of other machines.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;Monotonic Versus Time-of-Day Clocks&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;Modern computers have a &lt;em&gt;time-of-day clock&lt;/em&gt; and a &lt;em&gt;monotonic clock&lt;/em&gt;.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Time-of-day clocks&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;A time-of-day clock returns the current date and time according to some calendar, also known as the &lt;em&gt;wall-clock time&lt;/em&gt;.&lt;/li&gt; 
 &lt;li&gt;If such a clock is too-far ahead of the NTP server it&apos;s synchronizing with, it can be forcibly reset and jump back to a previous time. This makes it unsuitable for measuring elapsed time.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Monotonic clocks&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;The name &lt;em&gt;monotonic clock&lt;/em&gt; comes from the fact that it is guaranteed to always move forward.&lt;/li&gt; 
 &lt;li&gt;The difference between two monotonic clock values tells you how much time has elapsed, but the &lt;em&gt;absolute&lt;/em&gt; value of the clock is meaningless.&lt;/li&gt; 
 &lt;li&gt;NTP allows the monotonic clock to be sped up or slowed down by up to 0.05%, but it cannot cause the clock to jump forward or backward.&lt;/li&gt; 
 &lt;li&gt;The resolution of monotonic clocks is quite good, as they can measure time intervals in microseconds or less.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;Clock Synchronization and Accuracy&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;Google assumes a drift of 6 ms for a clock that is synchronized every 30 seconds, or 17 seconds for a server that is synchronized once per day.&lt;/li&gt; 
 &lt;li&gt;If a computer&apos;s clock differs too much from an NTP server, it may refuse to synchronize, or the local clock will be forcibly reset.&lt;/li&gt; 
 &lt;li&gt;The best way for NTP servers to handle leap seconds is to perform the leap second adjustment gradually over the course of the day, a technique known as &lt;em&gt;smearing&lt;/em&gt;.&lt;/li&gt; 
 &lt;li&gt;When a VM is paused so that another VM can run, the application experiences the pause as the clock suddenly jumping forward.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;Relying on Synchronized Clocks&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;Incorrect clocks easily go unnoticed. Any bug that results is more likely to be silent and subtle data loss than a dramatic crash.&lt;/li&gt; 
 &lt;li&gt;Any node who&apos;s clock drifts too far from the others should be declared dead and removed from the cluster.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Timestamps for ordering events&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;Fundamental problems with last write wins given inaccurate clocks include:&lt;/li&gt; 
 &lt;li&gt;A node with a lagging clock cannot overwrite values previously written by a node with a fast clock until the clock skew between them has elapsed.&lt;/li&gt; 
 &lt;li&gt;Two nodes can independently generate writes with the same timestamp, especially when the clock has only millisecond precision.&lt;/li&gt; 
 &lt;li&gt;NTP&apos;s synchronization accuracy is limited by the network round-trip time, as well as quartz drift.&lt;/li&gt; 
 &lt;li&gt;&lt;em&gt;Logical clocks&lt;/em&gt; are based on incrementing counters rather than oscillating quartz crystal and are a safer alternative for ordering events.&lt;/li&gt; 
 &lt;li&gt;&lt;em&gt;Physical clocks&lt;/em&gt; are time-of-day and monotonic clocks, which measure actual elapsed time.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Clock readings have a confidence interval&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;Given quartz drift, don&apos;t think of a clock reading as a point in time, but as a range of times within a confidence interval.&lt;/li&gt; 
 &lt;li&gt;Google&apos;s &lt;em&gt;TrueTime&lt;/em&gt; API in Spanner explicitly returns a confidence interval with the earliest possible and latest possible timestamp.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Synchronized clocks for global snapshots&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;The most common implementation of snapshot isolation requires a monotonically increasing transaction ID.&lt;/li&gt; 
 &lt;li&gt;With lots of small, rapid transactions, creating transaction IDs in a distributed system becomes an untenable bottleneck.&lt;/li&gt; 
 &lt;li&gt;If you have two non-overlapping TrueTime confidence intervals in Spanner, then one definitely happened before the other.&lt;/li&gt; 
 &lt;li&gt;To ensure transaction timestamps reflect reality, Spanner waits for the confidence interval length before committing a read-write transaction. This ensures that any transaction that may read the data has a non-overlapping confidence interval.&lt;/li&gt; 
 &lt;li&gt;Google deploys a GPS receiver or atomic clock in each data center to synchronize clocks within 7 ms.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;Process Pauses&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;Reasons for &lt;em&gt;preempting&lt;/em&gt; a running thread for a long time include:&lt;/li&gt; 
 &lt;li&gt;The programming language time might run garbage collection and &quot;stop the world.&quot;&lt;/li&gt; 
 &lt;li&gt;The hypervisor can switch to a different virtual machine. The CPU time spent in other virtual machines is known as &lt;em&gt;steal time&lt;/em&gt;.&lt;/li&gt; 
 &lt;li&gt;Unexpected disk access, such as the Java class loader lazily loading class files on first use.&lt;/li&gt; 
 &lt;li&gt;The server did not disable paging, and so a simple memory access results in a page fault that loads a page from disk into memory.&lt;/li&gt; 
 &lt;li&gt;The Unix process being paused by a &lt;code&gt;SIGSTOP&lt;/code&gt; signal, and so it yields all CPU cycles until it receives a &lt;code&gt;SIGCONT&lt;/code&gt; signal.&lt;/li&gt; 
 &lt;li&gt;A node in a distributed system must assume its execution can be paused, during which the rest of the world keeps moving and may even declare the node dead.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Response time guarantees&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;A &lt;em&gt;hard real-time&lt;/em&gt; system is one where if the software does not respond by some &lt;em&gt;deadline&lt;/em&gt;, the entire system may fail.&lt;/li&gt; 
 &lt;li&gt;In embedded systems, &lt;em&gt;real-time&lt;/em&gt; means that a system is carefully designed and tested to meet specified timing guarantees in all circumstances.&lt;/li&gt; 
 &lt;li&gt;Real-time systems may have lower throughput, since they have to prioritize timely responses above all else.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Limiting the impact of garbage collection&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;If the runtime can warn the application that a node soon requires a GC pause, it can shift traffic to other nodes while the garbage collection runs.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Knowledge, Truth, and Lies&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;A node in the network cannot &lt;em&gt;know&lt;/em&gt; anything for sure –&amp;nbsp;it can only make guesses based on messages it does or does not receive via the network.&lt;/li&gt; 
 &lt;li&gt;In a distributed system, we can state the assumptions we are making about the behavior (the system model) and design the system in a way to meet those assumptions.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;The Truth is Defined by the Majority&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;Many distributed algorithms rely on a &lt;em&gt;quorum&lt;/em&gt;, where decisions require some minimum number of votes from several nodes in order to reduce the dependence on any single node.&lt;/li&gt; 
 &lt;li&gt;Most commonly the quorum is an absolute majority of more than half the nodes, as you cannot have two such majorities with conflicting decisions.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;The leader and the clock&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;There can be problems if the majority of nodes have declared some node dead, but that node still believes it is the single node responsible for some thing.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Fencing tokens&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;With &lt;em&gt;fencing&lt;/em&gt;, when a lock server grants a lock or lease, it can also return a &lt;em&gt;fencing token&lt;/em&gt;, or a number that increases every time.&lt;/li&gt; 
 &lt;li&gt;A resource protected by the lock service can check tokens and reject any requests with an older token than one that has already been processed.&lt;/li&gt; 
 &lt;li&gt;It&apos;s unwise for a service to assume that clients are well behaved, as the people running the clients and those running the service likely have very different priorities.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;Byzantine Faults&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;A &lt;em&gt;Byzantine fault&lt;/em&gt; is when there is the risk that nodes may &quot;lie,&quot; or send arbitrarily faulty or corrupted responses.&lt;/li&gt; 
 &lt;li&gt;The &lt;em&gt;Byzantine Generals Problem&lt;/em&gt; imagines there are &lt;em&gt;n&lt;/em&gt; generals who need to agree, but this is hampered by generals who are traitors.&lt;/li&gt; 
 &lt;li&gt;A system is &lt;em&gt;Byzantine fault-tolerant&lt;/em&gt; if it operates correctly even if some nodes are not obeying the protocol, or if attackers are interfering with the network.&lt;/li&gt; 
 &lt;li&gt;In most server-side data systems, the cost of deploying Byzantine fault-tolerant solutions makes the impracticable.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;System Model and Reality&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;A &lt;em&gt;system model&lt;/em&gt; is an abstraction that describes what things an algorithm may assume.&lt;/li&gt; 
 &lt;li&gt;There are three system models for timing assumptions:&lt;/li&gt; 
 &lt;li&gt;A &lt;em&gt;synchronous model&lt;/em&gt; assumes bounded network delay, bounded process pauses, and bounded clock error.&lt;/li&gt; 
 &lt;li&gt;A &lt;em&gt;partially asynchronous model&lt;/em&gt; mostly behaves like the synchronous model, but can sometimes exceed its bounds for network delay, process pauses, and clock drift.&lt;/li&gt; 
 &lt;li&gt;An &lt;em&gt;asynchronous model&lt;/em&gt; does not allow the model to make any timing assumptions, and in fact does not even have a clock.&lt;/li&gt; 
 &lt;li&gt;There are three system models for node failures:&lt;/li&gt; 
 &lt;li&gt;A &lt;em&gt;crash-stop faults model&lt;/em&gt; assumes a node can fail only by crashing, and once it has crashed it is gone forever.&lt;/li&gt; 
 &lt;li&gt;A &lt;em&gt;crash-recovery faults model&lt;/em&gt; assumes the node can crash but respond at some later time, and that stable storage is preserved while in-memory state is lost.&lt;/li&gt; 
 &lt;li&gt;A &lt;em&gt;Byzantine faults model&lt;/em&gt; assumes nodes can do absolutely anything.&lt;/li&gt; 
 &lt;li&gt;For modeling real systems, the most useful model is partially asynchronous with crash-recovery faults.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Correctness of an algorithm&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;An algorithm is &lt;em&gt;correct&lt;/em&gt; if it always satisfies its &lt;em&gt;properties&lt;/em&gt; in all situations that we assume may occur in that system model.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Safety and liveness&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;Safety is often informally defined as &lt;em&gt;nothing bad happens&lt;/em&gt;, and liveness as &lt;em&gt;something good eventually happens&lt;/em&gt;.&lt;/li&gt; 
 &lt;li&gt;If a safety property is violated, we can point to the exact time at which it was broken. At this time the damage is done, and cannot be undone.&lt;/li&gt; 
 &lt;li&gt;A liveness property may not hold at some point in time, but there is always hope that it may be satisfied in the future.&lt;/li&gt; 
 &lt;li&gt;For distributed algorithms, it&apos;s common to require that safety properties &lt;em&gt;always&lt;/em&gt; hold. Meaning even if all nodes crash, the algorithm must not return a wrong result.&lt;/li&gt; 
 &lt;li&gt;With liveness properties we can make caveats. The definition of the partially synchronous model requires that eventually the system returns to a synchronous state.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Mapping system models to the real world&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;System models help distill the complexity of real systems to a set of faults that we can reason about, so that we can understand the problem and try to solve it systematically.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Summary&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;If you can avoid opening Pandora&apos;s box and simply keep things on a single machine, it&apos;s generally worth doing so.&lt;/li&gt; 
 &lt;li&gt;Distributed sequence number generators like Twitter&apos;s Snowflake cannot guarantee that ordering is consistent with causality, because the timescale at which blocks of IDs are assigned is longer than the timescale of database reads and writes.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Chapter 9: Consistency and Consensus&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;The best way of building fault-tolerant systems is to find some general-purpose abstractions with useful guarantees, implement them once, and then let applications rely on them.&lt;/li&gt; 
 &lt;li&gt;&lt;em&gt;Split brain&lt;/em&gt; is when nodes believe they are the leader, and it often leads to data loss.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Consistency Guarantees&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;A better name for eventual consistency may be &lt;em&gt;convergence&lt;/em&gt;, as we expect all replicas to eventually converge to the same value.&lt;/li&gt; 
 &lt;li&gt;The edge cases of eventual consistency only become apparent when there is a fault in the system or at high concurrency.&lt;/li&gt; 
 &lt;li&gt;Transaction isolation is about avoiding race conditions due to concurrently executing transactions. Distributed consistency is about coordinating the state of replicas in the face of delays and faults.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Linearizability&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;em&gt;Linearizability&lt;/em&gt; (or &lt;em&gt;strong consistency&lt;/em&gt;) is to make a system appear as if there were only one copy of the data, and all operations on it are atomic.&lt;/li&gt; 
 &lt;li&gt;Linearizability is a &lt;em&gt;recency guarantee&lt;/em&gt;: As soon as a client completes a write, all clients reading from the database must be able to see the value just written.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;What Makes a System Linearizable?&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;A linearizable system appears as if it has only a single copy of the data.&lt;/li&gt; 
 &lt;li&gt;A &lt;em&gt;concurrent read&lt;/em&gt; is a read that overlaps in time with the write operation. Because we don&apos;t know whether the write has taken effect when the read operation is processed, it may return either the old value or the new value.&lt;/li&gt; 
 &lt;li&gt;In a linearizable system there must be some point in time at which a register is updated to its new value, and so all subsequent reads must return the new value even if the write operation has not yet completed.&lt;/li&gt; 
 &lt;li&gt;It is possible to test whether a system is linearizable by recording the timings of all requests and responses, and checking whether they can be arranged in a valid sequential order.&lt;/li&gt; 
 &lt;li&gt;Serializability is a isolation property of transactions which guarantees that the transactions behave as if they had executed in some serial order.&lt;/li&gt; 
 &lt;li&gt;Implementations of serializability based on two-phase locking or actual serial execution are typically linearizable.&lt;/li&gt; 
 &lt;li&gt;Snapshot isolation is not linearizable because a consistent snapshot does not include writes that are more recent than the snapshot.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;Relying on Linearizability&lt;/h5&gt; 
&lt;h6&gt;Locking and leader election&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;Electing a leader requires one node successfully acquiring a lock. This system must be linearizable, as all nodes must agree on which node owns the lock.&lt;/li&gt; 
 &lt;li&gt;Consensus algorithms implement linearizability in a fault-tolerant way, but linearizable storage is the foundation for these coordination tasks.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Constraints and uniqueness guarantees&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;A hard uniqueness constraint requires linearizability, while constraints like foreign key or attribute constraints do not require linearizability.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Cross-channel timing dependencies&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;Without the recency guarantees of linearizability, you must be concerned with race conditions between two communication channels.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;Implementing Linearizable Systems&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;The simplest way to implement linearizability is to rely on only a single copy of the data, but that does not tolerate faults.&lt;/li&gt; 
 &lt;li&gt;Single-leader replication is potentially linearizable if you make all reads from the leader&amp;nbsp;– which assumes you know for sure who the leader is – or from synchronously updated followers.&lt;/li&gt; 
 &lt;li&gt;Multi-leader replication are generally not linearizable, because they concurrently process writes on multiple nodes and asynchronously replicate them to other nodes.&lt;/li&gt; 
 &lt;li&gt;Leaderless replication systems with LWW conflict resolution or sloppy quorums are not linearizable.&lt;/li&gt; 
 &lt;li&gt;Quorums where &lt;em&gt;w + r &amp;gt; n&lt;/em&gt; can be linearizable if readers perform read repair synchronously before returning results, and if writers read the latest quorum state before sending writes.&lt;/li&gt; 
 &lt;li&gt;Only linearizable read and write operations can be performed in this way; a linearizable compare-and-set operation cannot, because it requires a consensus algorithm.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;The Cost of Linearizability&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;The &lt;em&gt;CAP theorem&lt;/em&gt; states that applications that don&apos;t require linearizability can be more tolerant of failures:&lt;/li&gt; 
 &lt;li&gt;If your application requires linearizability, then a disconnected replica is &lt;em&gt;unavailable&lt;/em&gt; and must either wait until the network is fixed, or return an error.&lt;/li&gt; 
 &lt;li&gt;If your application doesn&apos;t require linearizability, then a replica can remain &lt;em&gt;available&lt;/em&gt; and process requests even if disconnected.&lt;/li&gt; 
 &lt;li&gt;The CAP theorem encouraged database engineers to explore a wider design space of distributed shared-nothing systems, which were more suitable for implementing large-scale web services.&lt;/li&gt; 
 &lt;li&gt;CAP is sometimes presented as &lt;em&gt;Consistent, Available, Partitioned – pick 2&lt;/em&gt; but partitions are a kind of fault and so they will happen whether you like it or not.&lt;/li&gt; 
 &lt;li&gt;A better way of presenting CAP is &lt;em&gt;Consistent or Available when Partitioned&lt;/em&gt;, as you must choose linearizability or total availability when a network fault occurs.&lt;/li&gt; 
 &lt;li&gt;CAP has little practical value for designing systems as it doesn&apos;t say anything about network delays, dead nodes, or other trade-offs.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Linearizability and network delays&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;The response times of linearizable reads and writes is very high in a network with highly variable network delays, and so weaker consistency models can be much faster.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Ordering Guarantees&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;The leader in single-leader replication determines the &lt;em&gt;order of writes&lt;/em&gt; in the replication log, while serializability ensures that transactions behave as if executed in &lt;em&gt;some sequential order&lt;/em&gt;.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;Ordering and Causality&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;Ordering is recurring because it helps preserve &lt;em&gt;causality&lt;/em&gt;. Cases where causality is important include:&lt;/li&gt; 
 &lt;li&gt;Snapshot isolation provides a snapshot consistent with causality: The effects of all operations that happened causally before that point in time are visible, but no operations that happened causally afterward are seen.&lt;/li&gt; 
 &lt;li&gt;Serializable snapshot isolation detects write skew by tracking the causal dependencies between transactions.&lt;/li&gt; 
 &lt;li&gt;A &lt;em&gt;causally consistent&lt;/em&gt; system obeys the ordering imposed by causality, where chains of causally dependent operations define the causal order in the system.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;The causal order is not a total order&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;In a linearizable system, we have a &lt;em&gt;total order&lt;/em&gt; of operations: For any two operations, we can always say which happened first.&lt;/li&gt; 
 &lt;li&gt;Other consistency models offer a &lt;em&gt;partial order&lt;/em&gt;: Two events are ordered if they are causally related, but they are incomparable if they are concurrent.&lt;/li&gt; 
 &lt;li&gt;There are no concurrent operations in a linearizable datastore, as there must be a single timeline along which all operations are totally ordered.&lt;/li&gt; 
 &lt;li&gt;Concurrency means that the timeline branches and merges again, and that operations on different branches are incomparable (i.e. concurrent).&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Linearizability is stronger than causal consistency&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;Linearizability ensures causality, which is what makes linearizable systems simple to understand and appealing.&lt;/li&gt; 
 &lt;li&gt;Causal consistency is the strongest consistency model that does not slow down due to network delays, and remains available in the face of network failures.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Capturing causal dependencies&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;Concurrent operations may be processed in any order, but if one operation happened before another, then they must be processed in that order on every replica.&lt;/li&gt; 
 &lt;li&gt;Causal consistency must track causal dependencies across the entire database. And to determine the causal ordering, the database must know which version of the data was read by the application.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;Sequence Number Ordering&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;Causality is an important theoretical concept, but actually keeping track of all causal dependencies can become impracticable.&lt;/li&gt; 
 &lt;li&gt;Monotonically increasing &lt;em&gt;sequence numbers&lt;/em&gt; can create a total ordering that is consistent with causality: If operation A happened before operation B, then A occurs before B in the total order.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Noncausal sequence number generators&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;Multiple leaders independently generating sequence numbers will not correctly capture the ordering of operations across different nodes, and are not consistent with causality.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Lamport timestamps&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;If each node has a unique identifier and a count of the number of operations it has processed, its Lamport timestamp is the pair &lt;em&gt;(counter, node ID)&lt;/em&gt;.&lt;/li&gt; 
 &lt;li&gt;Each node and client maintains the maximum counter value it has seen so far and includes it on every request. When a node receives a request or response with a maximum counter value greater than its own counter value, it immediately increases its own counter to that maximum.&lt;/li&gt; 
 &lt;li&gt;The ordering from the Lamport timestamps is consistent with causality, because every causal dependency results in an increased timestamp.&lt;/li&gt; 
 &lt;li&gt;Version vectors can distinguish whether two operations are concurrent or whether one is casually dependent on the other, whereas Lamport timestamps enforce a total ordering.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Timestamp ordering is not sufficient&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;To implement something like a uniqueness constraint for usernames, it&apos;s not sufficient to have a total ordering of operations -&amp;nbsp;you also need to know when that ordering is finalized.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;Total Order Broadcast&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;em&gt;Total order broadcast&lt;/em&gt; or &lt;em&gt;atomic broadcast&lt;/em&gt; is the problem of how to scale the system if the throughput is greater than a single leader can handle, and how to handle failover if the leader fails.&lt;/li&gt; 
 &lt;li&gt;Total ordering across all partitions in a partitioned database is possible, but it requires additional coordination.&lt;/li&gt; 
 &lt;li&gt;Total order broadcast is a protocol for exchanging messages between nodes and requires two safety guarantees: reliable delivery and totally ordered delivery.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Using total order broadcast&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;Consensus services such as ZooKeeper and etcd actually implement total order broadcast.&lt;/li&gt; 
 &lt;li&gt;&lt;em&gt;State machine replication&lt;/em&gt; is the use of total order broadcast for database replication: Every replica processes every write in the same order.&lt;/li&gt; 
 &lt;li&gt;Total order broadcast can be framed as creating a &lt;em&gt;log&lt;/em&gt;, where delivering a message is like appending to the log.&lt;/li&gt; 
 &lt;li&gt;ZooKeeper uses total order broadcast to implement a lock service: Every request to acquire the lock is appended as a message to the log, and all messages in the log are sequentially ordered. The sequence number, or &lt;code&gt;zxid&lt;/code&gt;, serves as a fencing token.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Implementing linearizable storage using total order broadcast&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;You can build linearizable storage on top of total order broadcast by appending a message for each write or read, and then processing the write or read upon reading the message from the log.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Implementing total order broadcast using linearizable storage&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;For every message you want to send through total order broadcast, increment-and-get the linearizable integer, and then attach the register value as a sequence number to the message.&lt;/li&gt; 
 &lt;li&gt;It can be proved that a linearizable compare-and-set (or increment-and-get) register and total order broadcast are both &lt;em&gt;equivalent to consensus&lt;/em&gt;.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Distributed Transactions and Consensus&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;Consensus is needed for leader election, as all nodes need to agree on which node is the leader.&lt;/li&gt; 
 &lt;li&gt;In the &lt;em&gt;atomic commit problem&lt;/em&gt;, all nodes participating in a distributed transaction need to agree on the outcome of the transaction (either all aborting or all committing).&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;Atomic Commit and Two-Phase Commit (2PC)&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;Atomicity ensures that a secondary index stays consistent with the primary data.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;From single-node to distributed atomic commit&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;The deciding moment for whether a transaction commits or aborts is the moment at which the disk finishes writing the commit record: After this moment, the transaction is committed.&lt;/li&gt; 
 &lt;li&gt;Once a transaction has been committed on one node, it cannot be retracted if it later turns out that it was aborted on another node.&lt;/li&gt; 
 &lt;li&gt;If a transaction was allowed to abort after committing, it would violate &lt;em&gt;read committed isolation&lt;/em&gt;, and any transactions that read the committed data would be based on data that was retroactively declared not to have existed.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Introduction to two-phase commit&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;2PC (two-phase commit) provides atomic commit in a distributed database, whereas 2PL (two-phase locking) provides serializable isolation.&lt;/li&gt; 
 &lt;li&gt;2PC requires a &lt;em&gt;coordinator&lt;/em&gt;, or &lt;em&gt;transaction manager&lt;/em&gt;, which is often implemented as a library within the same application process that is requesting the transaction.&lt;/li&gt; 
 &lt;li&gt;When an application is ready to commit, the coordinator begins phase 1, sending a &lt;em&gt;prepare&lt;/em&gt; request to every node asking if it is able to commit.&lt;/li&gt; 
 &lt;li&gt;If all nodes reply &quot;yes&quot; then the coordinator sends a &lt;em&gt;commit&lt;/em&gt; request in phase 2 and the commit actually takes place.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;A system of promises&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;By replying &quot;yes&quot; to the coordinator, a node promises to commit the transaction without error if requested.&lt;/li&gt; 
 &lt;li&gt;The &lt;em&gt;commit point&lt;/em&gt; is when the coordinator writes to its transaction log on disk whether it will go ahead with phase 2 or abort, so that its decision is preserved in case it subsequently crashes.&lt;/li&gt; 
 &lt;li&gt;If the decision was to commit, then that decision must be enforced, no matter how many retires it takes.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Coordinator failure&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;After a node has voted &quot;yes&quot; to a prepare request, it must wait to hear from the coordinator whether to commit or abort.&lt;/li&gt; 
 &lt;li&gt;If a node replies to a prepare request and then the coordinator crashes or the network fails, the node&apos;s transaction state is called &lt;em&gt;in doubt&lt;/em&gt; or &lt;em&gt;uncertain&lt;/em&gt;.&lt;/li&gt; 
 &lt;li&gt;Upon the coordinator recovering from a crash, it computes the status of all in-doubt transactions by reading its transaction log, and aborts any without a commit record.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;Distributed Transactions in Practice&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;Distributed transactions are criticized for causing operational problems, killing performance, and promising more than they can deliver.&lt;/li&gt; 
 &lt;li&gt;The performance cost inherent in 2PC is due to the additional disk forcing (&lt;code&gt;fsync&lt;/code&gt;) that is required for crash recovery, and the additional network round-trips.&lt;/li&gt; 
 &lt;li&gt;Database-internal distributed transactions can often work quite well, while transactions spanning heterogeneous technologies are a lot more challenging.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;XA transactions&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;X/Open XA (for eXtended Architecture) is a C API for interfacing with a transaction coordinator. It is supported by many traditional databases and message brokers.&lt;/li&gt; 
 &lt;li&gt;In practice the transaction coordinator implementing the XA API is a library loaded into the same process as the application issuing the transaction.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Holding locks while in doubt&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;Database transactions take a row-level exclusive lock on any rows they modify, and serializable isolation requires acquiring a shared lock on any rows read by the transaction.&lt;/li&gt; 
 &lt;li&gt;Using 2PC, a transaction must hold onto locks throughout the entire time it is in doubt, which can cause large parts of your application to be unavailable until the in-doubt transaction is resolved.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Recovering from coordinator failure&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;Orphaned in-doubt transactions do occur, which hold locks and block other transactions until they are either manually committed or rolled back by an administrator.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Limitations of distributed transactions&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;When the transaction coordinator is part of the application server, the application servers are no longer stateless because the coordinator logs are a critical part of the durable system state.&lt;/li&gt; 
 &lt;li&gt;Distributed transactions tend to &lt;em&gt;amplify failures&lt;/em&gt;, because if any part of the system is broken then the distributed transaction also fails.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;Fault-Tolerant Consensus&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;Consensus is where one or more nodes may &lt;em&gt;propose&lt;/em&gt; values, and a consensus algorithm &lt;em&gt;decides&lt;/em&gt; on one of those values.&lt;/li&gt; 
 &lt;li&gt;The algorithm must have uniform agreement (no two nodes decide differently), integrity (no node decides twice), validity (a node can decide only on a proposed value), and termination (every node that does not crash eventually decides a value).&lt;/li&gt; 
 &lt;li&gt;The termination property formalizes the idea of fault tolerance, as the consensus algorithm must make progress.&lt;/li&gt; 
 &lt;li&gt;Termination is a liveness property, whereas uniform agreement, integrity, and validity are all safety properties.&lt;/li&gt; 
 &lt;li&gt;Any consensus algorithm requires at least a majority of nodes to be functioning correctly in order to assure termination. This majority can safely form a quorum.&lt;/li&gt; 
 &lt;li&gt;A large-scale outage can stop the consensus system from being able to process requests, but it cannot corrupt the system by causing it to make invalid decisions.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Consensus algorithms and total order broadcast&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;Total order is equivalent to repeated rounds of consensus: In each round, nodes propose the message that they want to send next, and then decide on the next message to be delivered in the total order.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Epoch numbering and quorums&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;Consensus protocols like Raft and Paxos define an &lt;em&gt;epoch number&lt;/em&gt;, and guarantee that within each epoch the leader is unique.&lt;/li&gt; 
 &lt;li&gt;Every time the leader is thought to be dead, a vote is started among the nodes to elect a new leader. This election is given an incremented epoch number.&lt;/li&gt; 
 &lt;li&gt;The quorums for voting for a leader and for voting on a leader&apos;s proposal must overlap. So if a vote on a proposal succeeds, then at least one of the nodes that voted for it must have also participated in the most recent leader election.&lt;/li&gt; 
 &lt;li&gt;If the vote on a proposal doesn&apos;t reveal any higher-numbered epoch, the current leader can conclude that no leader election with a higher epoch number has happened, and so it is still the leader.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Limitations of consensus&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;The process by which nodes vote on proposals before they are decided is a kind of synchronous replication.&lt;/li&gt; 
 &lt;li&gt;Most consensus algorithms assume a fixed set of nodes that participate in voting, meaning you cannot add or remove nodes in the cluster.&lt;/li&gt; 
 &lt;li&gt;In geographically distributed systems, nodes can falsely believe the leader to have failed because of a transient network issue, leading to frequently leader elections that degrade performance.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;Membership and Coordination Services&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;ZooKeeper and etc are designed to hold small amounts of data that fit entirely in memory, which is replicated across all nodes using a fault-tolerant total order broadcast algorithm.&lt;/li&gt; 
 &lt;li&gt;Using an atomic compare-and-set operation, you can implement a lock in ZooKeeper: If several nodes concurrently try to perform the same operation, only one will succeed.&lt;/li&gt; 
 &lt;li&gt;ZooKeeper provides a monotonically increasing fencing token by totally ordering all operations and giving each one a monotonically increasing transaction ID (&lt;code&gt;zxid&lt;/code&gt;) and version number (&lt;code&gt;cversion&lt;/code&gt;).&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Allocating work to nodes&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;Leader election and assigning partitioned resources to nodes can be achieved by judicious use of atomic operations, ephemeral nodes, and notifications in ZooKeeper.&lt;/li&gt; 
 &lt;li&gt;ZooKeeper provides a way of &quot;outsourcing&quot; some of the work of coordinating nodes (consensus, operation ordering, and failure detection) to an external service.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Service discovery&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;ZooKeeper, etc, and consul are often used for &lt;em&gt;service discovery&lt;/em&gt;, which returns the set of IP addresses that are running a given service.&lt;/li&gt; 
 &lt;li&gt;Replicas that asynchronously receive the log of all decisions of the consensus algorithm but don&apos;t participate in the voting can serve read requests that don&apos;t need to be linearizable.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Chapter 10: Batch Processing&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;There are three types of systems:&lt;/li&gt; 
 &lt;li&gt;Services (online systems), where servers wait for a request to arrive and then attempt to send a response back as quickly as possible. Availability and response time are most important metrics.&lt;/li&gt; 
 &lt;li&gt;Bach processing (offline systems), where a job processes some large amount of input data to create output data. Throughput is the most important metric.&lt;/li&gt; 
 &lt;li&gt;Stream processing (near-realtime systems), where a stream job operates on events shortly after they happen.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Batch Processing with Unix Tools&lt;/h4&gt; 
&lt;h5&gt;Simple Log Analysis&lt;/h5&gt; 
&lt;h6&gt;Sorting versus in-memory aggregation&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;If data to sort exceeds available memory, chunks can be sored in memory and written to disk as segment files, and then multiple sorted segments can be merged together into a larger sorted file.&lt;/li&gt; 
 &lt;li&gt;The &lt;code&gt;sort&lt;/code&gt; utility handles larger-than-memory datasets by spilling to disk, and automatically parallelizes sorting across multiple CPU cores.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;The Unix Philosophy&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;The philosophy described in 1978 says: Make each program do one thing well, and expect the output of every program to be the input to another, as yet unknown, program.&lt;/li&gt; 
 &lt;li&gt;A Unix shell like &lt;code&gt;bash&lt;/code&gt; allows us to easily &lt;em&gt;compose&lt;/em&gt; small programs into surprisingly powerful data processing jobs.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;A uniform interface&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;In Unix, all programs use a file descriptor as the input/output interface. That file is just an ordered sequence of bytes.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Separation of logic and wiring&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;Pipes allow you to attach the &lt;code&gt;stdout&lt;/code&gt; of one process to the &lt;code&gt;stdin&lt;/code&gt; of another process with an in-memory buffer, without writing all intermediate data to disk.&lt;/li&gt; 
 &lt;li&gt;Separating the input/output wiring from the program logic makes it easier to compose small tools into bigger systems.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Transparency and experimentation&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;Unix tools are successful in part because it is easy to see what is going on:&lt;/li&gt; 
 &lt;li&gt;The input files are normally treated as immutable, and so you can run the commands repeatedly.&lt;/li&gt; 
 &lt;li&gt;You can pipe the output into &lt;code&gt;less&lt;/code&gt; and look to see if it has the expected form at any point.&lt;/li&gt; 
 &lt;li&gt;By writing the output of one stage to a file and using that file as the input to the next stage, you can restart the later stage without re-running the entire pipeline.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;MapReduce and Distributed Filesystems&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;Hadoop Distributed File System (HDFS) is based on the shard-nothing principle requiring no special hardware, only computers connected by a conventional network.&lt;/li&gt; 
 &lt;li&gt;HDFS consists of a daemon process running on each machine for I/O, and a central server called NameNode to track which file blocks are stored on which machine.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;MapReduce Job Execution&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;The &lt;em&gt;mapper&lt;/em&gt; of a MapReduce job can generate any number of key-value pairs for a given input.&lt;/li&gt; 
 &lt;li&gt;The &lt;em&gt;reducer&lt;/em&gt; processes the collection of values for a given key and can produce output records.&lt;/li&gt; 
 &lt;li&gt;The role of the mapper is to prepare the data by putting it in a form that is suitable for sorting, and the role of the reducer is to process the data that has been sorted.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Distributed execution of MapReduce&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;The mapper and reducer do not know where each input record is coming from or output record is going to, so the framework can handle those complexities.&lt;/li&gt; 
 &lt;li&gt;The MapReduce framework &lt;em&gt;puts computation near the data&lt;/em&gt; by attempting to run each mapper on one of the machines that stores the record of the input file.&lt;/li&gt; 
 &lt;li&gt;While the number of map tasks is determined by the number of input file blocks, the number of reduce tasks is configured by the job author.&lt;/li&gt; 
 &lt;li&gt;Each map task partitions its output by reducer, based on the hash of the key. Each of these partitions is written to a sorted file on the mapper&apos;s local disk.&lt;/li&gt; 
 &lt;li&gt;The reducers download the files of sorted key-value pairs for their partition. The process of partitioning by reducer, sorting, and copying data partitions from mappers to reducers is known as the &lt;em&gt;shuffle&lt;/em&gt;.&lt;/li&gt; 
 &lt;li&gt;When the reduce task merges the files from the mapper it preserves their sorted order, and so the values are iterated over in sorted order.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;MapReduce workflows&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;It&apos;s common for MapReduce jobs to be chained together into &lt;em&gt;workflows&lt;/em&gt;, where the output of one job becomes the input to the next job.&lt;/li&gt; 
 &lt;li&gt;Chained MapReduce jobs are less like pipelines of Unix commands and more like a sequence of commands where each command&apos;s output is written to a temporary file, which the next command reads from.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;Reduce-Side Joins and Grouping&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;Associations between records include a &lt;em&gt;foreign key&lt;/em&gt; in a relational model, &lt;em&gt;document reference&lt;/em&gt; in a document model, or an &lt;em&gt;edge&lt;/em&gt; in a graph model.&lt;/li&gt; 
 &lt;li&gt;A join is necessary whenever you have some code that needs to access records on both sides of that association.&lt;/li&gt; 
 &lt;li&gt;In the context of batch processing, a join means resolving &lt;em&gt;all&lt;/em&gt; occurrences of some association within a data set, and is not limited to a subset of records.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Example: analysis of user activity events&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;To achieve good throughput in a batch process, computation must be (as much as possible) local to one machine. Requests over the network on a per-record basis is too slow.&lt;/li&gt; 
 &lt;li&gt;When data must be joined together, it should be co-located on the same machine.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Sort-merge joins&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;A &lt;em&gt;secondary sort&lt;/em&gt; ensures that a reducer first processes all records on one side of the association first, and then all records on the other side.&lt;/li&gt; 
 &lt;li&gt;A sort-merge join has its name because mapper output is sorted by key, and the reducers then merge together the sorted lists of records from both sides of the join.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Bringing related data together in the same place&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;Having lined up all the data in advance, the reducer can be a simple, single-threaded piece of code that churns through records with high throughput and low memory overhead.&lt;/li&gt; 
 &lt;li&gt;Because MapReduce separates the physical network communication aspects of computation from the application logic, it can transparently retry failed tasks without affecting the application logic.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;GROUP BY&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;The simplest way of implementing &lt;code&gt;GROUP BY&lt;/code&gt; in MapReduce is to configure the mappers so that all produced key-value pairs use the desired grouping key, and then aggregate them in the reducer.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Handling skew&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;Keys with a disproportionate number of values, or &lt;em&gt;hot keys&lt;/em&gt;, can lead to &lt;em&gt;skew&lt;/em&gt; or &lt;em&gt;hot spots&lt;/em&gt; where one reducer must process significantly more records than the others.&lt;/li&gt; 
 &lt;li&gt;This is problematic because any subsequent jobs must wait for the slowest reducer to complete before they can start.&lt;/li&gt; 
 &lt;li&gt;To aggregate values for a hot key, a first stage of aggregation can be distributed across multiple reducers, and then a second stage combines those values to create a single value for the key.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;Map-Side Joins&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;A &lt;em&gt;reduce-side join&lt;/em&gt; where join logic belongs to the reducers is flexible, but all that sorting, copying to reducers, and merging of reducer inputs can be expensive.&lt;/li&gt; 
 &lt;li&gt;A &lt;em&gt;map-side join&lt;/em&gt; makes assumptions about the size, sorting, and partitioning of input data, but removes the needs for reducers and sorting.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Broadcast hash joins&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;In a &lt;em&gt;broadcast hash join&lt;/em&gt;, all the data on one side of the association is loaded into memory and is used directly by the mapper.&lt;/li&gt; 
 &lt;li&gt;The term &lt;em&gt;broadcast&lt;/em&gt; refers to how the small input is &quot;broadcast&quot; to all partitions of the large input, and &lt;em&gt;hash&lt;/em&gt; refers to its use of a hash table.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Partitioned hash joins&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;In a &lt;em&gt;partitioned hash join&lt;/em&gt; all records you might want to join belong to the same partition, and so each mapper can read only one partition from each of the input data sets.&lt;/li&gt; 
 &lt;li&gt;This only works if both of the join&apos;s inputs have the same number of partitions, with records assigned to partitions based on the same key and the same hash function.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Map-side merge joins&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;If the input data sets are not only partitioned in the same way but also sorted by the same key, the mapper can perform the merging operation normally done by a reducer.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;MapReduce workflows with map-side joins&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;The output of a reduce-side join is partitioned and sorted by the join key, whereas the output of a map-side join is partitioned and sorted in the same way as the large input.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;The Output of Batch Workflows&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;Batch processing is closer to analytics in that it typically scans over large portions of an input data set, but its output is often not a report but some other structure.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Key-value stores as batch process output&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;To persist the output of a batch process into a database for querying, writing one record at a time to the database from the mapper or reducer is a bad idea:&lt;/li&gt; 
 &lt;li&gt;Making a network request for every single record is orders of magnitude slower than the normal throughput of a batch task.&lt;/li&gt; 
 &lt;li&gt;If all mappers or reducers concurrently write to the same database, then that database can become overwhelmed.&lt;/li&gt; 
 &lt;li&gt;Partially completed jobs may be visible to other systems, while MapReduce provides a clean all-or-nothing guarantee for job output.&lt;/li&gt; 
 &lt;li&gt;A better solution is to create a new database inside the batch job and write it as files to the job&apos;s output directory in the distributed filesystem.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Philosophy of batch process outputs&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;By treating inputs as immutable and avoiding side-effects, batch jobs not only achieve good performance but also become easier to maintain.&lt;/li&gt; 
 &lt;li&gt;The idea of being able to recover from buggy code has been called &lt;em&gt;human fault tolerance&lt;/em&gt;.&lt;/li&gt; 
 &lt;li&gt;The automatic retry of a map or reduce task is safe only because inputs are immutable and outputs from failed tasks are discarded by the MapReduce framework.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;Comparing Hadoop to Distributed Databases&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;Hadoop is somewhat like a distributed version of Unix, where HDFS is the filesystem and MapReduce is a quirky implementation of a Unix process.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Diversity of storage&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;In practice, making data available quickly – even if in a difficult-to-use, raw format –&amp;nbsp;is more valuable than trying to decide on the ideal data model up front.&lt;/li&gt; 
 &lt;li&gt;A &quot;data lake&quot; or &quot;enterprise data hub&quot; collects data in its raw form, allowing its collection to be expedited.&lt;/li&gt; 
 &lt;li&gt;Instead of forcing the producer of a dataset to bring it into a standardized format, the interpretation of the data becomes the consumer&apos;s problem.&lt;/li&gt; 
 &lt;li&gt;The &lt;em&gt;sushi principle&lt;/em&gt; says raw data is better, as dumping the raw data allows a consumer to transform the data into whatever form is ideal for its purposes.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Diversity of processing models&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;MapReduce is too limiting or performs too badly for some types of processing, and so various other processing models have been developed on top of Hadoop.&lt;/li&gt; 
 &lt;li&gt;These various processing models can all be run on a single shared-use cluster of machines, all accessing the same files on the distributed system.&lt;/li&gt; 
 &lt;li&gt;The Hadoop ecosystem includes random-access OLTP databases such as HBase, and MPP (Massively Parallel Processing) databases such as Impala.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Designing for frequent faults&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;Unlike MPP databases, MapReduce can tolerate the failure of a MapReduce map or reduce task by retrying it, and it eagerly writes data to disk for fault tolerance and in case the data cannot fit entirely in memory.&lt;/li&gt; 
 &lt;li&gt;MapReduce was designed to tolerate frequent faults because MapReduce jobs at Google were run at low priority and could be preempted at any time by higher-priority processes requiring their resources.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Beyond MapReduce&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;MapReduce is robust, but other tools are sometimes orders of magnitude faster for other types of processing.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;Materialization of Intermediate State&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;The process of writing out intermediate state to files is called &lt;em&gt;materialization&lt;/em&gt;.&lt;/li&gt; 
 &lt;li&gt;Pipes in Unix do not fully materialize the intermediate state, but instead &lt;em&gt;stream&lt;/em&gt; one command&apos;s output to the next command&apos;s input using a small in-memory buffer.&lt;/li&gt; 
 &lt;li&gt;Unlike Unix pipes, MapReduce fully materializing intermediate state has downsides:&lt;/li&gt; 
 &lt;li&gt;Having to wait until all of the preceding job&apos;s tasks have completed slows down the execution of the workflow as a whole.&lt;/li&gt; 
 &lt;li&gt;Mappers are often redundant because they just read back the same file that was just written by a reducer, and prepare it for the next stage of partitioning and sorting.&lt;/li&gt; 
 &lt;li&gt;Storing intermediate state in a distributed filesystem replicates it across several nodes, which is overkill for temporary data.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Dataflow engines&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;em&gt;Dataflow engines&lt;/em&gt; model the flow of data through several processing stages. The user-defined functions for operating on the data are called &lt;em&gt;operators&lt;/em&gt;.&lt;/li&gt; 
 &lt;li&gt;Advantages over the MapReduce model include:&lt;/li&gt; 
 &lt;li&gt;Expensive work like sorting is only done in places where it is required, rather than always happening between every map and reduce stage.&lt;/li&gt; 
 &lt;li&gt;There are no unnecessary map tasks, since the work done by a mapper can often be incorporated into the preceding reduce operator.&lt;/li&gt; 
 &lt;li&gt;Because all joins and data dependencies are explicitly declared, the scheduler can make locality optimizations.&lt;/li&gt; 
 &lt;li&gt;Intermediate state between operators can be kept in memory or written to local disk, which requires less I/O than writing it to HDFS.&lt;/li&gt; 
 &lt;li&gt;Operators can start executing as soon as their input is ready instead of waiting for the entire preceding stage to finish.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Fault tolerance&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;If a machine fails and the intermediate state on a machine is lost, the dataflow engine can recompute it from the preceding stages.&lt;/li&gt; 
 &lt;li&gt;If a computation is not deterministic, then the original data is not the same as the lost data, and downstream operators must reconcile the contradictions between the old and new data.&lt;/li&gt; 
 &lt;li&gt;The solution to such nondeterministic operators is to kill the downstream operators as well, and run them again on the new data.&lt;/li&gt; 
 &lt;li&gt;If the intermediate data is much smaller than the source data, or if the computation is very CPU-intensive, it&apos;s cheaper to materialize the intermediate data than to recompute it.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Discussion of materialization&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;While materialized datasets on HDFS are still usually the inputs and outputs of a job, the dataflow engine saves the job from writing all intermediate state to the filesystem.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;Graphs and Iterative Processing&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;Many graph algorithms traverse one edge at a time, joining one vertex with an adjacent one to propagate some information, and repeating until some condition is met like no more edges to follow, or some metric converging.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;The Pregel processing model&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;The &lt;em&gt;Pregel&lt;/em&gt; model, or &lt;em&gt;bulk synchronous processing model&lt;/em&gt; (BSP), is a popular optimization for batch processing graphs.&lt;/li&gt; 
 &lt;li&gt;One vertex can &quot;send a message&quot; to another vertex, usually along an edge in a graph – similar to how mappers can conceptually send messages to reducers by key.&lt;/li&gt; 
 &lt;li&gt;In each iteration, a function is called for each vertex, passing the function all the messages that were sent to that vertex – again like a reducer.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Fault tolerance&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;Pregel implementations guarantee that messages are processed exactly once at their destination vertex in the following iteration.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Parallel execution&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;Graph algorithms often have a lot of cross-machine communication overhead, as the intermediate state is often bigger than the original graph.&lt;/li&gt; 
 &lt;li&gt;If your graph can fit in memory on a single computer, it&apos;s likely that a single-machine or even single-threaded algorithm will outperform a distributed batch process.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;High Level APIs and Languages&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;Now that MapReduce is robust at scale, attention has turned to improving the programming model, improving efficiency, and broadening the set of problems that these technologies can solve.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;The move toward declarative query languages&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;The freedom to run arbitrary code is what has long distinguished batch processing systems of MapReduce heritage from MPP databases.&lt;/li&gt; 
 &lt;li&gt;By incorporating declarative aspects into high-level APIs, batch processing frameworks can use query optimizers to achieve comparable performance with MPP databases.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Specialization for different domains&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;As batch processing systems gain high-level declarative operators, and MPP databases become more programmable, the two are beginning to look more alike.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Summary&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;Distributed batch processing systems need to solve partitioning, where all related data (e.g. all records with the same key) are brought together in the same place, and fault tolerance.&lt;/li&gt; 
 &lt;li&gt;Callback functions like mappers and reducers are assumed to be stateless and without side-effects, allowing the framework to hide some of the hard distributed systems problems behind its abstraction.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Chapter 11: Stream Processing&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;A lot of data is unbounded because it changes gradually over time. Batch processors just artificially divide the data into chunks of fixed duration.&lt;/li&gt; 
 &lt;li&gt;The problem with daily batch processes is that changes in the input are only reflected in the output a day later, which is too slow for many impatient users.&lt;/li&gt; 
 &lt;li&gt;A &quot;stream&quot; refers to data that is incrementally made available over time.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Transmitting Event Streams&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;In a stream processing context, a record is commonly referred to as an &lt;em&gt;event&lt;/em&gt;.&lt;/li&gt; 
 &lt;li&gt;An event is generated once by a &lt;em&gt;producer&lt;/em&gt; or &lt;em&gt;publisher&lt;/em&gt;, and is processed by multiple &lt;em&gt;subscribers&lt;/em&gt; or &lt;em&gt;recipients&lt;/em&gt;. Related events are grouped together into a &lt;em&gt;topic&lt;/em&gt; or &lt;em&gt;stream&lt;/em&gt;.&lt;/li&gt; 
 &lt;li&gt;When moving toward continual processing with low delays, polling can become expensive; instead it&apos;s better for consumers to be notified when new events appear.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;Messaging Systems&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;Two questions are worth asking in a publish/subscribe model:&lt;/li&gt; 
 &lt;li&gt;What happens if producers send messages faster than consumers can process them? There are three options: dropping messages, buffering messages, and applying backpressure.&lt;/li&gt; 
 &lt;li&gt;What happens if nodes crash or temporarily go offline? If you can lose messages then you can probably get higher throughput and lower latency on the same hardware.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Direct messaging from producers to consumers&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;StatsD uses unreliable UDP messaging for collecting metrics from all machines on the network and monitoring them.&lt;/li&gt; 
 &lt;li&gt;Direct messaging systems generally require the application code to be aware of the possibility of message loss.&lt;/li&gt; 
 &lt;li&gt;If a consumer is offline, it may miss messages that were sent while it is unreachable.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Message brokers&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;A &lt;em&gt;message broker&lt;/em&gt; or &lt;em&gt;message queue&lt;/em&gt; is a database optimized for handling message streams.&lt;/li&gt; 
 &lt;li&gt;Centralizing data in the broker allows clients to come and go, and the question of durability is moved to the broker instead.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Message brokers compared to databases&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;Databases usually keep data until it is explicitly deleted, whereas most message brokers automatically delete a message when it has been successfully delivered to consumers.&lt;/li&gt; 
 &lt;li&gt;Since message brokers quickly delete messages, it&apos;s assumed that their queues are short.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Multiple consumers&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;Given multiple consumers reading messages in the same topic, two patterns of messaging are used:&lt;/li&gt; 
 &lt;li&gt;Load balancing: Each message is delivered to one of the consumers, and you can add consumers to parallelize the processing.&lt;/li&gt; 
 &lt;li&gt;Fan-out: Each message is delivered to &lt;em&gt;all&lt;/em&gt; of the consumers, allowing several independent consumers to consume the same topic of messages without affecting each other.&lt;/li&gt; 
 &lt;li&gt;The two patterns can be combined, e.g. two separate groups of consumers can subscribe to the same topic.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Acknowledgments and redelivery&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;Message brokers use &lt;em&gt;acknowledgments&lt;/em&gt; where a client must explicitly tell the broker when it has finished processing a message so that it can be removed from the queue.&lt;/li&gt; 
 &lt;li&gt;The combination of load balancing and redelivery inevitably leads messages to be reordered. To avoid the issue, you can disable load balancing by enforcing a separate queue per consumer.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;Partitioned Logs&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;Receiving a message is destructive if the acknowledgment causes it to be deleted from the broker, so you cannot run the same consumer again and get the same result.&lt;/li&gt; 
 &lt;li&gt;When adding a new consumer, it typically only starts receiving messages sent after the time it was registered, and so any prior messages cannot be recovered.&lt;/li&gt; 
 &lt;li&gt;A &lt;em&gt;log-based message broker&lt;/em&gt; combines the durable storage approach of databases with the low-latency notification facilities of messaging.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Using logs for message storage&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;A topic is a group of partitions that all carry messages of the same type.&lt;/li&gt; 
 &lt;li&gt;Within each partition, the broker assigns a monotonically increasing sequence number, or &lt;em&gt;offset&lt;/em&gt;, to every message. There is no total ordering of messages across partitions.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Logs compared to traditional messaging&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;To load balance across a group of consumers, the broker can assign entire partitions to each consumer in a consumer group, as opposed to assigning individual messages.&lt;/li&gt; 
 &lt;li&gt;Each consumer consumes &lt;em&gt;all&lt;/em&gt; the messages in the partitions it has been assigned. This has some downsides:&lt;/li&gt; 
 &lt;li&gt;The number of consumers in a group can be at most the number of log partitions in that topic.&lt;/li&gt; 
 &lt;li&gt;If a single message is slow to process, it holds up the processing of subsequent messages in that partition.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Consumer offsets&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;If a consumer node fails, another node in the consumer group is assigned the failed consumer&apos;s partitions, and it starts consuming messages at the last recorded offset.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Disk space usage&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;To reclaim disk space, the log is divided into segments, and periodically the oldest segments are deleted or moved to archive storage.&lt;/li&gt; 
 &lt;li&gt;The log therefore implements a bounded-size buffer, also known as a &lt;em&gt;circular buffer&lt;/em&gt; or &lt;em&gt;ring buffer&lt;/em&gt;, that discards old messages when it gets full.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;When consumers cannot keep up with producers&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;If a consumer falls so far behind that the messages it requires are older than what is retained on disk, then it cannot read those messages and they are effectively dropped.&lt;/li&gt; 
 &lt;li&gt;You can monitor how far a consumer is behind the head of the log, or its lag, and raise an alert if it falls behind significantly.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Databases and Streams&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;The fact that something was written to the database is itself an event that can be captured, stored, and processed.&lt;/li&gt; 
 &lt;li&gt;A replication log is a stream of database write events, produced by the leader as it processes transactions, and consumed by replicas.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;Keeping Streams in Sync&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;Often data is persisted somewhere and then needs to be replicated to several different places, such as a search index or cache.&lt;/li&gt; 
 &lt;li&gt;Dual writes, where the application explicitly writes to each of the systems, suffer from two problems:&lt;/li&gt; 
 &lt;li&gt;A &lt;em&gt;race condition&lt;/em&gt; where upon two clients dual writing a value, one client may write to the first system first and the second system second.&lt;/li&gt; 
 &lt;li&gt;One of the writes may fail while the other succeeds, thereby leaving the data in the two systems in an inconsistent state.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;Change Data Capture&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;em&gt;Change data capture&lt;/em&gt; (CDC) is the process of observing all data changes to a database and extracting them in a form in which they can be replicated to other systems.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Implementing change data capture&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;CDC ensures that all changes made to the system of record are also reflected in the derived data systems so that they too have an accurate copy of the data.&lt;/li&gt; 
 &lt;li&gt;A log-based message broker is well suited for transporting the change events from the source database to the derived systems, because it preserves the ordering of messages.&lt;/li&gt; 
 &lt;li&gt;Parsing the replication log of a database is a robust approach to CDC, but it comes with challenges such as handling schema changes.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Initial snapshot&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;If you do not have the entire log history, you must start with a consistent snapshot.&lt;/li&gt; 
 &lt;li&gt;The snapshot must correspond to a known position or offset in the change log, so that you know at which point to start applying changes after the snapshot has been processed.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Log compaction&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;A compaction or merging process running in the background looks for messages with the same key, and keeps only the most recent update for each key.&lt;/li&gt; 
 &lt;li&gt;The disk usage required by a compacted log depends only on the current contents of the database, and not the number of writes that have ever occurred in the database.&lt;/li&gt; 
 &lt;li&gt;To rebuild a derived data system, start a new consumer from offset 0 of the log-compacted topic, and sequentially scan over all messages in the log.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;Event Sourcing&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;em&gt;Event sourcing&lt;/em&gt; stores all changes to the application state as a log of change events, but applies the idea at a different level of abstraction:&lt;/li&gt; 
 &lt;li&gt;In CDC, the application uses the database in a mutable way, updating and deleting records. The application layer can be unaware that CDC is occurring.&lt;/li&gt; 
 &lt;li&gt;In event sourcing, the application logic is built on the basis of immutable events written to an event log. Events reflect things that happened at the application level, rather than low-level state changes.&lt;/li&gt; 
 &lt;li&gt;From an application point of view it is more meaningful to record the user&apos;s actions as immutable events rather than recording the effects of those actions on a mutable database.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Deriving current state from the event log&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;Applications using event sourcing must transform the log of events (representing data &lt;em&gt;written&lt;/em&gt; to the system) into application state that is suitable for display to the user.&lt;/li&gt; 
 &lt;li&gt;Log compaction is not possible with event sourcing, as later events do not override prior events, and so you need the full history of events to construct the final state.&lt;/li&gt; 
 &lt;li&gt;Applications using event sourcing can restore from a snapshot of the current state, but the intention is that the system can reprocess the full event log whenever required.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Commands and events&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;When a request from a user first arrives, it is initially a &lt;em&gt;command&lt;/em&gt;: At this point it may still fail, for example because some integrity constraint is violated.&lt;/li&gt; 
 &lt;li&gt;If the validation is successful and the command is accepted, it becomes an &lt;em&gt;event&lt;/em&gt;, which is durable and immutable. It becomes a &lt;em&gt;fact&lt;/em&gt;.&lt;/li&gt; 
 &lt;li&gt;A consumer of the event stream cannot reject an event, as it&apos;s already an immutable part of the log. So validation of the command must happen synchronously before it becomes an event.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;State, Streams, and Immutability&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;Mutable state and an append-only log are two sides of the same coin: The log of all changes, or the &lt;em&gt;changelog&lt;/em&gt;, represents the evolution of state over time.&lt;/li&gt; 
 &lt;li&gt;You might say that the application state is what you get when you integrate an event stream over time, and a change stream is what you get when you differentiate the state by time.&lt;/li&gt; 
 &lt;li&gt;You can consider the log as truth. The database is a cache of the subset of the log, namely the contents of the latest record values in the logs.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Advantages of immutable events&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;If you accidentally deploy buggy code that writes bad data to a database, recovery is much harder if the code is able to destructively overwrite data.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Deriving several views from the same event log&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;By separating mutable state from the immutable event log, you can derive several different read-oriented representations from the same log of events.&lt;/li&gt; 
 &lt;li&gt;You can use the event log to build a separate read-optimized view for some new feature, and run it alongside the existing system until transitioning over and decommissioning the old system.&lt;/li&gt; 
 &lt;li&gt;Storing data is normally quite straightforward if you don&apos;t have to worry about how it is going to be queried, as most schema complexity comes from supporting querying the data.&lt;/li&gt; 
 &lt;li&gt;Separating the form in which data is written from the form it is read is called &lt;em&gt;command query responsibility segregation&lt;/em&gt;, or CQRS.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Concurrency control&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;Because event sourcing and CDC is asynchronous, the user may write to a log, and then read from a log-derived view and find that their write has not yet been reflected in the read view.&lt;/li&gt; 
 &lt;li&gt;Because event sourcing requires only a single, atomic write&amp;nbsp;– namely appending an event to a log&amp;nbsp;– which is a simpler concurrency model than using multi-object transactions to update data in multiple places.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Limitations to immutability&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;Workloads with many updates and deletes on comparatively few entities may cause the immutable history to grow prohibitively large.&lt;/li&gt; 
 &lt;li&gt;Given a large history of changes, the performance of compaction and garbage collection becomes crucial for operational robustness.&lt;/li&gt; 
 &lt;li&gt;Immutability is also at odds with having to delete the data for administrative or legal reasons, such as GDPR.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Processing Streams&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;There are three options for processing a stream:&lt;/li&gt; 
 &lt;li&gt;You can take the data in the events and write it to a database, cache, search index, or similar storage system, from where it can then be queried by other clients.&lt;/li&gt; 
 &lt;li&gt;You can push the events to the users in some way, so that a human is the ultimate consumer of a stream.&lt;/li&gt; 
 &lt;li&gt;You can process one or more input streams to produce one or more output streams.&lt;/li&gt; 
 &lt;li&gt;A piece of code that processes one or more streams to produce other, derived streams is called an &lt;em&gt;operator&lt;/em&gt; or a &lt;em&gt;job&lt;/em&gt;.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;Uses of Stream Processing&lt;/h5&gt; 
&lt;h6&gt;Complex event processing&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;em&gt;Complex event processing&lt;/em&gt; (CEP) allows specifying rules to search for certain patterns of events in a stream, similar to a regular expression operating on a string.&lt;/li&gt; 
 &lt;li&gt;CEP systems often use a high-level declarative query language like SQL to describe patterns of events for detection.&lt;/li&gt; 
 &lt;li&gt;A processing engine maintains a state machine that performs the required matching on the input streams, and emits a &lt;em&gt;complex event&lt;/em&gt; with the details of a matching event pattern.&lt;/li&gt; 
 &lt;li&gt;CEP engines function in an manner opposite to normal databases: The queries are stored long-term, and the data that they operate on is transient.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Stream analytics&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;Analytics is less interested in finding specific event sequences, and is more oriented toward aggregations and statistical metrics over a large number of events.&lt;/li&gt; 
 &lt;li&gt;The time interval over which you aggregate is known as a &lt;em&gt;window&lt;/em&gt;.&lt;/li&gt; 
 &lt;li&gt;Probabilistic algorithms produce approximate results, but have the advantage of requiring significantly less memory in the stream processor than exact algorithms.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Search on streams&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;Running in a manner opposite to normal search engines, searching a stream requires storing the queries, and the documents they search over are transient.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;Reasoning About Time&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;Many stream processing frameworks use the local system clock on the processing machine (or &lt;em&gt;processing time&lt;/em&gt;) to determine windowing, but this breaks down if there is significant processing lag.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Event time versus processing time&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;Processing may be delayed from queueing, network faults, contention in the broker or processor, a restart of the stream consumer, or reprocessing of past events.&lt;/li&gt; 
 &lt;li&gt;Confusing event time and processing time leads to bad data.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Knowing when you&apos;re ready&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;You can never be sure when you&apos;ve received all of the events for a given window, or whether there are some events still to come.&lt;/li&gt; 
 &lt;li&gt;You have two options for handling &lt;em&gt;straggler&lt;/em&gt; events that arrive after the window has already been declared complete: Ignore them, or publish a corrective value with stragglers included.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Whose clock are you using, anyway?&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;Assigning timestamps to events is even more difficult when events can be buffered at several points in the system, such as on a mobile device that is offline and later reconnects.&lt;/li&gt; 
 &lt;li&gt;To estimate the offset between the server and device clocks, subtract the timestamp at which the event was sent to the server according to the device clock from the timestamp at which the event was received by the server according to the server clock.&lt;/li&gt; 
 &lt;li&gt;Applying this computed offset to the event timestamp allows you to estimate the true time at which the event occurred.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Types of windows&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;A &lt;em&gt;tumbling window&lt;/em&gt; has a fixed length, and every event belongs to exactly one window.&lt;/li&gt; 
 &lt;li&gt;A &lt;em&gt;hopping window&lt;/em&gt; has a fixed length, but windows may overlap to provide smoothing. You can implement this by computing 1-minute tumbling windows, and then aggregating over several adjacent windows.&lt;/li&gt; 
 &lt;li&gt;A &lt;em&gt;sliding window&lt;/em&gt; contains all events that occur within some interval of each other. You can implement this by buffering events sorted by time, and removing old events that have expired from the window.&lt;/li&gt; 
 &lt;li&gt;A &lt;em&gt;session window&lt;/em&gt; has no fixed duration, but instead groups together all events for the same user that occur closely together in time. The window ends when the user is inactive for some time.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;Stream Joins&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;The fact that new events can appear anytime on a stream makes joins on streams more challenging than in batch jobs.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Stream-stream join (window join)&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;The stream processor maintains state that is updated whenever an event occurs, which is referenced upon processing subsequent events.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Stream-table join (stream enrichment)&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;em&gt;Enriching&lt;/em&gt; a stream means augmenting its events with additional data queried from a database.&lt;/li&gt; 
 &lt;li&gt;If the stream processor has a local copy of the database (similar to map-side joins), then that database can be kept up to date using change data capture.&lt;/li&gt; 
 &lt;li&gt;Unlike a stream-stream join, a stream-table join uses a window that reaches back to the beginning of time (a conceptually infinite window) with newer versions of records overwriting old ones.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Table-table join (materialized view maintenance)&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;A table-table join is a stream process that maintains a materialized join between two tables.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Time-dependence of joins&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;All three joins above require the stream processor to maintain some state based on one join input, and to query that state on messages from the other input.&lt;/li&gt; 
 &lt;li&gt;The ordering of the events that maintain the state is important, and in a partitioned log, there is no ordering guarantee of events across different streams or partitions.&lt;/li&gt; 
 &lt;li&gt;Because state changes over time, and you join with some state, you must ask yourself what point in time you are using for the join.&lt;/li&gt; 
 &lt;li&gt;If the ordering of events across streams is undetermined, then the join is nondeterministic, and the events may be interleaved differently when you run the job again.&lt;/li&gt; 
 &lt;li&gt;This issue is known as a &lt;em&gt;slowly changing dimension&lt;/em&gt; (SCD) in data warehouses and is often addressed by using a unique identifier for a particular version of a joined record.&lt;/li&gt; 
 &lt;li&gt;A unique identifier makes the join deterministic, but log compaction is no longer possible because all versions of the records in the table must be retained.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;Fault Tolerance&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;The batch processing approach to fault tolerance exposes &lt;em&gt;exactly-once semantics&lt;/em&gt;, where it appears as though every record was processed exactly once.&lt;/li&gt; 
 &lt;li&gt;In stream processing, waiting until a task is finished before making its output visible is not an option, because a stream is infinite.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Microbatching and checkpointing&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;em&gt;Microbatching&lt;/em&gt; breaks the stream into small blocks and treats each block like a miniature batch process.&lt;/li&gt; 
 &lt;li&gt;With microbatching, small batches incur greater scheduling and coordination overhead, while larger batches mean a longer delay before results of the stream processor become available.&lt;/li&gt; 
 &lt;li&gt;An alternative is to periodically generate rolling checkpoints of state and write them to durable storage.&lt;/li&gt; 
 &lt;li&gt;Once the output leaves the stream processor, the framework cannot discard the output of a failed batch. Restarting a failed task causes its external side-effects to happen twice, regardless of checkpointing or microbatching.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Atomic commit revisited&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;To give the appearance of exactly-once processing in the presence of faults, all outputs and side-effects of processing an event must happen if and only if the processing is successful.&lt;/li&gt; 
 &lt;li&gt;More restricted environments, which do not attempt to persist data across heterogeneous environments, can implement an atomic commit facility efficiently.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Idempotence&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;An idempotent operation is one that you can perform multiple times, and it has the same effect as if you had performed it only once.&lt;/li&gt; 
 &lt;li&gt;Using idempotence relies on restarting a task to replay the same messages in the same order, the processing must be deterministic, and no other node may concurrently update the same value.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Rebuilding state after a failure&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;Any stream process that requires state (e.g. any windowed aggregations or tables for joins) must ensure that the state can be recovered after a failure.&lt;/li&gt; 
 &lt;li&gt;A performant solution is to keep the state local to the stream processor, and then to replicate it periodically.&lt;/li&gt; 
 &lt;li&gt;If the state is a local replica of a database, maintained by CDC, then the database can be rebuilt from the log-compacted change stream.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Summary&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;There are three types of joins that may appear in stream processes:&lt;/li&gt; 
 &lt;li&gt;&lt;em&gt;Stream-stream joins&lt;/em&gt;: Both input streams consist of activity events, and the join operator searches for related events that occur in some window of time.&lt;/li&gt; 
 &lt;li&gt;&lt;em&gt;Stream-table joins&lt;/em&gt;: One input stream consists of activity events, while the other is a database changelog that keeps a local copy of a database up to date. This emits enriched activity events.&lt;/li&gt; 
 &lt;li&gt;&lt;em&gt;Table-table joins&lt;/em&gt;: Both input streams are database changelogs. The result is a stream of changes to the materialized view of the join between the two tables.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Chapter 12: The Future of Data Systems&lt;/h3&gt; 
&lt;h4&gt;Data Integration&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;There is unlikely one piece of software that is suitable for all circumstances in which data is used, and so we must cobble together several pieces of software to provide the application&apos;s functionality.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;Combining Specialized Tools by Deriving Data&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;As the number of different representations of the data increases, the integration problem becomes harder.&lt;/li&gt; 
 &lt;li&gt;The need for data integration often only becomes apparent when you zoom out and consider the dataflows across an entire organization.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Reasoning about dataflows&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;You must have clarity on the inputs and outputs, namely where data is written first, and which representations are derived from which sources.&lt;/li&gt; 
 &lt;li&gt;By funneling all user input through a single system that decides on an ordering for all writes, it&apos;s easier to derive other representations of the data by processing the writes in the same order.&lt;/li&gt; 
 &lt;li&gt;Whether to use change data capture or an event sourcing log is less important than simply the principle of deciding on a total order.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Derived data versus distributed transactions&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;Distributed transactions decide on an ordering of writes by using locks for mutual exclusion, while CDC and event sourcing use a log for ordering.&lt;/li&gt; 
 &lt;li&gt;Distributed transactions use atomic commit to ensure that changes take effect only once, while log-based systems are often based on deterministic retry and idempotence.&lt;/li&gt; 
 &lt;li&gt;Transactions systems usually provide linearizability and reading your own writes, while derived data systems are asynchronous and do not offer such guarantees.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;The limits of total ordering&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;As systems scale, limitations of total ordering begin to emerge:&lt;/li&gt; 
 &lt;li&gt;To scale you may need to partition the log across multiple machines, but the order of events across two different partitions is ambiguous.&lt;/li&gt; 
 &lt;li&gt;If servers are are spread across multiple geographically distributed datacenters, there is an undefined ordering of events between events in two different datacenters.&lt;/li&gt; 
 &lt;li&gt;When two events originate in different micro-services, then there is no defined order for those events.&lt;/li&gt; 
 &lt;li&gt;Deciding on a total order of events is known as a &lt;em&gt;total order broadcast&lt;/em&gt;, which is equivalent to consensus. It&apos;s an open research problem to design consensus algorithms that work well beyond a single node in a geographically distributed setting.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Ordering events to capture causality&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;Where there is no causal link between events, the lack of a total order is not a big problem since concurrent events can be ordered arbitrarily.&lt;/li&gt; 
 &lt;li&gt;Logical timestamps can provide total ordering without coordination, so they may help in cases where total order broadcast is not feasible.&lt;/li&gt; 
 &lt;li&gt;If you can log an event to record the state of the system the user saw before making a decision, and give that event a unique identifier, then any later events can refer to that event identifier to record the causal dependency.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;Batch and Stream Processing&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;The goal of data integration is to ensure that data ends up in the right form in all the right places.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Maintaining derived state&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;No matter what the derived data is, it&apos;s helpful to think in terms of data pipelines that derive one thing from another, pushing state changes in one system through functional application code and applying the effects to derived systems.&lt;/li&gt; 
 &lt;li&gt;Asynchrony is what makes systems based on event logs robust, as a fault in one part of the system is contained locally.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Reprocessing data for application evolution&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;With reprocessing it is possible to re-structure a dataset into a completely different model in order to better serve new requirements.&lt;/li&gt; 
 &lt;li&gt;Derived views allow &lt;em&gt;gradual&lt;/em&gt; evolution. A gradual migration has little risk as you always have a working system to go back to.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;The lambda architecture&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;The lambda architecture records incoming data by appending immutable events to an always-growing dataset, from which read-optimized views are derived.&lt;/li&gt; 
 &lt;li&gt;A stream processor consumes the events and quickly produces an approximate update to a view. A batch processor later consumes the &lt;em&gt;same&lt;/em&gt; set of events and produces a corrected version of the derived view.&lt;/li&gt; 
 &lt;li&gt;The stream processor can use fast approximate algorithms while the batch process uses slower exact algorithms.&lt;/li&gt; 
 &lt;li&gt;The lambda architecture has several practical problems:&lt;/li&gt; 
 &lt;li&gt;The same logic must be implemented in both a batch and in a stream processing framework.&lt;/li&gt; 
 &lt;li&gt;The batch pipeline and the stream pipeline outputs must be merged in order to respond to user requests.&lt;/li&gt; 
 &lt;li&gt;Batch processing on large datasets is expensive, and so the batch pipeline often needs to process incremental batches rather than reprocessing everything, which adds complexity.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Unbundling Databases&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;Relational databases want to give programmers a high-level abstraction that hide the complexities of data structures on disk, concurrency, crash recovery, and so on.&lt;/li&gt; 
 &lt;li&gt;The NoSQL movement wants to apply a Unix-esque approach of low-level abstractions to the domain of distributed OLTP data storage.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;Composing Data Storage Technologies&lt;/h5&gt; 
&lt;h6&gt;The meta-database of everything&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;The dataflow across an entire organization looks like one huge database: Each batch, stream, or ETL process acts like a database subsystem that keeps indexes or materialized views up to date.&lt;/li&gt; 
 &lt;li&gt;There are two avenues by which different storage and processing tools can be composed into a cohesive system:&lt;/li&gt; 
 &lt;li&gt;Federated databases (unifying reads): A &lt;em&gt;federated database&lt;/em&gt; or &lt;em&gt;polystore&lt;/em&gt; provides a unified query interface to a wide variety of storage engines and processing methods.&lt;/li&gt; 
 &lt;li&gt;Unbundled databases (unifying writes): Data capture and event logs allow &lt;em&gt;unbundling&lt;/em&gt; a database&apos;s index-maintenance features in a way that can synchronize writes across disparate technologies.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Making unbundling work&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;Asynchronous event logs with idempotent retries is a more robust and practical approach than distributed transactions across heterogeneous storage systems.&lt;/li&gt; 
 &lt;li&gt;Log-based integration is &lt;em&gt;loose coupling&lt;/em&gt; between storage components:&lt;/li&gt; 
 &lt;li&gt;Asynchronous event streams make the system as a whole more robust to outages or performance degradation of individual components.&lt;/li&gt; 
 &lt;li&gt;Unbundling data systems allows different software components and services to be developed, improved, and maintained independently from each other by different teams.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Unbundling versus integrated systems&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;Unbundling allows you to combine several different databases in order to achieve good performance for a much wider range of workflows than is possible with a single piece of software.&lt;/li&gt; 
 &lt;li&gt;The advantages of unbundling and composition only come into the picture when there is no single piece of software that satisfies all your requirements.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;Designing Applications Around Dataflow&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;The approach of unbundling databases by composing specialized storage and processing systems with application code is becoming known as the &quot;database inside-out&quot; approach.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Application code as a derivation function&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;A dataset derived from another must go through some transformation function. Examples include a secondary index, a full-text search index, a machine learning model (derived from the training data), or a cache (aggregating data in a form for rendering in the UI).&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Separation of application code and state&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;In the typical web application model, the database acts as a kind of mutable shared variable that can be accessed synchronously over the network.&lt;/li&gt; 
 &lt;li&gt;Subscribing to changes in a database is only now emerging as a feature; historically databases have inherited a passive approach to mutable data that requires polling for changes.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Dataflow: Interplay between state changes and application code&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;Instead of thinking of a database as a passive variable that is updated only by the application, we must think of application code responding to state changes in one place by updating state in another place.&lt;/li&gt; 
 &lt;li&gt;Unbundling the database applies this idea to derived datasets from the primary database, including caches, full-text search indexes, machine learning, or analytics systems.&lt;/li&gt; 
 &lt;li&gt;This requires stable message ordering and fault-tolerant message processing, but those are less stringent demands than those imposed by distributed transactions.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Stream processors and services&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;The advantage of a service-oriented architecture over a single monolithic application is primarily organizational scalability through loose coupling.&lt;/li&gt; 
 &lt;li&gt;Instead of one service querying another service for data, it can subscribe to to state changes from the other service and query a local database for improved speed and reliability.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;Observed Derived State&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;The write path between a primary database and its derived dataset and the read path between that derived dataset and the point it is consumed represents the whole journey of the data.&lt;/li&gt; 
 &lt;li&gt;Framing the journey in terms of functional programming languages, the write path is similar to eager evaluation, while the read path is similar to lazy evaluation.&lt;/li&gt; 
 &lt;li&gt;The derived dataset is where the write path and read path meet, and represents a tradeoff between the amount of work that must be done at write time and the amount that must be done at read time.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Materialized views and caching&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;Caches, indexes, and materialized views allow us to do more work on the write path and less work on the read path, thereby shifting the boundary between the write path and read path.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Stateful, offline-capable clients&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;When we move from stateless clients to a model where end-user devices maintain state, we can think of the on-device state as a &lt;em&gt;cache of state on the server&lt;/em&gt;.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Pushing state changes to clients&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;Actively pushing state changes all the way to client devices means extending the write path all the way to the end user.&lt;/li&gt; 
 &lt;li&gt;When a client is first initialized, it would still need to use a read path to get its initial state, but thereafter it could rely on a stream of state changes sent by the server.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;End-to-end event streams&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;Extending the write path all the way to the end user requires moving away from request/response interaction and toward a publish/subscribe dataflow.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Reads are events too&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;We can treat reads as events, and send them to the same stream processor as writes; the processor can respond to a read event by emitting the result of the read on the output stream.&lt;/li&gt; 
 &lt;li&gt;This performs a stream-table join between the stream of read queries and the database.&lt;/li&gt; 
 &lt;li&gt;Recording a log of read events has benefits with regard to tracking causal dependencies and data provenances, as you can reconstruct what a user saw before making some decision.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Multi-partition data processing&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;Representing queries as events and collecting responses from streams enables executing queries across several partitions, leveraging the infrastructure for message routing, partitioning, and joining already provided by stream processors.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Aiming for Correctness&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;We want to build applications that are reliable and &lt;em&gt;correct&lt;/em&gt;, i.e. programs whose semantics are well defined and understood, even in the presence of faults.&lt;/li&gt; 
 &lt;li&gt;Serializability and atomic commits provide strong assurances of correctness, but typically only work in a single datacenter, and they limit the scale of fault-tolerance properties you can achieve.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;The End-to-End Argument for Databases&lt;/h5&gt; 
&lt;h6&gt;Exactly-once execution of an operation&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;em&gt;Exactly-once&lt;/em&gt; means arranging the computation such that the final effect is the same as if no faults had occurred, even if the operation was retried due to some fault.&lt;/li&gt; 
 &lt;li&gt;One of the most effective approaches is to make the operation &lt;em&gt;idempotent&lt;/em&gt;.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Duplicate suppression&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;Even if you suppress duplicate transactions between the database client and server, you must still worry about the network between the end-user device and the application server.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Uniquely identifying requests&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;Relational databases can generally maintain a uniqueness constraint correctly (such as on an idempotence token), even at weak isolation levels.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;The end-to-end argument&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;The &lt;em&gt;end-to-end argument&lt;/em&gt; says some problems can be completely and correctly implemented only with the help of the endpoints of the communication system; providing a solution as a feature of the communication system is not possible.&lt;/li&gt; 
 &lt;li&gt;In such circumstances, low-level reliability features are not by themselves sufficient to ensure end-to-end correctness.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Applying end-to-end thinking in data systems&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;Reasoning about concurrency and partial failure is difficult and counterintuitive, and so most application-level mechanisms likely do not work correctly, thereby resulting in lost or corrupted data.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;Enforcing Constraints&lt;/h5&gt; 
&lt;h6&gt;Uniqueness constraints require consensus&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;Enforcing a uniqueness constraint requires consensus, as the system must decide which one of the conflicting operations is accepted, and reject the others as violating the constraint.&lt;/li&gt; 
 &lt;li&gt;Uniqueness constraints can be scaled out by partitioning based on the value that needs to be unique.&lt;/li&gt; 
 &lt;li&gt;Asynchronous multi-master replication cannot be used in this case, as two different masters could concurrently accept conflicting writes.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Uniqueness in log-based messaging&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;If a log is partitioned based on the value that needs to be unique, then a stream processor can unambiguously and deterministically decide which of several conflicting operations comes first in the log.&lt;/li&gt; 
 &lt;li&gt;To scale the number of handled requests, simply increase the number of partitions.&lt;/li&gt; 
 &lt;li&gt;Because all writes that may conflict are routed to the same partition and processed sequentially, this works for many constraints other than uniqueness constraints.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Multi-partition request processing&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;Single-object writes are atomic in almost all data systems, and so a request appended to a log either appears in the log or it doesn&apos;t.&lt;/li&gt; 
 &lt;li&gt;By breaking down a multi-partition transaction into partitioned stages using the same end-to-end request ID, you can achieve correctness even in the presence of faults without using an atomic commit protocol.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;Timeliness and Integrity&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;The term &lt;em&gt;consistency&lt;/em&gt; conflates two requirements that are worth considering separately:&lt;/li&gt; 
 &lt;li&gt;&lt;em&gt;Timeliness&lt;/em&gt; means ensuring the data is in an up-to-date state. Read data may be stale but that inconsistency is only temporary.&lt;/li&gt; 
 &lt;li&gt;&lt;em&gt;Integrity&lt;/em&gt; means absence of corruption, and no contradictory or false data. If integrity is violated, then the inconsistency is permanent.&lt;/li&gt; 
 &lt;li&gt;Violations of timeliness are &quot;eventual consistency&quot; whereas violations of integrity are &quot;permanent inconsistency.&quot;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Correctness of dataflow systems&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;ACID transactions usually provide both timeliness (e.g. linearizability) and integrity (e.g. atomic commit) guarantees.&lt;/li&gt; 
 &lt;li&gt;Event-based dataflow systems decouple timeliness and integrity: You forfeit timeliness because of asynchrony, but &lt;em&gt;exactly-once&lt;/em&gt; or &lt;em&gt;effectively-once&lt;/em&gt; semantics preserve integrity.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Loosely interpreted constraints&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;If an application can get away with weaker notions of uniqueness, then persisting a &lt;em&gt;compensating transaction&lt;/em&gt; may undo a constraint violation.&lt;/li&gt; 
 &lt;li&gt;In many business contexts, it may be acceptable to temporarily violate a constraint and fix it up later by apologizing. The cost of the apology is a business decision.&lt;/li&gt; 
 &lt;li&gt;Such applications that tolerate optimistic writes and checking the constraint afterward do require integrity, but don&apos;t require timeliness on the enforcement of the constraint.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Coordinating-avoiding data systems&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;Systems that synchronize cross-partition coordination or have strict constraints reduce the number of apologies you must make due to inconsistencies, but potentially also reduce your performance and availability.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;Trust, but Verify&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;The &lt;em&gt;system model&lt;/em&gt; is the set of assumptions that certain things might go wrong, but other things won&apos;t.&lt;/li&gt; 
 &lt;li&gt;Faults are really modeled by probabilities. The question is whether violations of our assumptions happen often enough that we may encounter them in practice.&lt;/li&gt; 
 &lt;li&gt;If you have enough devices running your software, then even very unlikely things do happen.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Maintaining integrity in the face of software bugs&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;If the application uses the database incorrectly in some way, for example using a weak isolation level unsafely, then the integrity of the database cannot be guaranteed.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Don&apos;t blindly trust what they promise&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;Checking the integrity of data is known as &lt;em&gt;auditing&lt;/em&gt;.&lt;/li&gt; 
 &lt;li&gt;HDFS and Amazon S3 run background checks that continually read back files, compare them to other replicas, and move files between disks, in order to mitigate the risk of silent corruption.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Designing for auditability&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;Mutations to database tables do not detail &lt;em&gt;why&lt;/em&gt; those mutations were performed. The invocation of the application logic that decided on those mutations is transient and cannot be reproduced.&lt;/li&gt; 
 &lt;li&gt;Being explicit about dataflow makes the &lt;em&gt;provenance&lt;/em&gt; of data much clearer, which makes integrity checking much more feasible.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;The end-to-end argument again&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;Checking the integrity of data systems is best done in an end-to-end fashion: The more systems we can include in an integrity check, the fewer opportunities there are for corruption to go unnoticed at some stage of the process.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Tools for auditable data systems&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;Blockchains and distributed ledgers are essentially distributed databases run by mutually untrusting organizations. These replicas check each other&apos;s work and use a consensus protocol to agree on the transactions that should be executed.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Doing the Right Thing&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;Data may be an abstract thing, but many datasets are about people: their behavior, their interests, their identity. We must treat such data with humanity and respect.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;Predictive Analytics&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;The criminal justice system may presume innocence until proven guilty, but automated systems can systematically and arbitrarily exclude a person from participating in society without any proof of guilt, and with little chance of appeal.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Bits and discrimination&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;Predictive analytics systems do not merely automate a human&apos;s decision by using software to specify the rules for when to say yes or no; instead we leave the rules themselves to be inferred from the data.&lt;/li&gt; 
 &lt;li&gt;If there is systematic bias in the input to an algorithm, the system will most likely learn and amplify that bias in its output.&lt;/li&gt; 
 &lt;li&gt;Predictive analytics systems merely extrapolate from the past; if the past is discriminatory, then they codify that discrimination.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Responsibility and accountability&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;As data-driven decision making becomes more widespread, we must discover how to make algorithms accountable and transparent, how to avoid reinforcing existing biases, and how to fix them when they inevitably make mistakes.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Feedback loops&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;Consequences such as feedback loops can be predicted by thinking about the entire system, including the people interacting with it – an approach known as &lt;em&gt;systems thinking&lt;/em&gt;.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;Privacy and Tracking&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;When a system only stores data that has been explicitly entered, then the system is performing a service for the user: The user is the customer.&lt;/li&gt; 
 &lt;li&gt;Tracking the user serves not the individual but the needs of advertisers who are funding the service. This relationship is appropriately described as &lt;em&gt;surveillance&lt;/em&gt;.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Surveillance&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;In our attempts to make software &quot;eat the world&quot; we have built the greatest mass surveillance infrastructure that the world has ever seen.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Consent and freedom of choice&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;Most privacy policies do more to obscure than to illuminate. But without understanding what happens to their data, users cannot give any meaningful consent.&lt;/li&gt; 
 &lt;li&gt;Data is extracted from users through a one-way process, not a relationship with true reciprocity, and not a fair value exchange.&lt;/li&gt; 
 &lt;li&gt;For the user who does not consent to surveillance, the only real alternative is simply to not use the service, which may have real social cost.&lt;/li&gt; 
 &lt;li&gt;For people in a less privileged position, there is no meaningful freedom of choice: surveillance becomes inescapable.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Privacy and use of data&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;Privacy does not mean keeping everything secret, but having the freedom to choose which things to reveal to whom, what to make public, and what to keep secret.&lt;/li&gt; 
 &lt;li&gt;When data is extracted from people through surveillance infrastructure, privacy rights are usually not eroded but rather transferred to the data collector.&lt;/li&gt; 
 &lt;li&gt;Even if particular users cannot be personally identified from the group targeted by a particular ad, they have lost their agency about the disclosure of some intimate information.&lt;/li&gt; 
 &lt;li&gt;Whether something is &quot;undesirable&quot; or &quot;inappropriate&quot; is down to human judgment; algorithms are oblivious to such notions unless we explicitly program them to respect human needs.&lt;/li&gt; 
 &lt;li&gt;Surveillance has always existed, but it used to be expensive and manual. Trust relationships have always existed, but the are mostly governed by ethical, legal, and regulatory constraints.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Data as assets and power&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;Behavioral data is sometimes called &quot;data exhaust&quot; because it is a byproduct of users interacting with a service.&lt;/li&gt; 
 &lt;li&gt;From an economic point of view, if targeted advertising is what pays for a service, then behavioral data about people is the service&apos;s core asset.&lt;/li&gt; 
 &lt;li&gt;Because data can be abused so easily, critics have said that data is not just an asset, but a &quot;toxic asset&quot; or at least a &quot;hazardous material.&quot;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h6&gt;Remembering the Industrial Revolution&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;Just as the Industrial Revolution had a dark side that needed to be managed, our transition to the information age has major problems that we must confront and solve.&lt;/li&gt; 
 &lt;li&gt;As Bruce Schneier said, data is the pollution problem of the information age, and protecting privacy is the environmental challenge.&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Dynamic instrumentation tools</title>
      <link>https://tedneward.github.io/Research/reading/development/dynamic-instrumentation/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">reading/development/dynamic-instrumentation/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;http://www.dyninst.org/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/dyninst/dyninst&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://github.com/rimsa/dumpcfgs&quot;&gt;dumpcfgs&lt;/a&gt;: Dump (extract) CFGs statically from binary programs using DynInst API&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://arxiv.org/abs/2001.10621&quot;&gt;Parallelizing Binary Code Analysis&lt;/a&gt;: by Xiaozhu Meng, Jonathon M. Anderson, John Mellor-Crummey, Mark W. Krentel, Barton P. Miller, Srđan Milaković, 2020 arXiv&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Foreign Function Interface (FFI)</title>
      <link>https://tedneward.github.io/Research/reading/development/ffi/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">reading/development/ffi/index.html</guid>
      	<description>
	&lt;p&gt;The concept of an FFI is fairly straightforward: How does a language/platform &quot;bind&quot; (in other words, be able to call) to underlying APIs of the host environment or other libraries/languages/platforms? Examples include Java code, running on top of the JVM, being able to &quot;call out to&quot; native C code, such as operating system APIs or native libraries; game engines being able to call out to libraries that aren&apos;t a part of the game engine itself; and so on.&lt;/p&gt; 
&lt;p&gt;Most of the time this requires several pieces of knowledge:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;How to dynamically load a library at runtime on the host environment (operating system)&lt;/li&gt; 
 &lt;li&gt;How to understand the &quot;signature&quot; and calling convention of the host/OS library or API&lt;/li&gt; 
 &lt;li&gt;How to &quot;marshal&quot; parameters and return values from one environment to the other, which requires knowing information about both the caller and the target&apos;s choice of binary representation of values&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Dynamically loading libraries&lt;/h2&gt; 
&lt;p&gt;Most FFIs (particularly those of VM-based languages) use dynamic loading of libraries, so as to reduce the need to statically-link new executables each time a new FFI invocation is needed/desired.&lt;/p&gt; 
&lt;p&gt;Lots of this material is covered in &lt;a href=&quot;../linking-loading&quot;&gt;linking and loading&lt;/a&gt; reading. Typically the two-step process is to:&lt;/p&gt; 
&lt;ol&gt; 
 &lt;li&gt;Load the library. Asking the OS to bring the library up into the process&apos; space and make it available.&lt;/li&gt; 
 &lt;li&gt;Request the address of a given exported symbol by name. In other words, look up the function by its name, returning either the address (which we can then coerce somehow into a callable reference--function pointer, if you will) or NULL if no such name is found.&lt;/li&gt; 
&lt;/ol&gt; 
&lt;h2&gt;Call signatures&lt;/h2&gt; 
&lt;p&gt;How do we name the exported entry point? Does the entry point have any metadata describing the parameters and/or return type?&lt;/p&gt; 
&lt;h4&gt;&lt;a href=&quot;/languages/c&quot;&gt;C&lt;/a&gt;&lt;/h4&gt; 
&lt;p&gt;C generally mapped the name of a function directly to the exported ABI name, usually with a prefixed &lt;code&gt;_&lt;/code&gt;. (Not sure of the reason for that prefix, to be honest.) &quot;an identifier beginning with an underscore followed by a capital letter is a &lt;a href=&quot;https://en.wikipedia.org/wiki/Reserved_word&quot;&gt;reserved identifier&lt;/a&gt; in C, so conflict with user identifiers is avoided&quot;&lt;/p&gt; 
&lt;table&gt; 
 &lt;thead&gt; 
  &lt;tr&gt;
   &lt;th&gt;Element &lt;/th&gt;
   &lt;th&gt; Implementation&lt;/th&gt;
  &lt;/tr&gt; 
 &lt;/thead&gt; 
 &lt;tbody&gt; 
  &lt;tr&gt;
   &lt;td&gt;Argument-passing order &lt;/td&gt;
   &lt;td&gt; Right to left.&lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt;Stack-maintenance responsibility &lt;/td&gt;
   &lt;td&gt; Calling function pops the arguments from the stack.&lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt;Name-decoration convention &lt;/td&gt;
   &lt;td&gt; Underscore character (_) is prefixed to names, except when __cdecl functions that use C linkage are exported.&lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt;Case-translation convention &lt;/td&gt;
   &lt;td&gt; No case translation performed.&lt;/td&gt;
  &lt;/tr&gt; 
 &lt;/tbody&gt; 
&lt;/table&gt; 
&lt;h4&gt;&lt;a href=&quot;/languages/cplusplus&quot;&gt;C++&lt;/a&gt;&lt;/h4&gt; 
&lt;p&gt;... was where things got &lt;em&gt;really&lt;/em&gt; interesting. (&lt;em&gt;Inside the C++ Object Model&lt;/em&gt; had/has a lot of details on this.) In order to support function overloading (same name, different parameters), C++ generated C-style function names with the parameters encoded as part of the name; example:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;int  f () { return 1; }
int  f (int)  { return 0; }
void g () { int i = f(), j = f(0); }
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;... could produce ...&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;int  __f_v () { return 1; }
int  __f_i (int)  { return 0; } 
void __g_v () { int i = __f_v(), j = __f_i(0); }
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;and it got even more interesting for classes:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;namespace wikipedia 
{
   class article 
   {
   public:
      std::string format ();  // = _ZN9wikipedia7article6formatEv

      bool print_to (std::ostream&amp;amp;);  // = _ZN9wikipedia7article8print_toERSo

      class wikilink 
      {
      public:
         wikilink (std::string const&amp;amp; name);  // = _ZN9wikipedia7article8wikilinkC1ERKSs
      };
   };
}
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;... depending on the precise name-mangling convention for that C++ compiler:&lt;/p&gt; 
&lt;p&gt;Compiler | &lt;code&gt;void h(int)&lt;/code&gt; | &lt;code&gt;void h(int, char)&lt;/code&gt; | &lt;code&gt;void h(void)&lt;/code&gt;&lt;br&gt; -------- + ----------- + ----------------- + ------------&lt;br&gt; Intel C++ 8.0 for Linux, HP aC++ A.05.55 IA-64, IAR EWARM C++, GCC 3.x and higher, Clang 1.x and higher | &lt;code&gt;_Z1hi&lt;/code&gt; | &lt;code&gt;_Z1hic&lt;/code&gt; | &lt;code&gt;_Z1hv&lt;/code&gt;&lt;br&gt; GCC 2.9.x, HP aC++ A.03.45 PA-RISC | &lt;code&gt;h__Fi&lt;/code&gt; | &lt;code&gt;h__Fic&lt;/code&gt; | &lt;code&gt;h__Fv&lt;/code&gt;&lt;br&gt; Microsoft Visual C++ v6-v10 (&lt;a href=&quot;https://en.wikiversity.org/wiki/Visual_C%2B%2B_name_mangling&quot;&gt;mangling details&lt;/a&gt;), Digital Mars C++ | &lt;code&gt;?h@@YAXH@Z&lt;/code&gt; | &lt;code&gt;?h@@YAXHD@Z&lt;/code&gt; | &lt;code&gt;?h@@YAXXZ&lt;/code&gt;&lt;br&gt; Borland C++ v3.1 | &lt;code&gt;@h$qi&lt;/code&gt; | &lt;code&gt;@h$qizc&lt;/code&gt; | &lt;code&gt;@h$qv&lt;/code&gt;&lt;br&gt; OpenVMS C++ v6.5 (ARM mode) | &lt;code&gt;H__XI&lt;/code&gt; | &lt;code&gt;H__XIC&lt;/code&gt; | &lt;code&gt;H__XV&lt;/code&gt;&lt;br&gt; OpenVMS C++ v6.5 (ANSI mode) | | &lt;code&gt;CXX$__7H__FIC26CDH77&lt;/code&gt; | &lt;code&gt;CXX$__7H__FV2CB06E8&lt;/code&gt;&lt;br&gt; OpenVMS C++ X7.1 IA-64 | &lt;code&gt;CXX$_Z1HI2DSQ26A&lt;/code&gt; | &lt;code&gt;CXX$_Z1HIC2NP3LI4&lt;/code&gt; | &lt;code&gt;CXX$_Z1HV0BCA19V&lt;/code&gt;&lt;br&gt; SunPro CC | &lt;code&gt;__1cBh6Fi_v_&lt;/code&gt; | &lt;code&gt;__1cBh6Fic_v_&lt;/code&gt; | &lt;code&gt;__1cBh6F_v_&lt;/code&gt;&lt;br&gt; Tru64 C++ v6.5 (ARM mode) | &lt;code&gt;h__Xi&lt;/code&gt; | &lt;code&gt;h__Xic&lt;/code&gt; | &lt;code&gt;h__Xv&lt;/code&gt;&lt;br&gt; Tru64 C++ v6.5 (ANSI mode) | &lt;code&gt;__7h__Fi&lt;/code&gt; | &lt;code&gt;__7h__Fic&lt;/code&gt; | &lt;code&gt;__7h__Fv&lt;/code&gt;&lt;br&gt; Watcom C++ 10.6 | &lt;code&gt;W?h$n(i)v&lt;/code&gt; | &lt;code&gt;W?h$n(ia)v&lt;/code&gt; | &lt;code&gt;W?h$n()v&lt;/code&gt;&lt;/p&gt; 
&lt;h4&gt;&lt;a href=&quot;/content/platforms/windows/index.md&quot;&gt;Windows&lt;/a&gt;&lt;/h4&gt; 
&lt;p&gt;Windows developed a number of different calling conventions.&lt;/p&gt; 
&lt;h5&gt;&lt;a href=&quot;&quot;&gt;&lt;code&gt;__cdecl&lt;/code&gt;&lt;/a&gt;&lt;/h5&gt; 
&lt;p&gt;The C calling convention, above. Generally used solely for C-compiled libraries that weren&apos;t a core part of the Windows OS (a la the C standard library).&lt;/p&gt; 
&lt;h5&gt;&lt;a href=&quot;https://learn.microsoft.com/en-us/cpp/cpp/thiscall&quot;&gt;&lt;code&gt;__thiscall&lt;/code&gt;&lt;/a&gt;&lt;/h5&gt; 
&lt;p&gt;The (Microsoft-specific) &lt;code&gt;__thiscall&lt;/code&gt; calling convention is used on C++ class member functions on the x86 architecture. It&apos;s the default calling convention used by member functions that don&apos;t use variable arguments (vararg functions).&lt;/p&gt; 
&lt;p&gt;Under &lt;code&gt;__thiscall&lt;/code&gt;, the callee cleans the stack, which is impossible for vararg functions. Arguments are pushed on the stack from right to left. The this pointer is passed via register ECX, and not on the stack.&lt;/p&gt; 
&lt;p&gt;On ARM, ARM64, and x64 machines, &lt;code&gt;__thiscall&lt;/code&gt; is accepted and ignored by the compiler. That&apos;s because they use a register-based calling convention by default.&lt;/p&gt; 
&lt;p&gt;One reason to use &lt;code&gt;__thiscall&lt;/code&gt; is in classes whose member functions use __clrcall by default. In that case, you can use &lt;code&gt;__thiscall&lt;/code&gt; to make individual member functions callable from native code.&lt;/p&gt; 
&lt;p&gt;When compiling with /clr:pure, all functions and function pointers are __clrcall unless specified otherwise. The /clr:pure and /clr:safe compiler options are deprecated in Visual Studio 2015 and unsupported in Visual Studio 2017.&lt;/p&gt; 
&lt;p&gt;vararg member functions use the __cdecl calling convention. All function arguments are pushed on the stack, with the this pointer placed on the stack last.&lt;/p&gt; 
&lt;p&gt;Because this calling convention applies only to C++, it doesn&apos;t have a C name decoration scheme.&lt;/p&gt; 
&lt;p&gt;When you define a non-static class member function out-of-line, specify the calling convention modifier only in the declaration. You don&apos;t have to specify it again on the out-of-line definition. The compiler uses the calling convention specified during declaration at the point of definition.&lt;/p&gt; 
&lt;h5&gt;&lt;a href=&quot;https://learn.microsoft.com/en-us/cpp/cpp/stdcall&quot;&gt;&lt;code&gt;__stdcall&lt;/code&gt;&lt;/a&gt;&lt;/h5&gt; 
&lt;p&gt;This is the original Win32 API calling convention. The callee cleans the stack, so the compiler makes vararg functions __cdecl.&lt;/p&gt; 
&lt;table&gt; 
 &lt;thead&gt; 
  &lt;tr&gt;
   &lt;th&gt;Element &lt;/th&gt;
   &lt;th&gt; Implementation&lt;/th&gt;
  &lt;/tr&gt; 
 &lt;/thead&gt; 
 &lt;tbody&gt; 
  &lt;tr&gt;
   &lt;td&gt;Argument-passing order &lt;/td&gt;
   &lt;td&gt; Right to left.&lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt;Argument-passing convention &lt;/td&gt;
   &lt;td&gt; By value, unless a pointer or reference type is passed.&lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt;Stack-maintenance responsibility &lt;/td&gt;
   &lt;td&gt; Called function pops its own arguments from the stack.&lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt;Name-decoration convention &lt;/td&gt;
   &lt;td&gt; An underscore (_) is prefixed to the name. The name is followed by the at sign (@) followed by the number of bytes (in decimal) in the argument list. Therefore, the function declared as int func( int a, double b ) is decorated as follows: _func@12&lt;/td&gt;
  &lt;/tr&gt; 
 &lt;/tbody&gt; 
&lt;/table&gt; 
&lt;p&gt;Case-translation convention None&lt;/p&gt; 
&lt;h5&gt;&lt;a href=&quot;https://learn.microsoft.com/en-us/cpp/cpp/fastcall&quot;&gt;&lt;code&gt;_fastcall&lt;/code&gt;&lt;/a&gt;&lt;/h5&gt; 
&lt;p&gt;The __fastcall calling convention specifies that arguments to functions are to be passed in registers, when possible. This calling convention only applies to the x86 architecture. The following list shows the implementation of this calling convention.&lt;/p&gt; 
&lt;table&gt; 
 &lt;thead&gt; 
  &lt;tr&gt;
   &lt;th&gt;Element &lt;/th&gt;
   &lt;th&gt; Implementation&lt;/th&gt;
  &lt;/tr&gt; 
 &lt;/thead&gt; 
 &lt;tbody&gt; 
  &lt;tr&gt;
   &lt;td&gt;Argument-passing order &lt;/td&gt;
   &lt;td&gt; The first two DWORD or smaller arguments that are found in the argument list from left to right are passed in ECX and EDX registers; all other arguments are passed on the stack from right to left.&lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt;Stack-maintenance responsibility &lt;/td&gt;
   &lt;td&gt; Called function pops the arguments from the stack.&lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt;Name-decoration convention &lt;/td&gt;
   &lt;td&gt; At sign (@) is prefixed to names; an at sign followed by the number of bytes (in decimal) in the parameter list is suffixed to names.&lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt;Case-translation convention &lt;/td&gt;
   &lt;td&gt; No case translation performed.&lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt;Classes, structs, and unions &lt;/td&gt;
   &lt;td&gt; Treated as &quot;multibyte&quot; types (regardless of size) and passed on the stack.&lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt;Enums and enum classes &lt;/td&gt;
   &lt;td&gt; Passed by register if their underlying type is passed by register. For example, if the underlying type is int or unsigned int of size 8, 16, or 32 bits.&lt;/td&gt;
  &lt;/tr&gt; 
 &lt;/tbody&gt; 
&lt;/table&gt; 
&lt;h5&gt;&lt;a href=&quot;https://learn.microsoft.com/en-us/cpp/cpp/clrcall&quot;&gt;&lt;code&gt;_clrcall&lt;/code&gt;&lt;/a&gt;&lt;/h5&gt; 
&lt;p&gt;Specifies that a function can only be called from &lt;a href=&quot;/content/vms/clr/&quot;&gt;managed code&lt;/a&gt;. Use __clrcall for all virtual functions that will only be called from managed code. However this calling convention cannot be used for functions that will be called from native code.&lt;/p&gt; 
&lt;p&gt;Use __clrcall to improve performance when calling from a managed function to a virtual managed function or from managed function to managed function through pointer.&lt;/p&gt; 
&lt;p&gt;Entry points are separate, compiler-generated functions. If a function has both native and managed entry points, one of them will be the actual function with the function implementation. The other function will be a separate function (a thunk) that calls into the actual function and lets the common language runtime perform PInvoke. When marking a function as __clrcall, you indicate the function implementation must be MSIL and that the native entry point function will not be generated.&lt;/p&gt; 
&lt;p&gt;When taking the address of a native function if __clrcall is not specified, the compiler uses the native entry point. __clrcall indicates that the function is managed and there is no need to go through the transition from managed to native. In that case the compiler uses the managed entry point.&lt;/p&gt; 
&lt;p&gt;When /clr (not /clr:pure or /clr:safe) is used and __clrcall is not used, taking the address of a function always returns the address of the native entry point function. When __clrcall is used, the native entry point function is not created, so you get the address of the managed function, not an entry point thunk function. For more information, see Double Thunking. The /clr:pure and /clr:safe compiler options are deprecated in Visual Studio 2015 and unsupported in Visual Studio 2017.&lt;/p&gt; 
&lt;p&gt;/clr (Common Language Runtime Compilation) implies that all functions and function pointers are __clrcall and the compiler will not permit a function inside the compiland to be marked anything other than __clrcall. When /clr:pure is used, __clrcall can only be specified on function pointers and external declarations.&lt;/p&gt; 
&lt;p&gt;You can directly call __clrcall functions from existing C++ code that was compiled by using /clr as long as that function has an MSIL implementation. __clrcall functions cannot be called directly from functions that have inline asm and call CPU-specific intrinsics, for example, even if those functions are compiled with /clr.&lt;/p&gt; 
&lt;p&gt;__clrcall function pointers are only meant to be used in the application domain in which they were created.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Readings&lt;/strong&gt;&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Measuring Mangled Name Ambiguity in Large C / C++ Projects 
  &lt;ul&gt; 
   &lt;li&gt;SQAMIA 2017&lt;/li&gt; 
   &lt;li&gt;Richárd Szalay, Zoltán Porkoláb, Dániel Krupp&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.researchgate.net/publication/320923382_Measuring_Mangled_Name_Ambiguity_in_Large_C_C_Projects&quot;&gt;https://www.researchgate.net/publication/320923382_Measuring_Mangled_Name_Ambiguity_in_Large_C_C_Projects&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://ceur-ws.org/Vol-1938/paper-sza.pdf&quot;&gt;http://ceur-ws.org/Vol-1938/paper-sza.pdf&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Towards Better Symbol Resolution for C/C++ Programs: A Cluster-Based Solution 
  &lt;ul&gt; 
   &lt;li&gt;Source Code Analysis and Manipulation (SCAM) 2017&lt;/li&gt; 
   &lt;li&gt;Richárd Szalay, Zoltán Porkoláb, Dániel Krupp&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://ieeexplore.ieee.org/document/8090143/&quot;&gt;http://ieeexplore.ieee.org/document/8090143/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.researchgate.net/publication/320832497_Towards_Better_Symbol_Resolution_for_CC_Programs_A_Cluster-Based_Solution&quot;&gt;https://www.researchgate.net/publication/320832497_Towards_Better_Symbol_Resolution_for_CC_Programs_A_Cluster-Based_Solution&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;&lt;strong&gt;Software&lt;/strong&gt;&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://d.fuqu.jp/c++filtjs/&quot;&gt;c++filtjs&lt;/a&gt; (&lt;a href=&quot;https://github.com/nattofriends/c-filtjs&quot;&gt;Source&lt;/a&gt;): c++filt in JavaScript with Emscripten&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/whitequark/binja_itanium_cxx_abi/blob/master/demangler.py&quot;&gt;C++ Itanium ABI demangler&lt;/a&gt;: C++ demangler in Python that converts the mangled name into an AST&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/AVGTechnologies/cppmangle&quot;&gt;cppmangle&lt;/a&gt;: A library for demangling and mangling Visual Studio C++ names&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/gimli-rs/cpp_demangle&quot;&gt;cpp_demangle&lt;/a&gt;: A crate for demangling C++ symbols&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/avast-tl/demangler&quot;&gt;Demangler&lt;/a&gt;: A C++ library and tools for demangling mangled C++ names 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/avast-tl/retdec/tree/master/src/demangler&quot;&gt;https://github.com/avast-tl/retdec/tree/master/src/demangler&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/avast-tl/retdec/tree/master/tests/demangler&quot;&gt;https://github.com/avast-tl/retdec/tree/master/tests/demangler&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/nico/demumble&quot;&gt;demumble&lt;/a&gt;: A better c++filt and a better undname.exe, in one binary. demumble demangles both POSIX and Visual Studio symbols. It runs on both POSIX and Windows.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://demangler.com/&quot;&gt;GCC and MSVC C++ Demangler&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;&lt;strong&gt;Talks&lt;/strong&gt;&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;C++ Weekly - Ep 8 C++ Name Demangling - &lt;a href=&quot;https://www.youtube.com/watch?v=uX99t7GmuDc&quot;&gt;https://www.youtube.com/watch?v=uX99t7GmuDc&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;&lt;a href=&quot;/languages/objc&quot;&gt;Obj-C&lt;/a&gt;&lt;/h4&gt; 
&lt;p&gt;Two forms of method in Objective-C, the class (&quot;static&quot;) method, and the instance method. A method declaration in Objective-C is of the following form:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;+ (return-type) name0:parameter0 name1:parameter1 ...
– (return-type) name0:parameter0 name1:parameter1 ...
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Class methods are signified by +, instance methods use -. A typical class method declaration may then look like:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;+ (id) initWithX: (int) number andY: (int) number;
+ (id) new;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;With instance methods looking like this:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;- (id) value;
- (id) setValue: (id) new_value;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Each of these method declarations have a specific internal representation. When compiled, each method is named according to the following scheme for class methods:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;_c_Class_name0_name1_ ...
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;and this for instance methods:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;_i_Class_name0_name1_ ...
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;The colons in the Objective-C syntax are translated to underscores. So, the Objective-C class method &lt;code&gt;+ (id) initWithX: (int) number andY: (int) number;&lt;/code&gt;, if belonging to the Point class would translate as &lt;code&gt;_c_Point_initWithX_andY_&lt;/code&gt;, and the instance method (belonging to the same class) &lt;code&gt;- (id) value;&lt;/code&gt; would translate to &lt;code&gt;_i_Point_value&lt;/code&gt;.&lt;/p&gt; 
&lt;p&gt;Each of the methods of a class are labeled in this way. However, in order to look up a method that a class may respond to would be tedious if all methods are represented in this fashion. Each of the methods is assigned a unique symbol (such as an integer). Such a symbol is known as a selector. In Objective-C, one can manage selectors directly — they have a specific type in Objective-C — &lt;code&gt;SEL&lt;/code&gt;.&lt;/p&gt; 
&lt;p&gt;During compilation, a table is built that maps the textual representation, such as &lt;code&gt;_i_Point_value&lt;/code&gt;, to selectors. Managing selectors is more efficient than manipulating the textual representation of a method. Note that a selector only matches a method&apos;s name, not the class it belongs to — different classes can have different implementations of a method with the same name. Because of this, implementations of a method are given a specific identifier too, these are known as implementation pointers, and are also given a type, &lt;code&gt;IMP&lt;/code&gt;.&lt;/p&gt; 
&lt;p&gt;Message sends are encoded by the compiler as calls to the &lt;code&gt;id objc_msgSend (id receiver, SEL selector, ...)&lt;/code&gt; function, or one of its cousins, where receiver is the receiver of the message, and SEL determines the method to call. Each class has its own table that maps selectors to their implementations — the implementation pointer specifies where in memory the actual implementation of the method resides. There are separate tables for class and instance methods. Apart from being stored in the &lt;code&gt;SEL&lt;/code&gt; to &lt;code&gt;IMP&lt;/code&gt; lookup tables, the functions are essentially anonymous.&lt;/p&gt; 
&lt;p&gt;The SEL value for a selector does not vary between classes. This enables polymorphism.&lt;/p&gt; 
&lt;p&gt;The Objective-C runtime maintains information about the argument and return types of methods. However, this information is not part of the name of the method, and can vary from class to class.&lt;/p&gt; 
&lt;p&gt;Since Objective-C does not support namespaces, there is no need for the mangling of class names (that do appear as symbols in generated binaries).&lt;/p&gt; 
&lt;h4&gt;Swift&lt;/h4&gt; 
&lt;p&gt;Swift keeps metadata about functions (and more) in the mangled symbols referring to them. This metadata includes the function&apos;s name, attributes, module name, parameter types, return type, and more. For example:&lt;/p&gt; 
&lt;p&gt;The mangled name for a method &lt;code&gt;func calculate(x: int) -&amp;gt; int&lt;/code&gt; of a &lt;code&gt;MyClass&lt;/code&gt; class in module &lt;code&gt;test&lt;/code&gt; is &lt;code&gt;_TFC4test7MyClass9calculatefS0_FT1xSi_Si&lt;/code&gt;, for 2014 Swift. &lt;a href=&quot;https://mikeash.com/pyblog/friday-qa-2014-08-15-swift-name-mangling.html&quot;&gt;The components and their meanings&lt;/a&gt; are as follows:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;_T: The prefix for all Swift symbols. Everything will start with this.&lt;/li&gt; 
 &lt;li&gt;F: Non-curried function.&lt;/li&gt; 
 &lt;li&gt;C: Function of a class, i.e. a method&lt;/li&gt; 
 &lt;li&gt;4test: Module name, prefixed with its length.&lt;/li&gt; 
 &lt;li&gt;7MyClass: Name of class the function belongs to, prefixed with its length.&lt;/li&gt; 
 &lt;li&gt;9calculate: Function name, prefixed with its length.&lt;/li&gt; 
 &lt;li&gt;f: The function attribute. In this case ‘f’, which means a normal function.&lt;/li&gt; 
 &lt;li&gt;S0: Designates the type of the first parameter (namely the class instance) as the first in the type stack (here MyClass is not nested and thus has index 0).&lt;/li&gt; 
 &lt;li&gt;_FT: This begins the type list for the parameter tuple of the function.&lt;/li&gt; 
 &lt;li&gt;1x: External name of first parameter of the function.&lt;/li&gt; 
 &lt;li&gt;Si: Indicates builtin Swift type Swift.Int for the first parameter.&lt;/li&gt; 
 &lt;li&gt;_Si: The return type: again Swift.Int.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;Mangling for versions since Swift 4.0 is &lt;a href=&quot;https://github.com/apple/swift/blob/main/docs/ABI/Mangling.rst&quot;&gt;documented officially&lt;/a&gt;.&lt;/p&gt; 
&lt;h2&gt;Calling conventions&lt;/h2&gt; 
&lt;p&gt;An implementation-level (low-level) scheme for how subroutines receive parameters from their caller and how they return a result. Differences in various implementations include where parameters, return values, return addresses and scope links are placed (registers, stack or memory etc.), and how the tasks of preparing for a function call and restoring the environment afterwards are divided between the caller and the callee.&lt;/p&gt; 
&lt;p&gt;Calling conventions may differ in:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Where parameters, return values and return addresses are placed (in registers, on the call stack, a mix of both, or in other memory structures)&lt;/li&gt; 
 &lt;li&gt;For parameters passed in memory, the order in which actual arguments for formal parameters are passed (or the parts of a large or complex argument)&lt;/li&gt; 
 &lt;li&gt;How a (possibly long or complex) return value is delivered from the callee back to the caller (on the stack, in a register, or within the heap)&lt;/li&gt; 
 &lt;li&gt;How the task of setting up for and cleaning up after a function call is divided between the caller and the callee&lt;/li&gt; 
 &lt;li&gt;Whether and how metadata describing the arguments is passed&lt;/li&gt; 
 &lt;li&gt;Where the previous value of the frame pointer is stored, which is used to restore the frame pointer when the routine ends (in the stack frame, or in some register)&lt;/li&gt; 
 &lt;li&gt;Where any static scope links for the routine&apos;s non-local data access are placed (typically at one or more positions in the stack frame, but sometimes in a general register, or, for some architectures, in special-purpose registers)&lt;/li&gt; 
 &lt;li&gt;How local variables are allocated can sometimes also be part of the calling convention (when the caller allocates for the callee)&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;In some cases, differences also include the following:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Conventions on which registers may be directly used by the callee, without being preserved&lt;/li&gt; 
 &lt;li&gt;Which registers are considered to be volatile and, if volatile, need not be restored by the callee&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;x86&lt;/h4&gt; 
&lt;p&gt;Due to the small number of architectural registers, and historical focus on simplicity and small code-size, many x86 calling conventions pass arguments on the stack. The return value (or a pointer to it) is returned in a register. Some conventions use registers for the first few parameters which may improve performance, especially for short and simple leaf-routines very frequently invoked (i.e. routines that do not call other routines).&lt;/p&gt; 
&lt;p&gt;Example caller:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;push EAX            ; pass some register result
push dword [EBP+20] ; pass some memory variable (FASM/TASM syntax)
push 3              ; pass some constant
call calc           ; the returned result is now in EAX
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Example callee (&lt;code&gt;calc&lt;/code&gt;):&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;calc:
push EBP            ; save old frame pointer
mov EBP,ESP         ; get new frame pointer
sub ESP,localsize   ; reserve stack space for locals

; perform calculations, leave result in EAX

mov ESP,EBP         ; free space for locals
pop EBP             ; restore old frame pointer
ret paramsize       ; free parameter space and return.
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Some conventions leave the parameter space allocated, using plain &lt;code&gt;ret&lt;/code&gt; instead of &lt;code&gt;ret imm16&lt;/code&gt;. In that case, the caller could &lt;code&gt;add esp,12&lt;/code&gt; in this example, or otherwise deal with the change to ESP.&lt;/p&gt; 
&lt;h4&gt;ARM (A32)&lt;/h4&gt; 
&lt;p&gt;The standard 32-bit ARM calling convention allocates the 15 general-purpose registers as:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;r15: Program counter (as per the instruction set specification).&lt;/li&gt; 
 &lt;li&gt;r14: Link register. The BL instruction, used in a subroutine call, stores the return address in this register.&lt;/li&gt; 
 &lt;li&gt;r13: Stack pointer. The Push/Pop instructions in &quot;Thumb&quot; operating mode use this register only.&lt;/li&gt; 
 &lt;li&gt;r12: Intra-Procedure-call scratch register.&lt;/li&gt; 
 &lt;li&gt;r4 to r11: Local variables.&lt;/li&gt; 
 &lt;li&gt;r0 to r3: Argument values passed to a subroutine and results returned from a subroutine.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;If the type of value returned is too large to fit in r0 to r3, or whose size cannot be determined statically at compile time, then the caller must allocate space for that value at run time, and pass a pointer to that space in r0.&lt;/p&gt; 
&lt;p&gt;Subroutines must preserve the contents of r4 to r11 and the stack pointer (perhaps by saving them to the stack in the function prologue, then using them as scratch space, then restoring them from the stack in the function epilogue). In particular, subroutines that call other subroutines must save the return address in the link register r14 to the stack before calling those other subroutines. However, such subroutines do not need to return that value to r14—they merely need to load that value into r15, the program counter, to return.&lt;/p&gt; 
&lt;p&gt;The ARM calling convention mandates using a full-descending stack. (&lt;a href=&quot;https://github.com/ARM-software/abi-aa/blob/2bcab1e3b22d55170c563c3c7940134089176746/aapcs32/aapcs32.rst&quot;&gt;Reference&lt;/a&gt;)&lt;/p&gt; 
&lt;p&gt;This calling convention causes a &quot;typical&quot; ARM subroutine to:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;In the prologue, push r4 to r11 to the stack, and push the return address in r14 to the stack (this can be done with a single STM instruction);&lt;/li&gt; 
 &lt;li&gt;Copy any passed arguments (in r0 to r3) to the local scratch registers (r4 to r11);&lt;/li&gt; 
 &lt;li&gt;Allocate other local variables to the remaining local scratch registers (r4 to r11);&lt;/li&gt; 
 &lt;li&gt;Do calculations and call other subroutines as necessary using BL, assuming r0 to r3, r12 and r14 will not be preserved;&lt;/li&gt; 
 &lt;li&gt;Put the result in r0;&lt;/li&gt; 
 &lt;li&gt;In the epilogue, pull r4 to r11 from the stack, and pull the return address to the program counter r15. This can be done with a single LDM instruction.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;ARM (A64)&lt;/h4&gt; 
&lt;p&gt;The &lt;a href=&quot;https://developer.arm.com/documentation/den0024/a/The-ABI-for-ARM-64-bit-Architecture/Register-use-in-the-AArch64-Procedure-Call-Standard/Parameters-in-general-purpose-registers&quot;&gt;AArch 64 calling convention&lt;/a&gt; allocates the 31 general-purpose registers as:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;x31 (SP): Stack pointer or a zero register, depending on context.&lt;/li&gt; 
 &lt;li&gt;x30 (LR): Procedure link register, used to return from subroutines.&lt;/li&gt; 
 &lt;li&gt;x29 (FP): Frame pointer.&lt;/li&gt; 
 &lt;li&gt;x19 to x29: Callee-saved.&lt;/li&gt; 
 &lt;li&gt;x18 (PR): Platform register. Used for some operating-system-specific special purpose, or an additional caller-saved register.&lt;/li&gt; 
 &lt;li&gt;x16 (IP0) and x17 (IP1): Intra-Procedure-call scratch registers.&lt;/li&gt; 
 &lt;li&gt;x9 to x15: Local variables, caller saved.&lt;/li&gt; 
 &lt;li&gt;x8 (XR): Indirect return value address.&lt;/li&gt; 
 &lt;li&gt;x0 to x7: Argument values passed to and results returned from a subroutine.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;All registers starting with x have a corresponding 32-bit register prefixed with w. Thus, a 32-bit x0 is called w0.&lt;/p&gt; 
&lt;p&gt;Similarly, &lt;a href=&quot;https://developer.arm.com/documentation/den0024/a/The-ABI-for-ARM-64-bit-Architecture/Register-use-in-the-AArch64-Procedure-Call-Standard/Parameters-in-NEON-and-floating-point-registers&quot;&gt;the 32 floating-point registers are allocated&lt;/a&gt; as:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;v0 to v7: Argument values passed to and results returned from a subroutine.&lt;/li&gt; 
 &lt;li&gt;v8 to v15: callee-saved, but only the bottom 64 bits need to be preserved.&lt;/li&gt; 
 &lt;li&gt;v16 to v31: Local variables, caller saved.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Known calling conventions&lt;/h2&gt; 
&lt;p&gt;References:&lt;/p&gt; 
&lt;h4&gt;&quot;cdecl&quot;&lt;/h4&gt; 
&lt;h4&gt;&quot;Pascal&quot; style&lt;/h4&gt; 
&lt;h4&gt;Windows &quot;stdcall&quot;&lt;/h4&gt; 
&lt;h4&gt;macOS ABI&lt;/h4&gt; 
&lt;p&gt;&lt;a href=&quot;https://developer.apple.com/library/archive/documentation/DeveloperTools/Conceptual/LowLevelABI/000-Introduction/introduction.html&quot;&gt;Outdated: OS X ABI Function Call Guide&lt;/a&gt; covers 32-/64-bit PowerPC, and &lt;a href=&quot;https://developer.apple.com/library/archive/documentation/DeveloperTools/Conceptual/LowLevelABI/130-IA-32_Function_Calling_Conventions/IA32.html&quot;&gt;IA-32&lt;/a&gt; / &lt;a href=&quot;https://developer.apple.com/library/archive/documentation/DeveloperTools/Conceptual/LowLevelABI/140-x86-64_Function_Calling_Conventions/x86_64.html&quot;&gt;x86-64&lt;/a&gt; calling conventions&lt;/p&gt; 
&lt;h2&gt;Application Binary Interfaces (ABI) in general&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;code&gt;[[trivial_abi]]&lt;/code&gt; 101: &lt;a href=&quot;https://quuxplusone.github.io/blog/2018/05/02/trivial-abi-101/&quot;&gt;https://quuxplusone.github.io/blog/2018/05/02/trivial-abi-101/&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;ABI Breaks: Not just about rebuilding: &lt;a href=&quot;https://www.reddit.com/r/cpp/comments/fc2qqv/abi_breaks_not_just_about_rebuilding/&quot;&gt;https://www.reddit.com/r/cpp/comments/fc2qqv/abi_breaks_not_just_about_rebuilding/&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;ABI Policy and Guidelines - The GNU C++ Library Manual: &lt;a href=&quot;https://gcc.gnu.org/onlinedocs/libstdc++/manual/abi.html&quot;&gt;https://gcc.gnu.org/onlinedocs/libstdc++/manual/abi.html&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;ABIs, linkers and other animals - Stephen Kell (2014): &lt;a href=&quot;https://www.cl.cam.ac.uk/~srk31/research/talks/kell14abis-slides.pdf&quot;&gt;https://www.cl.cam.ac.uk/~srk31/research/talks/kell14abis-slides.pdf&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;Binary Compatibility Examples: &lt;a href=&quot;https://community.kde.org/Policies/Binary_Compatibility_Examples&quot;&gt;https://community.kde.org/Policies/Binary_Compatibility_Examples&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;Binary Compatibility Issues With C++: &lt;a href=&quot;https://community.kde.org/Policies/Binary_Compatibility_Issues_With_C%2B%2B&quot;&gt;https://community.kde.org/Policies/Binary_Compatibility_Issues_With_C%2B%2B&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;Binary Compatibility of Shared Libraries Implemented in C++ on GNU/Linux Systems 
  &lt;ul&gt; 
   &lt;li&gt;SYRCoSE 2009; Pavel Shved, Denis Silakov&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://syrcose.ispras.ru/2009/files/02_paper.pdf&quot;&gt;http://syrcose.ispras.ru/2009/files/02_paper.pdf&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://static.coldattic.info/restricted/science/syrcose09/cppbincomp.pdf&quot;&gt;http://static.coldattic.info/restricted/science/syrcose09/cppbincomp.pdf&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Binary-compatible C++ Interfaces - &lt;a href=&quot;https://chadaustin.me/cppinterface.html&quot;&gt;https://chadaustin.me/cppinterface.html&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.bell-labs.com/usr/dmr/www/clcs.html&quot;&gt;&quot;The C Language Calling Sequence&quot;&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;C++ Standards Committee Papers 
  &lt;ul&gt; 
   &lt;li&gt;ABI breakage - summary of initial comments 
    &lt;ul&gt; 
     &lt;li&gt;2019; Roger Orr&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;http://wg21.link/P1654&quot;&gt;http://wg21.link/P1654&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;What is ABI, and What Should WG21 Do About It? 
    &lt;ul&gt; 
     &lt;li&gt;2020; Titus Winters&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;http://wg21.link/P2028&quot;&gt;http://wg21.link/P2028&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;Extending the Type System to Provide API and ABI Flexibility 
    &lt;ul&gt; 
     &lt;li&gt;P2123R0; 2020-03-04; Hal Finkel, Tom Scogland&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;http://wg21.link/p2123&quot;&gt;http://wg21.link/p2123&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;C++: Under the Hood (March 1994) by Jan Gray 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;http://files.rsdn.org/4539/cud94.htm&quot;&gt;http://files.rsdn.org/4539/cud94.htm&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://blogs.msdn.microsoft.com/xiangfan/2012/02/06/c-under-the-hood/&quot;&gt;https://blogs.msdn.microsoft.com/xiangfan/2012/02/06/c-under-the-hood/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.openrce.org/articles/files/jangrayhood.pdf&quot;&gt;https://www.openrce.org/articles/files/jangrayhood.pdf&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Calling conventions for different C++ compilers and operating systems: &lt;a href=&quot;http://www.agner.org/optimize/calling_conventions.pdf&quot;&gt;http://www.agner.org/optimize/calling_conventions.pdf&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;Describing the MSVC ABI for Structure Return Types: &lt;a href=&quot;http://blog.aaronballman.com/2012/02/describing-the-msvc-abi-for-structure-return-types/&quot;&gt;http://blog.aaronballman.com/2012/02/describing-the-msvc-abi-for-structure-return-types/&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;How C array sizes become part of the binary interface of a library: &lt;a href=&quot;https://developers.redhat.com/blog/2019/05/06/how-c-array-sizes-become-part-of-the-binary-interface-of-a-library/&quot;&gt;https://developers.redhat.com/blog/2019/05/06/how-c-array-sizes-become-part-of-the-binary-interface-of-a-library/&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;Itanium C++ ABI 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://itanium-cxx-abi.github.io/cxx-abi/&quot;&gt;https://itanium-cxx-abi.github.io/cxx-abi/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/itanium-cxx-abi/cxx-abi&quot;&gt;https://github.com/itanium-cxx-abi/cxx-abi&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Lessons from the Unix stdio ABI: 40 Years Later 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://fingolfin.org/blog/20200327/stdio-abi.html&quot;&gt;https://fingolfin.org/blog/20200327/stdio-abi.html&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Some thoughts on binary compatibility - &lt;a href=&quot;http://blog.qt.io/blog/2009/08/12/some-thoughts-on-binary-compatibility/&quot;&gt;http://blog.qt.io/blog/2009/08/12/some-thoughts-on-binary-compatibility/&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;Some thoughts on calling convention - &lt;a href=&quot;http://blog.qt.io/blog/2009/08/15/some-thoughts-on-calling-convention/&quot;&gt;http://blog.qt.io/blog/2009/08/15/some-thoughts-on-calling-convention/&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;The Importance of Calling Conventions - &lt;a href=&quot;http://blog.aaronballman.com/2011/04/the-importance-of-calling-conventions/&quot;&gt;http://blog.aaronballman.com/2011/04/the-importance-of-calling-conventions/&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;The value of passing by value - &lt;a href=&quot;https://www.macieira.org/blog/2012/02/the-value-of-passing-by-value/&quot;&gt;https://www.macieira.org/blog/2012/02/the-value-of-passing-by-value/&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;X86-64 System V Application Binary Interface: &lt;a href=&quot;https://github.com/hjl-tools/x86-psABI/wiki/X86-psABI&quot;&gt;https://github.com/hjl-tools/x86-psABI/wiki/X86-psABI&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Software&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;ABI Compliance Checker (ABICC) 
  &lt;ul&gt; 
   &lt;li&gt;A tool for checking backward API/ABI compatibility of a C/C++ library&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://lvc.github.io/abi-compliance-checker/&quot;&gt;https://lvc.github.io/abi-compliance-checker/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/lvc/abi-compliance-checker&quot;&gt;https://github.com/lvc/abi-compliance-checker&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://ispras.linuxbase.org/index.php/ABI_compliance_checker&quot;&gt;http://ispras.linuxbase.org/index.php/ABI_compliance_checker&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;How to check for ABI changes with abi compliance checker - &lt;a href=&quot;https://fedoraproject.org/wiki/How_to_check_for_ABI_changes_with_abi_compliance_checker&quot;&gt;https://fedoraproject.org/wiki/How_to_check_for_ABI_changes_with_abi_compliance_checker&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;ABI Dumper 
  &lt;ul&gt; 
   &lt;li&gt;A tool to dump ABI of an ELF object containing DWARF debug info&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/lvc/abi-dumper&quot;&gt;https://github.com/lvc/abi-dumper&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;ABIGAIL: Application Binary Interface Generic Analysis and Instrumentation Library 
  &lt;ul&gt; 
   &lt;li&gt;abidiff - compares the Application Binary Interfaces (ABI) of two shared libraries in ELF format 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://sourceware.org/libabigail/manual/abidiff.html&quot;&gt;https://sourceware.org/libabigail/manual/abidiff.html&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;abidw - reads a shared library in ELF format and emits an XML representation of its ABI to standard output 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://sourceware.org/libabigail/manual/abidw.html&quot;&gt;https://sourceware.org/libabigail/manual/abidw.html&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;abicompat - checks that an application that links against a given shared library is still ABI compatible with a subsequent version of that library 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://sourceware.org/libabigail/manual/abicompat.html&quot;&gt;https://sourceware.org/libabigail/manual/abicompat.html&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;Comparing ABIs for Compatibility with libabigail – Part 1 - &lt;a href=&quot;https://developers.redhat.com/blog/2014/10/23/comparing-abis-for-compatibility-with-libabigail-part-1/&quot;&gt;https://developers.redhat.com/blog/2014/10/23/comparing-abis-for-compatibility-with-libabigail-part-1/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Comparing ABIs for Compatibility with libabigail – Part 2 - &lt;a href=&quot;https://developers.redhat.com/blog/2014/10/28/comparing-abis-for-compatibility-libabigail-part-2/&quot;&gt;https://developers.redhat.com/blog/2014/10/28/comparing-abis-for-compatibility-libabigail-part-2/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Pruning Dynamic Rebuilds With libabigail 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://engineering.mongodb.com/post/pruning-dynamic-rebuilds-with-libabigail&quot;&gt;https://engineering.mongodb.com/post/pruning-dynamic-rebuilds-with-libabigail&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://github.com/acmorrow/abilink-demo&quot;&gt;https://github.com/acmorrow/abilink-demo&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;Talk: Libabigail: How semantic analysis of C and C++ ELF binaries can be used to analyze ABI changes (openSUSE Conference 2017) 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://media.ccc.de/v/1234-libabigail-how-semantic-analysis-of-c-and-c-elf-binaries-can-be-used-to-analyze-abi-changes&quot;&gt;https://media.ccc.de/v/1234-libabigail-how-semantic-analysis-of-c-and-c-elf-binaries-can-be-used-to-analyze-abi-changes&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=wxVBuZK8Dl0&quot;&gt;https://www.youtube.com/watch?v=wxVBuZK8Dl0&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;abimap: A helper for library maintainers to use symbol versioning 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/ansasaki/abimap&quot;&gt;https://github.com/ansasaki/abimap&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Don&apos;t break your users: keep your API/ABI stable! 
    &lt;ul&gt; 
     &lt;li&gt;DevConf.CZ 2020; Anderson Sasaki&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=tFuFO_bDke0&quot;&gt;https://www.youtube.com/watch?v=tFuFO_bDke0&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;pexcheck: Pexcheck is a command-line tool for checking the binary compatibility of public interfaces. 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/AVGTechnologies/pexcheck&quot;&gt;https://github.com/AVGTechnologies/pexcheck&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Talks&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;Analyzing changes to the binary interface exposed by the Kernel to its modules 
  &lt;ul&gt; 
   &lt;li&gt;Kernel Recipes 2019; Dodji Seketeli, Matthias Männich, Jessica Yu&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://kernel-recipes.org/en/2019/talks/analyzing-changes-to-the-binary-interface-exposed-by-the-kernel-to-its-modules/&quot;&gt;https://kernel-recipes.org/en/2019/talks/analyzing-changes-to-the-binary-interface-exposed-by-the-kernel-to-its-modules/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;API &amp;amp; ABI versioning 
  &lt;ul&gt; 
   &lt;li&gt;Meeting C++ 2017; Mathieu Ropert&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=k9PLRAnnEmE&quot;&gt;https://www.youtube.com/watch?v=k9PLRAnnEmE&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Binary compatibility for library developers 
  &lt;ul&gt; 
   &lt;li&gt;C++Now 2013; Thiago Macieira&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=PHrXGHDd9no&quot;&gt;https://www.youtube.com/watch?v=PHrXGHDd9no&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/boostcon/cppnow_presentations_2013/blob/master/tue/binary_compat_for_cpp_devs.pdf?raw=true&quot;&gt;https://github.com/boostcon/cppnow_presentations_2013/blob/master/tue/binary_compat_for_cpp_devs.pdf?raw=true&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Easy Binary Compatible C++ Interfaces Across Compilers 
  &lt;ul&gt; 
   &lt;li&gt;C++Now 2013; John Bandela&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=BbbqBJ94-_E&quot;&gt;https://www.youtube.com/watch?v=BbbqBJ94-_E&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;PDF: &lt;a href=&quot;https://github.com/boostcon/cppnow_presentations_2013/blob/master/tue/easy_binary_compat.pdf?raw=true&quot;&gt;https://github.com/boostcon/cppnow_presentations_2013/blob/master/tue/easy_binary_compat.pdf?raw=true&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;PPT: &lt;a href=&quot;https://github.com/boostcon/cppnow_presentations_2013/blob/master/tue/easy_binary_compat.ppt?raw=true&quot;&gt;https://github.com/boostcon/cppnow_presentations_2013/blob/master/tue/easy_binary_compat.ppt?raw=true&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://jrb-programming.blogspot.com/2012/12/easy-binary-compatible-interfaces.html&quot;&gt;https://jrb-programming.blogspot.com/2012/12/easy-binary-compatible-interfaces.html&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/jbandela/cppcomponents&quot;&gt;https://github.com/jbandela/cppcomponents&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/jbandela/cross_compiler_call&quot;&gt;https://github.com/jbandela/cross_compiler_call&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;How to break an ABI and keep your users happy 
  &lt;ul&gt; 
   &lt;li&gt;CppCon 2017; Gennadiy Rozental&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=NzaYUlAw93k&quot;&gt;https://www.youtube.com/watch?v=NzaYUlAw93k&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://abseil.io/blog/20171023-cppcon-breaking-abi&quot;&gt;https://abseil.io/blog/20171023-cppcon-breaking-abi&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Linux User/Kernel ABI: the realities of how C and C++ programs really talk to the OS 
  &lt;ul&gt; 
   &lt;li&gt;ACCU 2018; Greg Law&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=4CdmGxc5BpU&quot;&gt;https://www.youtube.com/watch?v=4CdmGxc5BpU&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Reversing C++ 
  &lt;ul&gt; 
   &lt;li&gt;Black Hat USA 2007; Paul Vincent Sabanal, Mark Vincent Yason&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.blackhat.com/presentations/bh-dc-07/Sabanal_Yason/Presentation/bh-dc-07-Sabanal_Yason.pdf&quot;&gt;https://www.blackhat.com/presentations/bh-dc-07/Sabanal_Yason/Presentation/bh-dc-07-Sabanal_Yason.pdf&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.blackhat.com/presentations/bh-dc-07/Sabanal_Yason/Paper/bh-dc-07-Sabanal_Yason-WP.pdf&quot;&gt;https://www.blackhat.com/presentations/bh-dc-07/Sabanal_Yason/Paper/bh-dc-07-Sabanal_Yason-WP.pdf&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Videos: 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://archive.org/details/2007_BlackHat_Vegas-V72-Yason-Sabanal-Reversing_C&quot;&gt;https://archive.org/details/2007_BlackHat_Vegas-V72-Yason-Sabanal-Reversing_C&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=oJ3mOzD7rC8&quot;&gt;https://www.youtube.com/watch?v=oJ3mOzD7rC8&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;00: &lt;a href=&quot;https://www.youtube.com/watch?v=Vy0z1baCh8s&quot;&gt;https://www.youtube.com/watch?v=Vy0z1baCh8s&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;01: &lt;a href=&quot;https://www.youtube.com/watch?v=1wZ615YlMFs&quot;&gt;https://www.youtube.com/watch?v=1wZ615YlMFs&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;02: &lt;a href=&quot;https://www.youtube.com/watch?v=dcoNjUn_ACI&quot;&gt;https://www.youtube.com/watch?v=dcoNjUn_ACI&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;03: &lt;a href=&quot;https://www.youtube.com/watch?v=JZ8_QM-XM1k&quot;&gt;https://www.youtube.com/watch?v=JZ8_QM-XM1k&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;The ABI challenge 
  &lt;ul&gt; 
   &lt;li&gt;C++Now 2019; Arvid Norberg&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=ncyQAjTyPwU&quot;&gt;https://www.youtube.com/watch?v=ncyQAjTyPwU&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;The C++ ABI From the Ground Up 
  &lt;ul&gt; 
   &lt;li&gt;CppCon 2019; Louis Dionne&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=DZ93lP1I7wU&quot;&gt;https://www.youtube.com/watch?v=DZ93lP1I7wU&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;What&apos;s an ABI and why is it so complicated? 
  &lt;ul&gt; 
   &lt;li&gt;ACCU 2015; Jonathan Wakely&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://accu.org/content/conf2015/JonathanWakely-What%20Is%20An%20ABI%20And%20Why%20Is%20It%20So%20Complicated.pdf&quot;&gt;https://accu.org/content/conf2015/JonathanWakely-What%20Is%20An%20ABI%20And%20Why%20Is%20It%20So%20Complicated.pdf&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;hr&gt; 
&lt;h1&gt;Bash&lt;/h1&gt; 
&lt;ul&gt; 
 &lt;li&gt;ctypes.sh: a foreign function interface for bash 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/taviso/ctypes.sh&quot;&gt;https://github.com/taviso/ctypes.sh&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;hr&gt; 
&lt;h1&gt;Stata&lt;/h1&gt; 
&lt;ul&gt; 
 &lt;li&gt;Stata commands for inline C++ code in do-files 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/robertgrant/statacpp&quot;&gt;https://github.com/robertgrant/statacpp&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Cryptocurrency reading</title>
      <link>https://tedneward.github.io/Research/reading/development/cryptocurrency/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">reading/development/cryptocurrency/index.html</guid>
      	<description>
	&lt;h2&gt;Video&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=ORdWE_ffirg&quot;&gt;Crypto: The World&apos;s Greatest Scam&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Reading&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://blog.dshr.org/2022/02/ee380-talk.html&quot;&gt;EE380 talk&lt;/a&gt; (&lt;a href=&quot;../EE380Talk.pdf&quot;&gt;PDF&lt;/a&gt;) by David Rosenthal&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://bitcoinbook.cs.princeton.edu&quot;&gt;Bitcoin and Cryptocurrency Technologies&lt;/a&gt; - Arvind Narayanan, Joseph Bonneau, Edward Felten, Andrew Miller, Steven Goldfeder, Jeremy Clark (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://rosenbaum.se/book/&quot;&gt;Grokking Bitcoin&lt;/a&gt; - Kalle Rosenbaum (HTML)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/bitcoinbook/bitcoinbook&quot;&gt;Mastering Bitcoin - Unlocking digital currencies&lt;/a&gt; - Andreas M. Antonopoulos&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Data concurrency and parallel programming</title>
      <link>https://tedneward.github.io/Research/reading/development/data-concurrency/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">reading/development/data-concurrency/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;http://dl.acm.org/citation.cfm?id=1394128&amp;amp;bnc=1&quot;&gt;&quot;BASE: An Alternative to ACID&quot;&lt;/a&gt; (&lt;a href=&quot;https://dl.acm.org/doi/pdf/10.1145/1394127.1394128&quot;&gt;PDF&lt;/a&gt;)&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://crdt.tech/&quot;&gt;CRDTs.tech&lt;/a&gt;: A Conflict-free Replicated Data Type (CRDT) is a data structure that simplifies distributed data storage systems and multi-user applications.&lt;/p&gt; 
&lt;h3&gt;Parallel Programming&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;http://cnx.org/contents/bb821554-7f76-44b1-89e7-8a2a759d1347%405.2&quot;&gt;High Performance Computing&lt;/a&gt; - Charles Severance &amp;amp; Kevin Dowd (PDF, ePUB)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://web.archive.org/web/20170702124132/https://hpc.llnl.gov/training/tutorials&quot;&gt;High Performance Computing Training&lt;/a&gt; (LLNL materials)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://andreask.cs.illinois.edu/Teaching/HPCFall2012&quot;&gt;High-Performance Scientific Computing&lt;/a&gt; (class lectures and slides)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://pages.tacc.utexas.edu/~eijkhout/istc/istc.html&quot;&gt;Introduction to High-Performance Scientific Computing&lt;/a&gt; - Victor Eijkhout&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://computing.llnl.gov/tutorials/parallel_comp/&quot;&gt;Introduction to Parallel Computing&lt;/a&gt; - Blaise Barney&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.kernel.org/pub/linux/kernel/people/paulmck/perfbook/perfbook.html&quot;&gt;Is Parallel Programming Hard, And, If So, What Can You Do About It?&lt;/a&gt; - Paul E. McKenney&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://heather.cs.ucdavis.edu/parprocbook&quot;&gt;Programming on Parallel Machines; GPU, Multicore, Clusters and More&lt;/a&gt; - Norm Matloff&lt;br&gt; Kerridge (PDF) (email address &lt;em&gt;requested&lt;/em&gt;, not required)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://us.fixstars.com/products/opencl/book/OpenCLProgrammingBook/contents/&quot;&gt;The OpenCL Programming Book&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Debugging reading</title>
      <link>https://tedneward.github.io/Research/reading/development/debugging/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">reading/development/debugging/index.html</guid>
      	<description>
	&lt;ul&gt; 
 &lt;li&gt;Program repair: Community-driven effort to facilitate discovery, access and systematization of data related to automated program repair research 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;http://program-repair.org/&quot;&gt;http://program-repair.org/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;UNIX Debugger Translation Table: gdb, lldb, dbx, adb, sdb 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.lurklurk.org/debuggers.html&quot;&gt;https://www.lurklurk.org/debuggers.html&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://wizardzines.com/zines/debugging-guide/&quot;&gt;The Pocket Guide to Debugging&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;hr&gt; 
&lt;h1&gt;Standard Libraries&lt;/h1&gt; 
&lt;ul&gt; 
 &lt;li&gt;GLIBC (GNU C Library) 
  &lt;ul&gt; 
   &lt;li&gt;General GLIBC Debugging Techniques - &lt;a href=&quot;http://sourceware.org/glibc/wiki/Debugging/Development_Debugging&quot;&gt;http://sourceware.org/glibc/wiki/Debugging/Development_Debugging&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;GDB pretty-printers for GLIBC 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;http://sourceware.org/glibc/wiki/Debugging/Pretty_Printers&quot;&gt;http://sourceware.org/glibc/wiki/Debugging/Pretty_Printers&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;Debugging the Loader - &lt;a href=&quot;https://sourceware.org/glibc/wiki/Debugging/Loader_Debugging&quot;&gt;https://sourceware.org/glibc/wiki/Debugging/Loader_Debugging&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Backtraces - &lt;a href=&quot;http://www.gnu.org/software/libc/manual/html_node/Backtraces.html&quot;&gt;http://www.gnu.org/software/libc/manual/html_node/Backtraces.html&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Allocation Debugging - &lt;a href=&quot;http://www.gnu.org/software/libc/manual/html_node/Allocation-Debugging.html&quot;&gt;http://www.gnu.org/software/libc/manual/html_node/Allocation-Debugging.html&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;libstdc++ Debug Mode: &lt;a href=&quot;https://gcc.gnu.org/onlinedocs/libstdc++/manual/debug_mode.html&quot;&gt;https://gcc.gnu.org/onlinedocs/libstdc++/manual/debug_mode.html&lt;/a&gt; 
  &lt;ul&gt; 
   &lt;li&gt;Detecting incorrect C++ STL usage (libstdc++) - &lt;a href=&quot;https://kristerw.blogspot.com/2018/03/detecting-incorrect-c-stl-usage.html&quot;&gt;https://kristerw.blogspot.com/2018/03/detecting-incorrect-c-stl-usage.html&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;libc++ 
  &lt;ul&gt; 
   &lt;li&gt;Debug Mode: &lt;a href=&quot;https://libcxx.llvm.org/docs/DesignDocs/DebugMode.html&quot;&gt;https://libcxx.llvm.org/docs/DesignDocs/DebugMode.html&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;GDB pretty-printers for libc++ 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://github.com/llvm/llvm-project/blob/master/libcxx/utils/gdb/libcxx/printers.py&quot;&gt;https://github.com/llvm/llvm-project/blob/master/libcxx/utils/gdb/libcxx/printers.py&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://chromium.googlesource.com/chromium/src/+/master/third_party/libcxx-pretty-printers/printers.py&quot;&gt;https://chromium.googlesource.com/chromium/src/+/master/third_party/libcxx-pretty-printers/printers.py&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://github.com/koutheir/libcxx-pretty-printers&quot;&gt;https://github.com/koutheir/libcxx-pretty-printers&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Visual C++ Debug Iterator Support: &lt;a href=&quot;https://docs.microsoft.com/en-us/cpp/standard-library/debug-iterator-support&quot;&gt;https://docs.microsoft.com/en-us/cpp/standard-library/debug-iterator-support&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;hr&gt; 
&lt;h1&gt;Readings&lt;/h1&gt; 
&lt;ul&gt; 
 &lt;li&gt;Debugging - Ian Lance Taylor - &lt;a href=&quot;https://airs.com/ian/essays/debug/debug.html&quot;&gt;https://airs.com/ian/essays/debug/debug.html&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;Debugging in the (Very) Large: Ten Years of Implementation and Experience 
  &lt;ul&gt; 
   &lt;li&gt;Symposium on Operating Systems Principles (SOSP) 2009&lt;/li&gt; 
   &lt;li&gt;Kirk Glerum, Kinshuman Kinshumann, Steve Greenberg, Gabriel Aul, Vince Orgovan, Greg Nichols, David Grant, Gretchen Loihle, Galen Hunt&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.microsoft.com/en-us/research/publication/debugging-in-the-very-large-ten-years-of-implementation-and-experience/&quot;&gt;https://www.microsoft.com/en-us/research/publication/debugging-in-the-very-large-ten-years-of-implementation-and-experience/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.sigops.org/sosp/sosp09/papers/glerum-sosp09.pdf&quot;&gt;https://www.sigops.org/sosp/sosp09/papers/glerum-sosp09.pdf&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.sigops.org/sosp/sosp09/slides/glerum-slides-sosp09.pdf&quot;&gt;https://www.sigops.org/sosp/sosp09/slides/glerum-slides-sosp09.pdf&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;debugging-stories: A collection of debugging stories 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/danluu/debugging-stories&quot;&gt;https://github.com/danluu/debugging-stories&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://danluu.com/teach-debugging/&quot;&gt;http://danluu.com/teach-debugging/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Delta Debugging 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.st.cs.uni-saarland.de/dd/&quot;&gt;https://www.st.cs.uni-saarland.de/dd/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Delta: Heuristically minimizes interesting files 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;http://delta.stage.tigris.org/&quot;&gt;http://delta.stage.tigris.org/&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;Minimizing Interesting Files with Delta 
      &lt;ul&gt; 
       &lt;li&gt;&lt;a href=&quot;http://delta.stage.tigris.org/using_delta.html&quot;&gt;http://delta.stage.tigris.org/using_delta.html&lt;/a&gt;&lt;/li&gt; 
      &lt;/ul&gt; &lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;Yesterday, my program worked. Today, it does not. Why? 
    &lt;ul&gt; 
     &lt;li&gt;ESEC 1999&lt;/li&gt; 
     &lt;li&gt;Andreas Zeller&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://www.st.cs.uni-saarland.de/publications/details/zeller-esec-1999/&quot;&gt;https://www.st.cs.uni-saarland.de/publications/details/zeller-esec-1999/&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;Picireny: Hierarchical Delta Debugging Framework 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://github.com/renatahodovan/picireny&quot;&gt;https://github.com/renatahodovan/picireny&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;Simplifying and Isolating Failure-Inducing Input 
    &lt;ul&gt; 
     &lt;li&gt;IEEE Transactions on Software Engineering 28(2) 2002&lt;/li&gt; 
     &lt;li&gt;Andreas Zeller, Ralf Hildebrandt&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://www.st.cs.uni-saarland.de/publications/details/zeller-tse-2002/&quot;&gt;https://www.st.cs.uni-saarland.de/publications/details/zeller-tse-2002/&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://blog.acolyer.org/2015/11/16/simplifying-and-isolating-failure-inducing-input/&quot;&gt;https://blog.acolyer.org/2015/11/16/simplifying-and-isolating-failure-inducing-input/&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;HDD: Hierarchical Delta Debugging 
    &lt;ul&gt; 
     &lt;li&gt;ICSE 2006&lt;/li&gt; 
     &lt;li&gt;Ghassan Misherghi, Zhendong Su&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://dl.acm.org/citation.cfm?id=1134307&quot;&gt;https://dl.acm.org/citation.cfm?id=1134307&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://blog.acolyer.org/2015/11/17/hierarchical-delta-debugging/&quot;&gt;https://blog.acolyer.org/2015/11/17/hierarchical-delta-debugging/&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;Generalizing and Criticizing Delta Debugging 
    &lt;ul&gt; 
     &lt;li&gt;2011; John Regehr&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://blog.regehr.org/archives/527&quot;&gt;https://blog.regehr.org/archives/527&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;Debugging Inputs 
    &lt;ul&gt; 
     &lt;li&gt;International Conference on Software Engineering (ICSE) 2020&lt;/li&gt; 
     &lt;li&gt;Lukas Kirschner, Ezekiel Soremekun, and Andreas Zeller&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://www.dropbox.com/s/ddn3fe55lws1rdr/icse2020-ddmax.pdf&quot;&gt;https://www.dropbox.com/s/ddn3fe55lws1rdr/icse2020-ddmax.pdf&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;ddmax implementations &amp;amp; experimental data: &lt;a href=&quot;https://tinyurl.com/DebuggingInputs&quot;&gt;https://tinyurl.com/DebuggingInputs&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Devon H. O&apos;Dell 
  &lt;ul&gt; 
   &lt;li&gt;Building a Debugging Mindset 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://9vx.org/post/building-a-debugging-mindset/&quot;&gt;https://9vx.org/post/building-a-debugging-mindset/&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://www.infoq.com/presentations/debugging-mindset&quot;&gt;https://www.infoq.com/presentations/debugging-mindset&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://speakerdeck.com/dho/building-a-debugging-mindset&quot;&gt;https://speakerdeck.com/dho/building-a-debugging-mindset&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;Debugging: Psychology, Theory, and Application - &lt;a href=&quot;https://9vx.org/post/debugging-psychology-theory-and-application/&quot;&gt;https://9vx.org/post/debugging-psychology-theory-and-application/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;The Debugging Mindset - &lt;a href=&quot;https://queue.acm.org/detail.cfm?id=3068754&quot;&gt;https://queue.acm.org/detail.cfm?id=3068754&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Henrik Warne 
  &lt;ul&gt; 
   &lt;li&gt;Great Programmers Write Debuggable Code - &lt;a href=&quot;https://henrikwarne.com/2013/05/05/great-programmers-write-debuggable-code/&quot;&gt;https://henrikwarne.com/2013/05/05/great-programmers-write-debuggable-code/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Finding Bugs: Debugger versus Logging - &lt;a href=&quot;https://henrikwarne.com/2014/01/01/finding-bugs-debugger-versus-logging/&quot;&gt;https://henrikwarne.com/2014/01/01/finding-bugs-debugger-versus-logging/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Learning From Your Bugs - &lt;a href=&quot;https://henrikwarne.com/2016/04/28/learning-from-your-bugs/&quot;&gt;https://henrikwarne.com/2016/04/28/learning-from-your-bugs/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;How to Debug - John Regehr - &lt;a href=&quot;https://blog.regehr.org/archives/199&quot;&gt;https://blog.regehr.org/archives/199&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;I tend to prefer debugging with release builds instead of debug builds - Ken Johnson (Skywing) - &lt;a href=&quot;http://www.nynaeve.net/?p=184&quot;&gt;http://www.nynaeve.net/?p=184&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;The Inflection Point Hypothesis: A Principled Debugging Approach for Locating the Root Cause of a Failure 
  &lt;ul&gt; 
   &lt;li&gt;Symposium on Operating Systems Principles (SOSP) 2019&lt;/li&gt; 
   &lt;li&gt;Yongle Zhang, Kirk Rodrigues, Yu Luo, Michael Stumm, Ding Yuan&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://dl.acm.org/citation.cfm?id=3359650&quot;&gt;https://dl.acm.org/citation.cfm?id=3359650&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://blog.acolyer.org/2019/11/08/the-inflection-point-hypothesis/&quot;&gt;https://blog.acolyer.org/2019/11/08/the-inflection-point-hypothesis/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;What does debugging a program look like? - Julia Evans - &lt;a href=&quot;https://jvns.ca/blog/2019/06/23/a-few-debugging-resources/&quot;&gt;https://jvns.ca/blog/2019/06/23/a-few-debugging-resources/&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;When debugging a stack overflow, you want to focus on the repeating recursive part - Raymond Chen - &lt;a href=&quot;https://blogs.msdn.microsoft.com/oldnewthing/20090107-00/?p=19573&quot;&gt;https://blogs.msdn.microsoft.com/oldnewthing/20090107-00/?p=19573&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Books, Book Reviews&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;Effective Debugging - &lt;a href=&quot;https://www.spinellis.gr/debugging/&quot;&gt;https://www.spinellis.gr/debugging/&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;Four Books on Debugging - &lt;a href=&quot;https://blog.regehr.org/archives/849&quot;&gt;https://blog.regehr.org/archives/849&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;Geoff Wozniak 
  &lt;ul&gt; 
   &lt;li&gt;On battle scars and debugging - &lt;a href=&quot;http://wozniak.ca/blog/2018/01/15/On-battle-scars-and-debugging/&quot;&gt;http://wozniak.ca/blog/2018/01/15/On-battle-scars-and-debugging/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;From intuition to methodology in debugging - &lt;a href=&quot;http://wozniak.ca/blog/2018/02/04/From-intuition-to-methodology-in-debugging/&quot;&gt;http://wozniak.ca/blog/2018/02/04/From-intuition-to-methodology-in-debugging/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Formalizing debugging - &lt;a href=&quot;https://wozniak.ca/blog/2018/03/25/Book-review-Formalizing-debugging/&quot;&gt;https://wozniak.ca/blog/2018/03/25/Book-review-Formalizing-debugging/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Why Programs Fail: A Guide to Systematic Debugging - &lt;a href=&quot;http://www.whyprogramsfail.com/&quot;&gt;http://www.whyprogramsfail.com/&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Concurrency&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;Interactive Debugging of Concurrent Programs under Relaxed Memory Models 
  &lt;ul&gt; 
   &lt;li&gt;CGO 2020&lt;/li&gt; 
   &lt;li&gt;Aakanksha Verma, Pankaj Kumar Kalita, Awanish Pandey, and Subhajit Roy&lt;/li&gt; 
   &lt;li&gt;Gambit: GDB Assisted Memory Behavior and Interference Tester&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://doi.org/10.1145/3368826.3377910&quot;&gt;https://doi.org/10.1145/3368826.3377910&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Probe Effect&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;A probe effect in concurrent programs 
  &lt;ul&gt; 
   &lt;li&gt;Software: Practice and Experience 16 (3)(1986)&lt;/li&gt; 
   &lt;li&gt;J. Gait&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://doi.org/10.1002/spe.4380160304&quot;&gt;https://doi.org/10.1002/spe.4380160304&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Debugging Concurrent Programs 
  &lt;ul&gt; 
   &lt;li&gt;ACM Computing Surveys (CSUR) 21(4) 1989&lt;/li&gt; 
   &lt;li&gt;C. E. McDowell, D. P. Helmbold&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://users.soe.ucsc.edu/~dph/mypubs/debugConcProg89.pdf&quot;&gt;https://users.soe.ucsc.edu/~dph/mypubs/debugConcProg89.pdf&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Implementation&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;An Efficient and Generic Reversible Debugger using the Virtual Machine based Approach 
  &lt;ul&gt; 
   &lt;li&gt;Virtual Execution Environments (VEE) 2005&lt;/li&gt; 
   &lt;li&gt;Toshihiko Koju, Shingo Takada, Norihisa Doi&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.usenix.org/events/vee05/full_papers/p79-koju.pdf&quot;&gt;https://www.usenix.org/events/vee05/full_papers/p79-koju.pdf&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Debin: Predicting Debug Information in Stripped Binaries 
  &lt;ul&gt; 
   &lt;li&gt;ACM CCS 2018&lt;/li&gt; 
   &lt;li&gt;Jingxuan He, Pesho Ivanov, Petar Tsankov, Veselin Raychev, Martin Vechev&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://dl.acm.org/citation.cfm?id=3243866&quot;&gt;https://dl.acm.org/citation.cfm?id=3243866&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=x1x_KtS-5Hs&quot;&gt;https://www.youtube.com/watch?v=x1x_KtS-5Hs&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/eth-sri/debin&quot;&gt;https://github.com/eth-sri/debin&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://files.sri.inf.ethz.ch/website/papers/ccs18-debin.pdf&quot;&gt;https://files.sri.inf.ethz.ch/website/papers/ccs18-debin.pdf&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Debuggers for Programming Languages 
  &lt;ul&gt; 
   &lt;li&gt;2002 Book Chapter in &quot;The Compiler Design Handbook: Optimizations and Machine Code Generation&quot;&lt;/li&gt; 
   &lt;li&gt;Sanjeev Kumar Aggarwal, M. Sarath Kumar&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.taylorfrancis.com/books/9781420040579/chapters/10.1201%2F9781420040579-12&quot;&gt;https://www.taylorfrancis.com/books/9781420040579/chapters/10.1201%2F9781420040579-12&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Debugging with the natives - Stephen Kell 
  &lt;ul&gt; 
   &lt;li&gt;part 1 - &lt;a href=&quot;http://www.cl.cam.ac.uk/~srk31/blog/2016/02/25/#native-debugging-part-1&quot;&gt;http://www.cl.cam.ac.uk/~srk31/blog/2016/02/25/#native-debugging-part-1&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;part 2 - &lt;a href=&quot;http://www.cl.cam.ac.uk/~srk31/blog/2017/01/30/#native-debugging-part-2&quot;&gt;http://www.cl.cam.ac.uk/~srk31/blog/2017/01/30/#native-debugging-part-2&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Debugging Native Extensions of Dynamic Languages 
  &lt;ul&gt; 
   &lt;li&gt;International Conference on Managed Languages &amp;amp; Runtimes (ManLang) 2018&lt;/li&gt; 
   &lt;li&gt;Jacob Kreindl, Manuel Rigger, Hanspeter Mössenböck&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://doi.org/10.1145/3237009.3237017&quot;&gt;https://doi.org/10.1145/3237009.3237017&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://ssw.jku.at/General/Staff/Kreindl/papers/ManLang_2018_SulongDebugging.pdf&quot;&gt;http://ssw.jku.at/General/Staff/Kreindl/papers/ManLang_2018_SulongDebugging.pdf&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Debugging with Intelligence via Probabilistic Inference 
  &lt;ul&gt; 
   &lt;li&gt;Zhaogui Xu, Shiqing Ma, Xiangyu Zhang, Shuofei Zhu, Baowen Xu&lt;/li&gt; 
   &lt;li&gt;International Conference on Software Engineering (ICSE) 2018&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.cs.purdue.edu/homes/ma229/papers/ICSE18.pdf&quot;&gt;https://www.cs.purdue.edu/homes/ma229/papers/ICSE18.pdf&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://blog.acolyer.org/2018/06/19/debugging-with-intelligence-via-probabilistic-inference/&quot;&gt;https://blog.acolyer.org/2018/06/19/debugging-with-intelligence-via-probabilistic-inference/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Debugopt: Debugging fully optimized natively compiled programs using multistage instrumentation 
  &lt;ul&gt; 
   &lt;li&gt;Science of Computer Programming 169 (2019)&lt;/li&gt; 
   &lt;li&gt;Jie Yin, Gang Tan, Hao Li, Xiaolong Bai, Yu Ping Wang, Shi Min Hu&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.sciencedirect.com/science/article/pii/S0167642318303629&quot;&gt;https://www.sciencedirect.com/science/article/pii/S0167642318303629&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://oslab.cs.tsinghua.edu.cn/debugopt/debugopt.html&quot;&gt;https://oslab.cs.tsinghua.edu.cn/debugopt/debugopt.html&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Eli Bendersky - &lt;a href=&quot;http://eli.thegreenplace.net/tag/debuggers&quot;&gt;http://eli.thegreenplace.net/tag/debuggers&lt;/a&gt; 
  &lt;ul&gt; 
   &lt;li&gt;How debuggers work 
    &lt;ul&gt; 
     &lt;li&gt;Part 1 - Basics - &lt;a href=&quot;http://eli.thegreenplace.net/2011/01/23/how-debuggers-work-part-1&quot;&gt;http://eli.thegreenplace.net/2011/01/23/how-debuggers-work-part-1&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;Part 2 - Breakpoints - &lt;a href=&quot;http://eli.thegreenplace.net/2011/01/27/how-debuggers-work-part-2-breakpoints&quot;&gt;http://eli.thegreenplace.net/2011/01/27/how-debuggers-work-part-2-breakpoints&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;Part 3 - Debugging information - &lt;a href=&quot;http://eli.thegreenplace.net/2011/02/07/how-debuggers-work-part-3-debugging-information&quot;&gt;http://eli.thegreenplace.net/2011/02/07/how-debuggers-work-part-3-debugging-information&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;An interesting tree serialization algorithm from DWARF - &lt;a href=&quot;https://eli.thegreenplace.net/2011/09/29/an-interesting-tree-serialization-algorithm-from-dwarf&quot;&gt;https://eli.thegreenplace.net/2011/09/29/an-interesting-tree-serialization-algorithm-from-dwarf&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;The contents of DWARF sections - &lt;a href=&quot;https://eli.thegreenplace.net/2011/12/26/the-contents-of-dwarf-sections&quot;&gt;https://eli.thegreenplace.net/2011/12/26/the-contents-of-dwarf-sections&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Programmatic access to the call stack in C++ - &lt;a href=&quot;https://eli.thegreenplace.net/2015/programmatic-access-to-the-call-stack-in-c/&quot;&gt;https://eli.thegreenplace.net/2015/programmatic-access-to-the-call-stack-in-c/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Fast, Flexible, Polyglot Instrumentation Support for Debuggers and other Tools 
  &lt;ul&gt; 
   &lt;li&gt;The Art, Science, and Engineering of Programming, 2018, Vol. 2, Issue 3, Article 14&lt;/li&gt; 
   &lt;li&gt;Van De Vanter, Michael; Seaton, Chris; Haupt, Michael; Humer, Christian; Würthinger, Thomas&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://programming-journal.org/2018/2/14/&quot;&gt;http://programming-journal.org/2018/2/14/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Framework for Instruction-level Tracing and Analysis of Program Executions 
  &lt;ul&gt; 
   &lt;li&gt;Virtual Execution Environments (VEE) 2006&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.usenix.org/legacy/events/vee06/full_papers/p154-bhansali.pdf&quot;&gt;https://www.usenix.org/legacy/events/vee06/full_papers/p154-bhansali.pdf&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;iDNA: Time Travel Debugging 
    &lt;ul&gt; 
     &lt;li&gt;Instruction-level Tracing: Framework &amp;amp; Applications&lt;/li&gt; 
     &lt;li&gt;Sanjay Bhansali&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;http://www.cs.wisc.edu/areas/pl/seminar/fall05/Bhansali.ppt&quot;&gt;http://www.cs.wisc.edu/areas/pl/seminar/fall05/Bhansali.ppt&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;GCC gOlogy: studying the impact of optimizations on debugging 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;http://www.fsfla.org/~lxoliva/writeups/gOlogy/gOlogy.txt&quot;&gt;http://www.fsfla.org/~lxoliva/writeups/gOlogy/gOlogy.txt&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;GNU Tools Cauldron 2018 slides: &lt;a href=&quot;http://people.redhat.com/aoliva/writeups/gOlogy/slides.pdf&quot;&gt;http://people.redhat.com/aoliva/writeups/gOlogy/slides.pdf&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;How breakpoints are set - &lt;a href=&quot;http://majantali.net/2016/10/how-breakpoints-are-set/&quot;&gt;http://majantali.net/2016/10/how-breakpoints-are-set/&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;How do debuggers keep track of the threads in your program? 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;http://timetobleed.com/how-do-debuggers-keep-track-of-the-threads-in-your-program/&quot;&gt;http://timetobleed.com/how-do-debuggers-keep-track-of-the-threads-in-your-program/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;How to code debuggers - Tomasz Wegrzanowski - &lt;a href=&quot;https://t-a-w.blogspot.com/2007/03/how-to-code-debuggers.html&quot;&gt;https://t-a-w.blogspot.com/2007/03/how-to-code-debuggers.html&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;Making a low level (Linux) debugger 
  &lt;ul&gt; 
   &lt;li&gt;part 1: assembly - &lt;a href=&quot;https://blog.asrpo.com/making_a_low_level_debugger&quot;&gt;https://blog.asrpo.com/making_a_low_level_debugger&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;part 2: C - &lt;a href=&quot;https://blog.asrpo.com/making_a_low_level_debugger_part_2&quot;&gt;https://blog.asrpo.com/making_a_low_level_debugger_part_2&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;part 3: our first program - &lt;a href=&quot;https://blog.asrpo.com/making_a_low_level_debugger_part_3&quot;&gt;https://blog.asrpo.com/making_a_low_level_debugger_part_3&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;On-Stack Replacement, Distilled 
  &lt;ul&gt; 
   &lt;li&gt;Programming Language Design and Implementation (PLDI) 2018&lt;/li&gt; 
   &lt;li&gt;Daniele Cono D&apos;Elia and Camil Demetrescu&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://pldi18.sigplan.org/event/pldi-2018-papers-on-stack-replacement-distilled&quot;&gt;https://pldi18.sigplan.org/event/pldi-2018-papers-on-stack-replacement-distilled&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://season-lab.github.io/papers/osr-distilled-pldi18.pdf&quot;&gt;http://season-lab.github.io/papers/osr-distilled-pldi18.pdf&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/dcdelia/tinyvm&quot;&gt;https://github.com/dcdelia/tinyvm&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&quot;As a novel application of OSR, we present a feasibility study on debugging of optimized code, showing how our techniques can be used to fix variables holding incorrect values at breakpoints due to optimizations.&quot;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Samy Al Bahra, Backtrace 
  &lt;ul&gt; 
   &lt;li&gt;Compiler debug quality suite - &lt;a href=&quot;https://github.com/backtrace-labs/cdqs&quot;&gt;https://github.com/backtrace-labs/cdqs&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Compile Once Debug Twice: Picking a Compiler for Debuggability 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://backtrace.io/blog/compile-once-debug-twice-picking-a-compiler-for-debuggability-1of3/&quot;&gt;https://backtrace.io/blog/compile-once-debug-twice-picking-a-compiler-for-debuggability-1of3/&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;Debugging the Debugger: Why Your Debugger Doesn’t Work When You Need it To 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://backtrace.io/debuggingthedebugger/&quot;&gt;https://backtrace.io/debuggingthedebugger/&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;Implementing a Debugger - Backtrace 
    &lt;ul&gt; 
     &lt;li&gt;The Fundamentals - &lt;a href=&quot;http://backtrace.io/blog/blog/2016/08/11/debugger-internals/&quot;&gt;http://backtrace.io/blog/blog/2016/08/11/debugger-internals/&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;Building a Go Debugger - &lt;a href=&quot;https://backtrace.io/blog/building-a-go-debugger/&quot;&gt;https://backtrace.io/blog/building-a-go-debugger/&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Writing a basic Windows debugger - &lt;a href=&quot;https://www.codeproject.com/Articles/43682/Writing-a-basic-Windows-debugger&quot;&gt;https://www.codeproject.com/Articles/43682/Writing-a-basic-Windows-debugger&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;Writing a Debugger - Joseph Kain - &lt;a href=&quot;http://system.joekain.com/debugger/&quot;&gt;http://system.joekain.com/debugger/&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;Writing a Linux Debugger - Simon Brand 
  &lt;ul&gt; 
   &lt;li&gt;1. Setup - &lt;a href=&quot;https://blog.tartanllama.xyz/writing-a-linux-debugger-setup/&quot;&gt;https://blog.tartanllama.xyz/writing-a-linux-debugger-setup/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;2. Breakpoints - &lt;a href=&quot;https://blog.tartanllama.xyz/writing-a-linux-debugger-breakpoints/&quot;&gt;https://blog.tartanllama.xyz/writing-a-linux-debugger-breakpoints/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;3. Registers and memory - &lt;a href=&quot;https://blog.tartanllama.xyz/writing-a-linux-debugger-registers/&quot;&gt;https://blog.tartanllama.xyz/writing-a-linux-debugger-registers/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;4. Elves and dwarves - &lt;a href=&quot;https://blog.tartanllama.xyz/writing-a-linux-debugger-elf-dwarf/&quot;&gt;https://blog.tartanllama.xyz/writing-a-linux-debugger-elf-dwarf/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;5. Source and signals - &lt;a href=&quot;https://blog.tartanllama.xyz/writing-a-linux-debugger-source-signal/&quot;&gt;https://blog.tartanllama.xyz/writing-a-linux-debugger-source-signal/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;6. Source-level stepping - &lt;a href=&quot;https://blog.tartanllama.xyz/writing-a-linux-debugger-dwarf-step/&quot;&gt;https://blog.tartanllama.xyz/writing-a-linux-debugger-dwarf-step/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;7. Source-level breakpoints - &lt;a href=&quot;https://blog.tartanllama.xyz/writing-a-linux-debugger-source-break/&quot;&gt;https://blog.tartanllama.xyz/writing-a-linux-debugger-source-break/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;8. Stack unwinding - &lt;a href=&quot;https://blog.tartanllama.xyz/writing-a-linux-debugger-unwinding/&quot;&gt;https://blog.tartanllama.xyz/writing-a-linux-debugger-unwinding/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;9. Handling variables - &lt;a href=&quot;https://blog.tartanllama.xyz/writing-a-linux-debugger-variables/&quot;&gt;https://blog.tartanllama.xyz/writing-a-linux-debugger-variables/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;10. Advanced topics - &lt;a href=&quot;https://blog.tartanllama.xyz/writing-a-linux-debugger-advanced-topics/&quot;&gt;https://blog.tartanllama.xyz/writing-a-linux-debugger-advanced-topics/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;minidbg: A mini x86 linux debugger for teaching purposes - &lt;a href=&quot;https://github.com/TartanLlama/minidbg&quot;&gt;https://github.com/TartanLlama/minidbg&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;(Windows) Data Breakpoints - &lt;a href=&quot;https://blogs.msdn.microsoft.com/reiley/2011/07/21/data-breakpoints/&quot;&gt;https://blogs.msdn.microsoft.com/reiley/2011/07/21/data-breakpoints/&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;(Windows) Side Effects of Debugger - &lt;a href=&quot;https://blogs.msdn.microsoft.com/reiley/2011/08/27/side-effects-of-debugger/&quot;&gt;https://blogs.msdn.microsoft.com/reiley/2011/08/27/side-effects-of-debugger/&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Correctness&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;Correctness Proofs of Compilers and Debuggers: an Approach Based on Structural Operational Semantics 
  &lt;ul&gt; 
   &lt;li&gt;1992 Ph.D. dissertation; Fabio Q. B. da Silva&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://hdl.handle.net/1842/13542&quot;&gt;http://hdl.handle.net/1842/13542&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://www.lfcs.inf.ed.ac.uk/reports/92/ECS-LFCS-92-241/&quot;&gt;http://www.lfcs.inf.ed.ac.uk/reports/92/ECS-LFCS-92-241/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Debug Information Validation for Optimized Code 
  &lt;ul&gt; 
   &lt;li&gt;PLDI 2020&lt;/li&gt; 
   &lt;li&gt;Yuanbo Li, Shuo Ding, Qirun Zhang, Davide Italiano&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://helloqirun.github.io/papers/pldi20_yuanbo1.pdf&quot;&gt;https://helloqirun.github.io/papers/pldi20_yuanbo1.pdf&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.cc.gatech.edu/~qrzhang/projects/debug/debug.html&quot;&gt;https://www.cc.gatech.edu/~qrzhang/projects/debug/debug.html&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://pldi20.sigplan.org/details/pldi-2020-papers/60/Debug-Information-Validation-for-Optimized-Code&quot;&gt;https://pldi20.sigplan.org/details/pldi-2020-papers/60/Debug-Information-Validation-for-Optimized-Code&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Testing&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;Comparing The Quality Of Debug Information Produced By Clang And GCC 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://robert.ocallahan.org/2018/11/comparing-quality-of-debug-information.html&quot;&gt;https://robert.ocallahan.org/2018/11/comparing-quality-of-debug-information.html&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;debuginfo-quality: Evaluate the quality of debuginfo in an ELF binary 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://github.com/rocallahan/debuginfo-quality&quot;&gt;https://github.com/rocallahan/debuginfo-quality&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Debug Frame Checking: Check &lt;code&gt;.eh_frame&lt;/code&gt; and &lt;code&gt;.debug_frame&lt;/code&gt; information 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/francesco-zappa-nardelli/eh_frame_check&quot;&gt;https://github.com/francesco-zappa-nardelli/eh_frame_check&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;DExTer (Debugging Experience Tester) 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/SNSystems/dexter&quot;&gt;https://github.com/SNSystems/dexter&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Measuring the User Debugging Experience 
    &lt;ul&gt; 
     &lt;li&gt;2018 European LLVM Developers Meeting; Greg Bedwell&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=XRT_GmpGjXE&quot;&gt;https://www.youtube.com/watch?v=XRT_GmpGjXE&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://llvm.org/devmtg/2018-04/slides/Bedwell-Measuring_the_User_Debugging_Experience.pdf&quot;&gt;https://llvm.org/devmtg/2018-04/slides/Bedwell-Measuring_the_User_Debugging_Experience.pdf&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;http://llvm.org/devmtg/2018-04/slides/Bedwell-Measuring_the_User_Debugging_Experience_poster.png&quot;&gt;http://llvm.org/devmtg/2018-04/slides/Bedwell-Measuring_the_User_Debugging_Experience_poster.png&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://www.snsystems.com/technology/tech-blog/measuring-the-user-debug-experience&quot;&gt;https://www.snsystems.com/technology/tech-blog/measuring-the-user-debug-experience&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Feedback-Directed Differential Testing of Interactive Debuggers 
  &lt;ul&gt; 
   &lt;li&gt;ESEC/FSE 2018&lt;/li&gt; 
   &lt;li&gt;Daniel Lehmann, Michael Pradel&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://software-lab.org/publications/fse2018.pdf&quot;&gt;http://software-lab.org/publications/fse2018.pdf&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/sola-da/DifferentialDebuggerTesting&quot;&gt;https://github.com/sola-da/DifferentialDebuggerTesting&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Interactive Metamorphic Testing of Debuggers 
  &lt;ul&gt; 
   &lt;li&gt;ISSTA 2019&lt;/li&gt; 
   &lt;li&gt;Sandro Tolksdorf, Daniel Lehmann, Michael Pradel&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://conf.researchr.org/event/issta-2019/issta-2019-technical-papers-interactive-metamorphic-testing-of-debuggers&quot;&gt;https://conf.researchr.org/event/issta-2019/issta-2019-technical-papers-interactive-metamorphic-testing-of-debuggers&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;lldb-repro: a utility to transparently capture and replay debugger sessions through the command line driver 
  &lt;ul&gt; 
   &lt;li&gt;used to test the reproducers by running the test suite twice&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/llvm/llvm-project/tree/master/lldb/utils/lldb-repro&quot;&gt;https://github.com/llvm/llvm-project/tree/master/lldb/utils/lldb-repro&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://lldb.llvm.org/resources/reproducers.html&quot;&gt;https://lldb.llvm.org/resources/reproducers.html&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Samy Al Bahra, Backtrace 
  &lt;ul&gt; 
   &lt;li&gt;Compiler debug quality suite - &lt;a href=&quot;https://github.com/backtrace-labs/cdqs&quot;&gt;https://github.com/backtrace-labs/cdqs&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Reverse Debugging&lt;/h2&gt; 
&lt;p&gt;See also: &lt;a href=&quot;#rr&quot;&gt;RR&lt;/a&gt;, &lt;a href=&quot;https://github.com/MattPD/cpplinks/blob/master/debugging.md#time-travel-debugging&quot;&gt;WinDbg - Time Travel Debugging&lt;/a&gt;&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;A Review of Reverse Debugging 
  &lt;ul&gt; 
   &lt;li&gt;System, Software, SoC and Silicon Debug Conference (S4D) 2012&lt;/li&gt; 
   &lt;li&gt;Jakob Engblom&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://ieeexplore.ieee.org/document/6338149/&quot;&gt;https://ieeexplore.ieee.org/document/6338149/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.338.3420&amp;amp;rep=rep1&amp;amp;type=pdf&quot;&gt;http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.338.3420&amp;amp;rep=rep1&amp;amp;type=pdf&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Don’t Panic: Reverse Debugging of Kernel Drivers 
  &lt;ul&gt; 
   &lt;li&gt;Foundations of Software Engineering (ESEC/FSE) 2015&lt;/li&gt; 
   &lt;li&gt;Pavel Dovgalyuk, Denis Dmitriev, Vladimir Makarov&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://dl.acm.org/citation.cfm?doid=2786805.2803179&quot;&gt;https://dl.acm.org/citation.cfm?doid=2786805.2803179&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Review (Jakob Engblom): Reverse Debug with Hardware in the Loop - &lt;a href=&quot;http://jakob.engbloms.se/archives/2432&quot;&gt;http://jakob.engbloms.se/archives/2432&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Efficient Algorithms for Bidirectional Debugging 
  &lt;ul&gt; 
   &lt;li&gt;Programming Language Design and Implementation (PLDI) 2000&lt;/li&gt; 
   &lt;li&gt;B. Boothe&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://dl.acm.org/citation.cfm?id=349339&quot;&gt;https://dl.acm.org/citation.cfm?id=349339&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Expositor: Scriptable Time-Travel Debugging with First Class Traces 
  &lt;ul&gt; 
   &lt;li&gt;International Conference on Software Engineering (ICSE) 2013&lt;/li&gt; 
   &lt;li&gt;Yit Phang Khoo, Jeffrey S. Foster, Michael Hicks&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://www.cs.umd.edu/~mwh/papers/khoo13expositor.html&quot;&gt;http://www.cs.umd.edu/~mwh/papers/khoo13expositor.html&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;full version - &lt;a href=&quot;http://www.cs.umd.edu/~mwh/papers/khoo13expositor-journal.html&quot;&gt;http://www.cs.umd.edu/~mwh/papers/khoo13expositor-journal.html&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Scriptable time-travel debugging Python library for GDB/UndoDB 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://bitbucket.org/khooyp/expositor/src/default/&quot;&gt;https://bitbucket.org/khooyp/expositor/src/default/&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Improving the performance of reverse debugging 
  &lt;ul&gt; 
   &lt;li&gt;Programming and Computer Software 43(1) 2017&lt;/li&gt; 
   &lt;li&gt;Klimushenkova, M.A. &amp;amp; Dovgalyuk, P.M.&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://link.springer.com/article/10.1134/S0361768817010042&quot;&gt;https://link.springer.com/article/10.1134/S0361768817010042&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;POMP: Postmortem Program Analysis with Hardware-Enhanced Post-Crash Artifacts 
  &lt;ul&gt; 
   &lt;li&gt;USENIX Security 2017&lt;/li&gt; 
   &lt;li&gt;Jun Xu, Dongliang Mu, Xinyu Xing, Peng Liu, Ping Chen, Bing Mao&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.usenix.org/conference/usenixsecurity17/technical-sessions/presentation/xu-jun&quot;&gt;https://www.usenix.org/conference/usenixsecurity17/technical-sessions/presentation/xu-jun&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/junxzm1990/pomp&quot;&gt;https://github.com/junxzm1990/pomp&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;REPT: Reverse Debugging of Failures in Deployed Software 
  &lt;ul&gt; 
   &lt;li&gt;USENIX Symposium on Operating Systems Design and Implementation (OSDI) 2018&lt;/li&gt; 
   &lt;li&gt;Weidong Cui, Xinyang Ge, Baris Kasikci, Ben Niu, Upamanyu Sharma, Ruoyu Wang, Insu Yun&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.usenix.org/conference/osdi18/presentation/weidong&quot;&gt;https://www.usenix.org/conference/osdi18/presentation/weidong&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.microsoft.com/en-us/research/publication/rept-reverse-debugging-of-failures-in-deployed-software/&quot;&gt;https://www.microsoft.com/en-us/research/publication/rept-reverse-debugging-of-failures-in-deployed-software/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Reverse History 
  &lt;ul&gt; 
   &lt;li&gt;Part One – Background - &lt;a href=&quot;http://jakob.engbloms.se/archives/1547&quot;&gt;http://jakob.engbloms.se/archives/1547&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Part Two – Research - &lt;a href=&quot;http://jakob.engbloms.se/archives/1554&quot;&gt;http://jakob.engbloms.se/archives/1554&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Part Three – Products - &lt;a href=&quot;http://jakob.engbloms.se/archives/1564&quot;&gt;http://jakob.engbloms.se/archives/1564&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Transition Watchpoints: Teaching Old Debuggers New Tricks 
  &lt;ul&gt; 
   &lt;li&gt;The Art, Science, and Engineering of Programming, 2017, Vol. 1, Issue 2, Article 16&lt;/li&gt; 
   &lt;li&gt;Kapil Arya, Tyler Denniston, Ariel Rabkin, Gene Cooperman&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://programming-journal.org/2017/1/16/&quot;&gt;http://programming-journal.org/2017/1/16/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Software Engineering&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;A Survey on Software Fault Localization 
  &lt;ul&gt; 
   &lt;li&gt;IEEE Transactions on Software Engineering 42(8) (2016)&lt;/li&gt; 
   &lt;li&gt;W. Eric Wong, Ruizhi Gao, Yihao Li, Rui Abreu, Franz Wotawa&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.researchgate.net/publication/291951202_A_Survey_on_Software_Fault_Localization&quot;&gt;https://www.researchgate.net/publication/291951202_A_Survey_on_Software_Fault_Localization&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Are Automated Debugging Techniques Actually Helping Programmers? 
  &lt;ul&gt; 
   &lt;li&gt;International Symposium on Software Testing and Analysis (ISSTA) 2011&lt;/li&gt; 
   &lt;li&gt;Chris Parnin, Alessandro Orso&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://dl.acm.org/citation.cfm?id=2001445&quot;&gt;https://dl.acm.org/citation.cfm?id=2001445&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Automated Debugging: Are We There Yet? 
  &lt;ul&gt; 
   &lt;li&gt;International Conference on Software Testing, Verification and Validation Workshops (ICSTW) 2011&lt;/li&gt; 
   &lt;li&gt;Alex Orso&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://ieeexplore.ieee.org/document/5954471/&quot;&gt;http://ieeexplore.ieee.org/document/5954471/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;2013 talk 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://www.slideshare.net/alexorso/20130204dagstuhl-alex-orso&quot;&gt;https://www.slideshare.net/alexorso/20130204dagstuhl-alex-orso&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://pdfs.semanticscholar.org/2436/0dc1bd271dcf3ecb73622e2c7b1d54a008bf.pdf&quot;&gt;https://pdfs.semanticscholar.org/2436/0dc1bd271dcf3ecb73622e2c7b1d54a008bf.pdf&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=WJHQnzLpVXk&quot;&gt;https://www.youtube.com/watch?v=WJHQnzLpVXk&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Debugging Reinvented: Asking and Answering Why and Why Not Questions about Program Behavior 
  &lt;ul&gt; 
   &lt;li&gt;International Conference on Software Engineering ICSE 2008&lt;/li&gt; 
   &lt;li&gt;Andrew J. Ko, Brad A. Myers 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.159.1425&quot;&gt;http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.159.1425&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://dl.acm.org/citation.cfm?id=1368130&quot;&gt;https://dl.acm.org/citation.cfm?id=1368130&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;Microsoft Research Talk: 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://www.microsoft.com/en-us/research/video/candidate-talk-debugging-reinvented-asking-and-answering-why-and-why-not-questions-about-program-behavior/&quot;&gt;https://www.microsoft.com/en-us/research/video/candidate-talk-debugging-reinvented-asking-and-answering-why-and-why-not-questions-about-program-behavior/&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=ScZfggGa4qs&quot;&gt;https://www.youtube.com/watch?v=ScZfggGa4qs&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://archive.org/details/Microsoft_Research_Video_103778&quot;&gt;https://archive.org/details/Microsoft_Research_Video_103778&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;&quot;Static and dynamic program slicing algorithms for extracting and answering developers questions about program output that substantially decrease fault localization time.&quot;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://blog.acolyer.org/2014/10/17/debugging-reinvented/&quot;&gt;https://blog.acolyer.org/2014/10/17/debugging-reinvented/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;On The Dichotomy of Debugging Behavior Among Programmers 
  &lt;ul&gt; 
   &lt;li&gt;ICSE 2018&lt;/li&gt; 
   &lt;li&gt;Moritz Beller, Niels Spruit, Diomidis Spinellis, Andy Zaidman&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://pure.tudelft.nl/ws/files/38319543/paper.pdf&quot;&gt;http://pure.tudelft.nl/ws/files/38319543/paper.pdf&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Where Is the Bug and How Is It Fixed? An Experiment with Practitioners 
  &lt;ul&gt; 
   &lt;li&gt;European Software Engineering Conference / Foundations of Software Engineering (ESEC/FSE) 2017&lt;/li&gt; 
   &lt;li&gt;Marcel Böhme, Ezekiel O. Soremekun, Sudipta Chattopadhyay, Emamurho Ugherughe, Andreas Zeller&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://doi.org/10.1145/3106237.3106255&quot;&gt;https://doi.org/10.1145/3106237.3106255&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.comp.nus.edu.sg/~mboehme/paper/FSE17.pdf&quot;&gt;https://www.comp.nus.edu.sg/~mboehme/paper/FSE17.pdf&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;DBGBench - &lt;a href=&quot;https://dbgbench.github.io/&quot;&gt;https://dbgbench.github.io/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&quot;the correct fault locations, bug diagnoses, and software patches of 27 real errors in open-source C projects that were consolidated from hundreds of debugging sessions of professional software engineers&quot;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Transparency&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;2017 - Ninja: Towards Transparent Tracing and Debugging on ARM 
  &lt;ul&gt; 
   &lt;li&gt;USENIX Security 2017&lt;/li&gt; 
   &lt;li&gt;Zhenyu Ning, Fengwei Zhang&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.usenix.org/conference/usenixsecurity17/technical-sessions/presentation/ning&quot;&gt;https://www.usenix.org/conference/usenixsecurity17/technical-sessions/presentation/ning&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://www.cs.wayne.edu/fengwei/paper/ninja-usenixsecurity17.pdf&quot;&gt;http://www.cs.wayne.edu/fengwei/paper/ninja-usenixsecurity17.pdf&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;2016 - Towards Transparent Debugging 
  &lt;ul&gt; 
   &lt;li&gt;IEEE Transactions on Dependable and Secure Computing (TDSC&apos;16), 2016.&lt;/li&gt; 
   &lt;li&gt;Fengwei Zhang, Kevin Leach, Angelos Stavrou, and Haining Wang&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://www.cs.wayne.edu/fengwei/paper/malt-tdsc16.pdf&quot;&gt;http://www.cs.wayne.edu/fengwei/paper/malt-tdsc16.pdf&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;2015 - Using Hardware Features for Increased Debugging Transparency 
  &lt;ul&gt; 
   &lt;li&gt;36th IEEE Symposium on Security and Privacy (S&amp;amp;P&apos;15), 2015&lt;/li&gt; 
   &lt;li&gt;Fengwei Zhang, Kevin Leach, Angelos Stavrou, Haining Wang, and Kun Sun&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://www.cs.wayne.edu/fengwei/paper/malt-sp15.pdf&quot;&gt;http://www.cs.wayne.edu/fengwei/paper/malt-sp15.pdf&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;hr&gt; 
&lt;h1&gt;Software&lt;/h1&gt; 
&lt;ul&gt; 
 &lt;li&gt;dbg: A macro for printf-style debugging fans 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/sharkdp/dbg-macro&quot;&gt;https://github.com/sharkdp/dbg-macro&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;LibVMI: Simplified Virtual Machine Introspection 
  &lt;ul&gt; 
   &lt;li&gt;&quot;LibVMI is a virtual machine introspection library. This means that it helps you access the memory of a running virtual machine. LibVMI provides primitives for accessing this memory using physical or virtual addresses and kernel symbols. LibVMI also supports accessing memory from a physical memory snapshot, which is helpful for debugging or forensic analysis.&quot;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/libvmi/libvmi&quot;&gt;https://github.com/libvmi/libvmi&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;PulseDbg: Hypervisor-based debugger 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/honorarybot/PulseDBG&quot;&gt;https://github.com/honorarybot/PulseDBG&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;PyREBox: a Python scriptable Reverse Engineering sandbox 
  &lt;ul&gt; 
   &lt;li&gt;&quot;It is based on QEMU, and its goal is to aid reverse engineering by providing dynamic analysis and debugging capabilities from a different perspective. PyREBox allows to inspect a running QEMU VM, modify its memory or registers, and to instrument its execution, by creating simple scripts in python to automate any kind of analysis. QEMU (when working as a whole-system-emulator) emulates a complete system (CPU, memory, devices...). By using VMI techniques, it does not require to perform any modification into the guest operating system, as it transparently retrieves information from its memory at run-time.&quot;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/Cisco-Talos/pyrebox&quot;&gt;https://github.com/Cisco-Talos/pyrebox&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://blog.talosintelligence.com/2017/07/pyrebox.html&quot;&gt;http://blog.talosintelligence.com/2017/07/pyrebox.html&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;pyvmidbg: LibVMI-based debug server, implemented in Python 
  &lt;ul&gt; 
   &lt;li&gt;Building a guest aware, stealth and agentless full-system debugger&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/Wenzel/pyvmidbg&quot;&gt;https://github.com/Wenzel/pyvmidbg&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Building a Flexible Hypervisor-Level Debugger 
    &lt;ul&gt; 
     &lt;li&gt;Insomni&apos;hack 2019; Mathieu Tarral&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://drive.google.com/open?id=1ZMUszfwWDOljdDfPOJgkEfSabNy0UAJR&quot;&gt;https://drive.google.com/open?id=1ZMUszfwWDOljdDfPOJgkEfSabNy0UAJR&lt;/a&gt;&lt;br&gt; ‏* QIRA - QEMU Interactive Runtime Analyser&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://qira.me/&quot;&gt;http://qira.me/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/BinaryAnalysisPlatform/qira/&quot;&gt;https://github.com/BinaryAnalysisPlatform/qira/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Radare2 
  &lt;ul&gt; 
   &lt;li&gt;Radare project started as a forensics tool, a scriptable commandline hexadecimal editor able to open disk files, but later support for analyzing binaries, disassembling code, debugging programs, attaching to remote gdb servers, etc.&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://www.radare.org/&quot;&gt;http://www.radare.org/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/radare/radare2&quot;&gt;https://github.com/radare/radare2&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;r2vmi: Hypervisor-Level Debugger based on Radare2 / LibVMI, using VMI IO and debug plugins 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://github.com/Wenzel/r2vmi&quot;&gt;https://github.com/Wenzel/r2vmi&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;Hack.lu 2018: Hypervisor-Level Debugger: Benefits And Challenges - Mathieu Tarral 
      &lt;ul&gt; 
       &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=NnWYT-kCx_s&quot;&gt;https://www.youtube.com/watch?v=NnWYT-kCx_s&lt;/a&gt;&lt;/li&gt; 
      &lt;/ul&gt; &lt;/li&gt; 
     &lt;li&gt;r2con2018 - Hypervisor Level Debugger with r2 - Mathieu Tarral 
      &lt;ul&gt; 
       &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=JOJMgWa7E6A&quot;&gt;https://www.youtube.com/watch?v=JOJMgWa7E6A&lt;/a&gt;&lt;/li&gt; 
       &lt;li&gt;&lt;a href=&quot;https://github.com/radareorg/r2con2018/tree/master/talks/10-hypervisor-level-debugger&quot;&gt;https://github.com/radareorg/r2con2018/tree/master/talks/10-hypervisor-level-debugger&lt;/a&gt;&lt;/li&gt; 
      &lt;/ul&gt; &lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;ret-sync: Reverse-Engineering Tools SYNChronization 
  &lt;ul&gt; 
   &lt;li&gt;A set of plugins to synchronize a debugging session (WinDbg/GDB/LLDB/OllyDbg/OllyDbg2/x64dbg) with IDA/Ghidra disassemblers.&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/bootleg/ret-sync&quot;&gt;https://github.com/bootleg/ret-sync&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;rVMI - A New Paradigm For Full System Analysis 
  &lt;ul&gt; 
   &lt;li&gt;&quot;rVMI is a debugger on steroids. It leverages Virtual Machine Introspection (VMI) and memory forensics to provide full system analysis. This means that an analyst can inspect userspace processes, kernel drivers, and preboot environments in a single tool.&quot;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/fireeye/rVMI&quot;&gt;https://github.com/fireeye/rVMI&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.fireeye.com/blog/threat-research/2017/09/rvmi-full-system-analysis.html&quot;&gt;https://www.fireeye.com/blog/threat-research/2017/09/rvmi-full-system-analysis.html&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Black Hat USA 2017 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://www.blackhat.com/docs/us-17/thursday/us-17-Pfoh-rVMI-A-New-Paradigm-For-Full-System-Analysis.pdf&quot;&gt;https://www.blackhat.com/docs/us-17/thursday/us-17-Pfoh-rVMI-A-New-Paradigm-For-Full-System-Analysis.pdf&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=KtoipviVJjw&quot;&gt;https://www.youtube.com/watch?v=KtoipviVJjw&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Vivisect / Vdb / Vtrace 
  &lt;ul&gt; 
   &lt;li&gt;Vivisect - interactive disassembler&lt;/li&gt; 
   &lt;li&gt;Vtrace - a cross-platform &amp;amp; cross-architecture debugging API&lt;/li&gt; 
   &lt;li&gt;VDB - a cross-platform &amp;amp; cross-architecture debugger using Vtrace&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://visi.kenshoto.com/viki/MainPage&quot;&gt;http://visi.kenshoto.com/viki/MainPage&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/vivisect/vivisect&quot;&gt;https://github.com/vivisect/vivisect&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;documentation: &lt;a href=&quot;http://fitblip.pub/vdb-fork/sphinx/&quot;&gt;http://fitblip.pub/vdb-fork/sphinx/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;fork &amp;amp; documentation: &lt;a href=&quot;http://fitblip.pub/vdb-fork/&quot;&gt;http://fitblip.pub/vdb-fork/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Using a Custom VDB Debugger for Exploit Analysis - &lt;a href=&quot;https://www.fireeye.com/blog/threat-research/2013/02/custom-vdb-debugger-exploit-analysis.html&quot;&gt;https://www.fireeye.com/blog/threat-research/2013/02/custom-vdb-debugger-exploit-analysis.html&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Malware Analysis with Vivisect - NEST - &lt;a href=&quot;http://nest.unm.edu/files/5514/1254/9114/Malware_Analysis_with_Vivsect.pdf&quot;&gt;http://nest.unm.edu/files/5514/1254/9114/Malware_Analysis_with_Vivsect.pdf&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Binary Vivisection 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://www.singlehop.com/blog/binary-vivisection-part-1/&quot;&gt;https://www.singlehop.com/blog/binary-vivisection-part-1/&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://www.singlehop.com/blog/binary-vivisection-part-2/&quot;&gt;https://www.singlehop.com/blog/binary-vivisection-part-2/&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://www.singlehop.com/blog/binary-vivisection-part-3/&quot;&gt;https://www.singlehop.com/blog/binary-vivisection-part-3/&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;FireEye Labs Query-Oriented Debugger 
    &lt;ul&gt; 
     &lt;li&gt;Command-line and Python debugger for instrumenting and modifying native software behavior on Windows and Linux&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://github.com/fireeye/flare-qdb&quot;&gt;https://github.com/fireeye/flare-qdb&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;Querying Dynamic State using the FireEye Labs Query-Oriented Debugger (flare-qdb) 
      &lt;ul&gt; 
       &lt;li&gt;&lt;a href=&quot;https://www.fireeye.com/blog/threat-research/2017/01/flare_script_series.html&quot;&gt;https://www.fireeye.com/blog/threat-research/2017/01/flare_script_series.html&lt;/a&gt;&lt;/li&gt; 
      &lt;/ul&gt; &lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Voltron - &lt;a href=&quot;https://github.com/snare/voltron&quot;&gt;https://github.com/snare/voltron&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;xendbg - A modern Xen debugger 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/nccgroup/xendbg&quot;&gt;https://github.com/nccgroup/xendbg&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&quot;&lt;code&gt;xendbg&lt;/code&gt; is a feature-complete reference implementation of a modern Xen VMI debugger, superseding Xen&apos;s own limited and rarely-maintained &lt;a href=&quot;https://github.com/mirage/xen/tree/master/tools/debugger/gdbsx&quot;&gt;&lt;code&gt;gdbsx&lt;/code&gt;&lt;/a&gt;. It can debug both paravirtualized (PV) and hardware virtualized (HVM) guests, and provides both a standalone REPL and an LLDB server mode.&quot;&lt;/li&gt; 
   &lt;li&gt;Xendbg: A Full-Featured Debugger for the Xen Hypervisor 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://www.nccgroup.trust/us/about-us/newsroom-and-events/blog/2019/january/xendbg-a-full-featured-debugger-for-the-xen-hypervisor/&quot;&gt;https://www.nccgroup.trust/us/about-us/newsroom-and-events/blog/2019/january/xendbg-a-full-featured-debugger-for-the-xen-hypervisor/&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;GDB&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;GDB: The GNU Project Debugger 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://sourceware.org/gdb/&quot;&gt;https://sourceware.org/gdb/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://sourceware.org/gdb/documentation/&quot;&gt;https://sourceware.org/gdb/documentation/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://sourceware.org/gdb/wiki/&quot;&gt;https://sourceware.org/gdb/wiki/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;GDB - The Architecture of Open Source Applications - Stan Shebs 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;http://aosabook.org/en/gdb.html&quot;&gt;http://aosabook.org/en/gdb.html&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Projects&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;CGDB: Console front-end to the GNU debugger 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/cgdb/cgdb&quot;&gt;https://github.com/cgdb/cgdb&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Gdb Assembly Informant 
  &lt;ul&gt; 
   &lt;li&gt;steps through your assembly code one instruction at a time and diffs register values&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/thlorenz/gai&quot;&gt;https://github.com/thlorenz/gai&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;GDB dashboard 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/cyrus-and/gdb-dashboard&quot;&gt;https://github.com/cyrus-and/gdb-dashboard&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://metricpanda.com/tips-for-productive-debugging-with-gdb&quot;&gt;https://metricpanda.com/tips-for-productive-debugging-with-gdb&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;GDB helper scripts 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/tromey/gdb-helpers&quot;&gt;https://github.com/tromey/gdb-helpers&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;gdb-gui: A gdb gui written in Python, running inside gdb itself 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/tromey/gdb-gui&quot;&gt;https://github.com/tromey/gdb-gui&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;gdb-helpers: GDB helper scripts 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/tromey/gdb-helpers&quot;&gt;https://github.com/tromey/gdb-helpers&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;gdb-tools: Various tools to improve the gdb experience 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/vuvova/gdb-tools&quot;&gt;https://github.com/vuvova/gdb-tools&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;gdb tools: duel and @PrettyPrinter - &lt;a href=&quot;https://fosdem.org/2018/schedule/event/debugging_tools_gdb_tools/&quot;&gt;https://fosdem.org/2018/schedule/event/debugging_tools_gdb_tools/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;gdb-walkers: Bring mdb walkers to gdb, also add other helpful commands. 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/hardenedapple/gdb-walkers&quot;&gt;https://github.com/hardenedapple/gdb-walkers&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;GDB pipelines -- convenience iteration over inferior data structures 
    &lt;ul&gt; 
     &lt;li&gt;Bringing MDB&apos;s &quot;walkers&quot; to GDB&lt;/li&gt; 
     &lt;li&gt;FOSDEM 2020; Matthew Malcomson&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://fosdem.org/2020/schedule/event/debugging_gdb_pipelines/&quot;&gt;https://fosdem.org/2020/schedule/event/debugging_gdb_pipelines/&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;GDBFrontend 
  &lt;ul&gt; 
   &lt;li&gt;&quot;an easy, flexible and extensionable gui debugger&quot;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/rohanrhu/gdb-frontend&quot;&gt;https://github.com/rohanrhu/gdb-frontend&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;gdbgui: A browser-based frontend for GDB 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://gdbgui.com/&quot;&gt;https://gdbgui.com/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/cs01/gdbgui&quot;&gt;https://github.com/cs01/gdbgui&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;GdbShellPipe: Enable piping of internal command output to external commands 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/hq6/GdbShellPipe&quot;&gt;https://github.com/hq6/GdbShellPipe&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;GDBundle: Plugin Manager for GDB and LLDB 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/memfault/gdbundle&quot;&gt;https://github.com/memfault/gdbundle&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;gdbundle - GDB and LLDB&apos;s Missing Plugin Manager 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://interrupt.memfault.com/blog/gdbundle-plugin-manager&quot;&gt;https://interrupt.memfault.com/blog/gdbundle-plugin-manager&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Gede: a graphical frontend (GUI) to GDB written in Qt 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;http://gede.acidron.com/&quot;&gt;http://gede.acidron.com/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;mirror: &lt;a href=&quot;https://github.com/Nanoseb/gede&quot;&gt;https://github.com/Nanoseb/gede&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;GEF (GDB Enhanced Features) 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/hugsy/gef&quot;&gt;https://github.com/hugsy/gef&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/hugsy/gef-scripts&quot;&gt;https://github.com/hugsy/gef-scripts&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/hugsy/gef-structs&quot;&gt;https://github.com/hugsy/gef-structs&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;GEF Tutorials - &lt;a href=&quot;https://www.youtube.com/playlist?list=PLjAuO31Rg972WeMvdR_57Qu-aVM8T6DkQ&quot;&gt;https://www.youtube.com/playlist?list=PLjAuO31Rg972WeMvdR_57Qu-aVM8T6DkQ&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://blahcat.github.io/2017/08/01/gef-at-black-hat-arsenal-us-2017/&quot;&gt;https://blahcat.github.io/2017/08/01/gef-at-black-hat-arsenal-us-2017/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/toolswatch/blackhat-arsenal-tools/blob/master/exploitation/gef.md&quot;&gt;https://github.com/toolswatch/blackhat-arsenal-tools/blob/master/exploitation/gef.md&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;libdebugme: Automatically drop to gdb on error 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/yugr/libdebugme&quot;&gt;https://github.com/yugr/libdebugme&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;OnlineGDB 
  &lt;ul&gt; 
   &lt;li&gt;&quot;OnlineGDB an online compiler and debugger tool for C/C++ languages. It is world&apos;s first online IDE which gives debugging facility with embedded gdb.&quot;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://OnlineGDB.com&quot;&gt;http://OnlineGDB.com&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;PEDA - Python Exploit Development Assistance for GDB 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/longld/peda&quot;&gt;https://github.com/longld/peda&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://eugenekolo.com/blog/better-disassembly-with-gdb-peda/&quot;&gt;https://eugenekolo.com/blog/better-disassembly-with-gdb-peda/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://ropshell.com/peda/Linux_Interactive_Exploit_Development_with_GDB_and_PEDA_Slides.pdf&quot;&gt;http://ropshell.com/peda/Linux_Interactive_Exploit_Development_with_GDB_and_PEDA_Slides.pdf&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;PINCE: front-end reverse engineering tool for the GDB - &lt;a href=&quot;https://github.com/korcankaraokcu/PINCE&quot;&gt;https://github.com/korcankaraokcu/PINCE&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;pwndbg - Exploit Development and Reverse Engineering with GDB Made Easy 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/pwndbg/pwndbg&quot;&gt;https://github.com/pwndbg/pwndbg&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/pwndbg/pwndbg/blob/dev/FEATURES.md&quot;&gt;https://github.com/pwndbg/pwndbg/blob/dev/FEATURES.md&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Pwngdb - &lt;a href=&quot;https://github.com/scwuaptx/Pwngdb&quot;&gt;https://github.com/scwuaptx/Pwngdb&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;pygdbmi - Get Structured Output from GDB&apos;s Machine Interface - &lt;a href=&quot;https://github.com/cs01/pygdbmi&quot;&gt;https://github.com/cs01/pygdbmi&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;QuickPatch: a GDB plug-in to patch an ELF file 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/invictus1306/QuickPatch&quot;&gt;https://github.com/invictus1306/QuickPatch&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://invictus1306.github.io/vulnerabilities/2019/10/20/quickpatch.html&quot;&gt;https://invictus1306.github.io/vulnerabilities/2019/10/20/quickpatch.html&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;SymGDB - symbolic execution plugin for gdb - &lt;a href=&quot;https://github.com/SQLab/symgdb&quot;&gt;https://github.com/SQLab/symgdb&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Editor Integration&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;GDB-MI: a package by Nick Roberts which makes Emacs use GDB/MI interface to talk with the GNU Debugger 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.emacswiki.org/emacs/GDB-MI&quot;&gt;https://www.emacswiki.org/emacs/GDB-MI&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;GDB graphical interface for GNU Emacs 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/weirdNox/emacs-gdb&quot;&gt;https://github.com/weirdNox/emacs-gdb&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Native Debug 
  &lt;ul&gt; 
   &lt;li&gt;GDB &amp;amp; LLDB Debugger support for VSCode&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://marketplace.visualstudio.com/items?itemName=webfreak.debug&quot;&gt;https://marketplace.visualstudio.com/items?itemName=webfreak.debug&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/WebFreak001/code-debug&quot;&gt;https://github.com/WebFreak001/code-debug&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;neogdb.vim: Vim GDB front-end for neovim 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/huawenyu/neogdb.vim&quot;&gt;https://github.com/huawenyu/neogdb.vim&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;RealGUD: An extensible, modular GNU Emacs front-end for interacting with external debuggers 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/realgud/realgud&quot;&gt;https://github.com/realgud/realgud&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Memory Debugging&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;pahole-gdb: pahole implementation for gdb - &lt;a href=&quot;https://github.com/PhilArmstrong/pahole-gdb&quot;&gt;https://github.com/PhilArmstrong/pahole-gdb&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;gdb-heap 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/rogerhu/gdb-heap&quot;&gt;https://github.com/rogerhu/gdb-heap&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://fedorahosted.org/gdb-heap/&quot;&gt;https://fedorahosted.org/gdb-heap/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://fedoraproject.org/wiki/Features/MemoryDebuggingTools&quot;&gt;https://fedoraproject.org/wiki/Features/MemoryDebuggingTools&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Plotting&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;GDBplotlib: Plotting and exporting of variables from GDB 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/X-Neon/gdbplotlib&quot;&gt;https://github.com/X-Neon/gdbplotlib&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;gdb-plot 
  &lt;ul&gt; 
   &lt;li&gt;a set of utils for: plotting from the gdb command line, saving c data to .mat files from gdb command line, exploring the stack frame&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/bthcode/gdb-plot&quot;&gt;https://github.com/bthcode/gdb-plot&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Profiling&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;gdbpmp: A GDB Based Wallclock Profiler - &lt;a href=&quot;https://github.com/markhpc/gdbpmp&quot;&gt;https://github.com/markhpc/gdbpmp&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;gdbprof: A wall clock time-based profiler built on GDB&apos;s Python interface 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/Muon/gdbprof&quot;&gt;https://github.com/Muon/gdbprof&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/markhpc/gdbprof&quot;&gt;https://github.com/markhpc/gdbprof&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;GDB profiler: Rich man&apos;s profiler, a profiler for native OCaml and other executables 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/copy/gdbprofiler&quot;&gt;https://github.com/copy/gdbprofiler&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Readings&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;8 gdb tricks you should know - &lt;a href=&quot;https://blogs.oracle.com/ksplice/8-gdb-tricks-you-should-know&quot;&gt;https://blogs.oracle.com/ksplice/8-gdb-tricks-you-should-know&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;Beej&apos;s Quick Guide to GDB - &lt;a href=&quot;https://beej.us/guide/bggdb/&quot;&gt;https://beej.us/guide/bggdb/&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;Cheatsheet - &lt;a href=&quot;https://github.com/jshaw87/Cheatsheets/blob/master/Cheatsheet_GDB.txt&quot;&gt;https://github.com/jshaw87/Cheatsheets/blob/master/Cheatsheet_GDB.txt&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;Displaying Stack Frames in gdb with Python - &lt;a href=&quot;http://jefftrull.github.io/c++/gdb/python/2018/03/02/print-frame.html&quot;&gt;http://jefftrull.github.io/c++/gdb/python/2018/03/02/print-frame.html&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;Fast Tracing with GDB - &lt;a href=&quot;https://suchakra.wordpress.com/2016/06/29/fast-tracing-with-gdb/&quot;&gt;https://suchakra.wordpress.com/2016/06/29/fast-tracing-with-gdb/&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;GDB Basics Tutorial 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://platform.avatao.com/paths/a0dc20fc-f1b5-43c9-89fc-3a5fccfb5f0b/challenges/166366b3-2e89-49ee-86a3-023663d197b7&quot;&gt;https://platform.avatao.com/paths/a0dc20fc-f1b5-43c9-89fc-3a5fccfb5f0b/challenges/166366b3-2e89-49ee-86a3-023663d197b7&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;GDB Custom Commands: Dynamic Arrays 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://testfit.io/devblog/gdb_custom_commands_dynamic_arrays&quot;&gt;https://testfit.io/devblog/gdb_custom_commands_dynamic_arrays&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;GDB Debugging Automation with Python: Implementing a memory leak detector - &lt;a href=&quot;https://nativecoding.wordpress.com/2016/07/31/gdb-debugging-automation-with-python/&quot;&gt;https://nativecoding.wordpress.com/2016/07/31/gdb-debugging-automation-with-python/&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;gdb Debugging Full Example (Tutorial): ncurses - &lt;a href=&quot;http://www.brendangregg.com/blog/2016-08-09/gdb-example-ncurses.html&quot;&gt;http://www.brendangregg.com/blog/2016-08-09/gdb-example-ncurses.html&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;GDB scripting and Indirect functions 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://fasterthanli.me/blog/2020/gdb-scripting-and-indirect-functions/&quot;&gt;https://fasterthanli.me/blog/2020/gdb-scripting-and-indirect-functions/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;GDB Tips and Tricks - Shane Kirk 
  &lt;ul&gt; 
   &lt;li&gt;1: A Tale of Two Terminals - &lt;a href=&quot;http://www.shanekirk.com/2017/08/gdb-tips-and-tricks-1-a-tale-of-two-terminals/&quot;&gt;http://www.shanekirk.com/2017/08/gdb-tips-and-tricks-1-a-tale-of-two-terminals/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;2: Setting Breakpoints with Regular Expressions - &lt;a href=&quot;http://www.shanekirk.com/2017/08/gdb-tips-and-tricks-2-setting-breakpoints-with-regular-expressions/&quot;&gt;http://www.shanekirk.com/2017/08/gdb-tips-and-tricks-2-setting-breakpoints-with-regular-expressions/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;3: Saving and Restoring Breakpoints Using Files - &lt;a href=&quot;http://www.shanekirk.com/2017/09/gdb-tips-and-tricks-3-saving-and-restoring-breakpoints-using-files/&quot;&gt;http://www.shanekirk.com/2017/09/gdb-tips-and-tricks-3-saving-and-restoring-breakpoints-using-files/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;4: Reverse Debugging - &lt;a href=&quot;http://www.shanekirk.com/2017/10/gdb-tips-and-tricks-4-reverse-debugging/&quot;&gt;http://www.shanekirk.com/2017/10/gdb-tips-and-tricks-4-reverse-debugging/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;5: The Display Command - &lt;a href=&quot;http://www.shanekirk.com/2017/12/gdb-tips-and-tricks-5-the-display-command/&quot;&gt;http://www.shanekirk.com/2017/12/gdb-tips-and-tricks-5-the-display-command/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;6: Examining Data Types - &lt;a href=&quot;http://www.shanekirk.com/2018/02/gdb-tips-and-tricks-6-examining-data-types/&quot;&gt;http://www.shanekirk.com/2018/02/gdb-tips-and-tricks-6-examining-data-types/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;GDB Tutorial - &lt;a href=&quot;https://www.gdb-tutorial.net/&quot;&gt;https://www.gdb-tutorial.net/&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;GDB Wiki - &lt;a href=&quot;https://sourceware.org/gdb/wiki/&quot;&gt;https://sourceware.org/gdb/wiki/&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;gdbWatchPoint: GDB tips &amp;amp; tricks 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://undo.io/resources/gdb-watchpoint/&quot;&gt;https://undo.io/resources/gdb-watchpoint/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/playlist?list=PLrADU7tRzDD4xHv_zVoLKYg9mXYjXGhjG&quot;&gt;https://www.youtube.com/playlist?list=PLrADU7tRzDD4xHv_zVoLKYg9mXYjXGhjG&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Hitchikers Guide To The GDB - &lt;a href=&quot;http://apoorvaj.io/hitchhikers-guide-to-the-gdb.html&quot;&gt;http://apoorvaj.io/hitchhikers-guide-to-the-gdb.html&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;How to point GDB to your sources - &lt;a href=&quot;https://alex.dzyoba.com/blog/gdb-source-path/&quot;&gt;https://alex.dzyoba.com/blog/gdb-source-path/&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;Howto: GDB Remote Serial Protocol 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.embecosm.com/appnotes/ean4/embecosm-howto-rsp-server-ean4-issue-2.html&quot;&gt;https://www.embecosm.com/appnotes/ean4/embecosm-howto-rsp-server-ean4-issue-2.html&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Introduction to Debuggers - Saumil Shah - &lt;a href=&quot;http://www.slideshare.net/saumilshah/introduction-to-debuggers&quot;&gt;http://www.slideshare.net/saumilshah/introduction-to-debuggers&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;Jeff Trull 
  &lt;ul&gt; 
   &lt;li&gt;Displaying Stack Frames in gdb with Python - &lt;a href=&quot;http://jefftrull.github.io/c++/gdb/python/2018/03/02/print-frame.html&quot;&gt;http://jefftrull.github.io/c++/gdb/python/2018/03/02/print-frame.html&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Improving C++ backtraces with the gdb Python API - &lt;a href=&quot;http://jefftrull.github.io/c++/gdb/python/2018/04/24/improved-backtrace.html&quot;&gt;http://jefftrull.github.io/c++/gdb/python/2018/04/24/improved-backtrace.html&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Skipping library code in gdb with help from libClang - &lt;a href=&quot;http://jefftrull.github.io/c++/gdb/python/libclang/llvm/2018/04/30/stepping-with-libclang.html&quot;&gt;http://jefftrull.github.io/c++/gdb/python/libclang/llvm/2018/04/30/stepping-with-libclang.html&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Julia Evans 
  &lt;ul&gt; 
   &lt;li&gt;Three steps to learning GDB - &lt;a href=&quot;https://jvns.ca/blog/2014/02/10/three-steps-to-learning-gdb/&quot;&gt;https://jvns.ca/blog/2014/02/10/three-steps-to-learning-gdb/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;How does gdb work? - &lt;a href=&quot;https://jvns.ca/blog/2016/08/10/how-does-gdb-work/&quot;&gt;https://jvns.ca/blog/2016/08/10/how-does-gdb-work/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;How does gdb call functions? - &lt;a href=&quot;https://jvns.ca/blog/2018/01/04/how-does-gdb-call-functions/&quot;&gt;https://jvns.ca/blog/2018/01/04/how-does-gdb-call-functions/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Notes on GDB - &lt;a href=&quot;https://publicclu2.blogspot.com/2013/05/notes-on-gdb.html&quot;&gt;https://publicclu2.blogspot.com/2013/05/notes-on-gdb.html&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;Object Inspection in GDB - &lt;a href=&quot;https://hgad.net/posts/object-inspection-in-gdb/&quot;&gt;https://hgad.net/posts/object-inspection-in-gdb/&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;Process Injection with GDB - &lt;a href=&quot;https://magisterquis.github.io/2018/03/11/process-injection-with-gdb.html&quot;&gt;https://magisterquis.github.io/2018/03/11/process-injection-with-gdb.html&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;Python Interpreter in GNU Debugger 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.pythonsheets.com/appendix/python-gdb.html&quot;&gt;https://www.pythonsheets.com/appendix/python-gdb.html&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;RevEngE is a dish served cold: Debug-Oriented Malware Decompilation and Reassembly 
  &lt;ul&gt; 
   &lt;li&gt;Reversing and Offensive-oriented Trends Symposium (ROOTS) 2019&lt;/li&gt; 
   &lt;li&gt;Marcus Botacin, Lucas Galante, Paulo de Geus, André Grégio&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://lasca.ic.unicamp.br/paulo/papers/2019-ROOTS-marcus.botacin-lucas.galante-RevEngE.pdf&quot;&gt;https://lasca.ic.unicamp.br/paulo/papers/2019-ROOTS-marcus.botacin-lucas.galante-RevEngE.pdf&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://corvus.inf.ufpr.br/&quot;&gt;https://corvus.inf.ufpr.br/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;RevEngE: Reverse Engineering Engine 
    &lt;ul&gt; 
     &lt;li&gt;Explore debugging extensions and malware decompilation capabilities based on dynamic GDB debugging sessions.&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://github.com/marcusbotacin/Reverse.Engineering.Engine&quot;&gt;https://github.com/marcusbotacin/Reverse.Engineering.Engine&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Skipping standard C++ library during debug session in gdb - &lt;a href=&quot;https://xaizek.github.io/2016-05-26/skipping-standard-library-in-gdb/&quot;&gt;https://xaizek.github.io/2016-05-26/skipping-standard-library-in-gdb/&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;Victor Stinner&apos;s Notes - GDB: GNU debugger - &lt;a href=&quot;http://vstinner.readthedocs.io/gdb.html&quot;&gt;http://vstinner.readthedocs.io/gdb.html&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Talks&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;A flexible GDB (GNU Debugger) target description for processor diversity – SFO17-210 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;http://connect.linaro.org/resource/sfo17/sfo17-210/&quot;&gt;http://connect.linaro.org/resource/sfo17/sfo17-210/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Become a GDB Power User - ACCU 2016 - Greg Law 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=713ay4bZUrw&quot;&gt;https://www.youtube.com/watch?v=713ay4bZUrw&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;including Q&amp;amp;A: &lt;a href=&quot;https://www.youtube.com/watch?v=6ag7yvhDAiE&quot;&gt;https://www.youtube.com/watch?v=6ag7yvhDAiE&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Debugging Linux C++ 
  &lt;ul&gt; 
   &lt;li&gt;CppCon 2018; Greg Law&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=V1t6faOKjuQ&quot;&gt;https://www.youtube.com/watch?v=V1t6faOKjuQ&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;GDB: C++ conversion &amp;amp; dogfooding C++ 
  &lt;ul&gt; 
   &lt;li&gt;GNU Tools Cauldron 2017; Pedro Alves&lt;/li&gt; 
   &lt;li&gt;Slides: &lt;a href=&quot;https://gcc.gnu.org/wiki/cauldron2017?action=AttachFile&amp;amp;do=view&amp;amp;target=gdb+-+C%2B%2B+conversion+%26+dogfood.pdf&quot;&gt;https://gcc.gnu.org/wiki/cauldron2017?action=AttachFile&amp;amp;do=view&amp;amp;target=gdb+-+C%2B%2B+conversion+%26+dogfood.pdf&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Video: &lt;a href=&quot;https://slideslive.com/38902352/gdb-c-conversion-dogfooding-c&quot;&gt;https://slideslive.com/38902352/gdb-c-conversion-dogfooding-c&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;GDB - A Lot More Than You Knew - CppCon 2016 - Greg Law 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=-n9Fkq1e6sg&quot;&gt;https://www.youtube.com/watch?v=-n9Fkq1e6sg&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Give me 15 minutes &amp;amp; I&apos;ll change your view of GDB - CppCon 2015 - Greg Law 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=PorfLSr3DDI&quot;&gt;https://www.youtube.com/watch?v=PorfLSr3DDI&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;How custom GDB commands help in C++ development 
  &lt;ul&gt; 
   &lt;li&gt;Munich C++ User Group 2018 (Lightning Talk); Michael Krasnyk&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=QtTYXE1wSVs&quot;&gt;https://www.youtube.com/watch?v=QtTYXE1wSVs&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Improving Debuggability with GDB&apos;s Python API - C++Now 2018 - Jeff Trull 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=mLPp1x_1h3g&quot;&gt;https://www.youtube.com/watch?v=mLPp1x_1h3g&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Liberating the Debugging Experience with the GDB Python API 
  &lt;ul&gt; 
   &lt;li&gt;ACCU Bay Area Meetup 2018; Jeff Trull&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/accuBayArea/Slides/blob/master/slides/2018-08-08-jeff.pdf&quot;&gt;https://github.com/accuBayArea/Slides/blob/master/slides/2018-08-08-jeff.pdf&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;CppCon 2018 - &lt;a href=&quot;https://www.youtube.com/watch?v=ck_jCH_G7pA&quot;&gt;https://www.youtube.com/watch?v=ck_jCH_G7pA&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;gdb_python_api: Experiments with the GDB Python API 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://github.com/jefftrull/gdb_python_api&quot;&gt;https://github.com/jefftrull/gdb_python_api&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;More GDB wizardry and 8 other essential Linux application debugging tools 
  &lt;ul&gt; 
   &lt;li&gt;ACCU 2019; Greg Law&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=Yq6g_kvyvPU&quot;&gt;https://www.youtube.com/watch?v=Yq6g_kvyvPU&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Programmatic Debugging with GDB and Python 
  &lt;ul&gt; 
   &lt;li&gt;PyCon APAC/Taiwan 2015; Scott Tsai&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=oAYbt2PsKng&quot;&gt;https://www.youtube.com/watch?v=oAYbt2PsKng&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://docs.google.com/presentation/d/15qOKBh9FDjCeGS-xAHXZSJDS5_aoZk0Caz12FL_f294/&quot;&gt;https://docs.google.com/presentation/d/15qOKBh9FDjCeGS-xAHXZSJDS5_aoZk0Caz12FL_f294/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;SecurityTube GDB Expert (SGDE) 
  &lt;ul&gt; 
   &lt;li&gt;Walkthroughs: &lt;a href=&quot;https://github.com/Kan1shka9/Securitytube-Gnu-Debugger-Expert&quot;&gt;https://github.com/Kan1shka9/Securitytube-Gnu-Debugger-Expert&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Course Videos: &lt;a href=&quot;http://www.securitytube.net/tags/sgde&quot;&gt;http://www.securitytube.net/tags/sgde&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/playlist?list=PLiP0FxVgYuUz0kdK7L7YaI5n4qkOuymue&quot;&gt;https://www.youtube.com/playlist?list=PLiP0FxVgYuUz0kdK7L7YaI5n4qkOuymue&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;The GDB Text User Interface 
  &lt;ul&gt; 
   &lt;li&gt;FOSDEM 2020; Tom Tromey&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://fosdem.org/2020/schedule/event/debugging_gdb_tui/&quot;&gt;https://fosdem.org/2020/schedule/event/debugging_gdb_tui/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Understanding, Scripting, and Extending GDB (2017) 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://mcgdb.0x972.info/team/&quot;&gt;https://mcgdb.0x972.info/team/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/kpouget/tuto-gdb.py&quot;&gt;https://github.com/kpouget/tuto-gdb.py&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Slides: &lt;a href=&quot;https://mcgdb.0x972.info/files/tuto-gdb-py.presentation.pdf&quot;&gt;https://mcgdb.0x972.info/files/tuto-gdb-py.presentation.pdf&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Your Application versus GDB - FOSDEM 2014 - Tom Tromey 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://archive.fosdem.org/2014/schedule/event/your_application_versus_gdb/&quot;&gt;https://archive.fosdem.org/2014/schedule/event/your_application_versus_gdb/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=RwDA3oIOtWw&quot;&gt;https://www.youtube.com/watch?v=RwDA3oIOtWw&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;LLDB&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;The LLDB Debugger - &lt;a href=&quot;https://lldb.llvm.org/&quot;&gt;https://lldb.llvm.org/&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Projects&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;ds2: Debug server for lldb 
  &lt;ul&gt; 
   &lt;li&gt;ds2 is a debug server designed to be used with LLDB to perform remote debugging of Linux, Android, FreeBSD, Windows and Windows Phone targets. Windows/Windows Phone support is still under active development.&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/facebook/ds2&quot;&gt;https://github.com/facebook/ds2&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;2015 LLVM Developers’ Meeting: Stephane Sezer &quot;ds2, a tiny debug server used with lldb&quot;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=n00EhLskJWk&amp;amp;list=PL_R5A0lGi1AA4Lv2bBFSwhgDaHvvpVU21&amp;amp;index=27&quot;&gt;https://www.youtube.com/watch?v=n00EhLskJWk&amp;amp;list=PL_R5A0lGi1AA4Lv2bBFSwhgDaHvvpVU21&amp;amp;index=27&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;GDBundle: Plugin Manager for GDB and LLDB 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/memfault/gdbundle&quot;&gt;https://github.com/memfault/gdbundle&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;gdbundle - GDB and LLDB&apos;s Missing Plugin Manager 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://interrupt.memfault.com/blog/gdbundle-plugin-manager&quot;&gt;https://interrupt.memfault.com/blog/gdbundle-plugin-manager&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;LLDB Scripts: A collection of LLDB aliases/regexes and Python scripts to aid in your debugging sessions 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/DerekSelander/LLDB&quot;&gt;https://github.com/DerekSelander/LLDB&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.raywenderlich.com/162020/custom-lldb-commands-practice&quot;&gt;https://www.raywenderlich.com/162020/custom-lldb-commands-practice&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.raywenderlich.com/161938/assembly-register-calling-convention-tutorial&quot;&gt;https://www.raywenderlich.com/161938/assembly-register-calling-convention-tutorial&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;lldbinit: Similar implementation of .gdbinit from fG! for lldb in python 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/deroko/lldbinit&quot;&gt;https://github.com/deroko/lldbinit&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;LLDBINIT: A gdbinit clone for LLDB 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/gdbinit/lldbinit&quot;&gt;https://github.com/gdbinit/lldbinit&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.zerodayinitiative.com/blog/2020/4/20/mindshare-using-lldbinit-to-enhance-the-lldb-debugger&quot;&gt;https://www.zerodayinitiative.com/blog/2020/4/20/mindshare-using-lldbinit-to-enhance-the-lldb-debugger&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Vegvisir: A browser based GUI for LLDB Debugger 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/ant4g0nist/vegvisir&quot;&gt;https://github.com/ant4g0nist/vegvisir&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;vplot: C++ container graph visualization for lldb 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/egladysh/vplot&quot;&gt;https://github.com/egladysh/vplot&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Editor Integration&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;CodeLLDB: a LLDB front end for Visual Studio Code - &lt;a href=&quot;https://github.com/vadimcn/vscode-lldb&quot;&gt;https://github.com/vadimcn/vscode-lldb&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;LLDB Vim Frontend - &lt;a href=&quot;https://github.com/gilligan/vim-lldb&quot;&gt;https://github.com/gilligan/vim-lldb&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;LLDB Neovim Frontend - &lt;a href=&quot;https://github.com/dbgx/lldb.nvim&quot;&gt;https://github.com/dbgx/lldb.nvim&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;Native Debug 
  &lt;ul&gt; 
   &lt;li&gt;GDB &amp;amp; LLDB Debugger support for VSCode&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://marketplace.visualstudio.com/items?itemName=webfreak.debug&quot;&gt;https://marketplace.visualstudio.com/items?itemName=webfreak.debug&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/WebFreak001/code-debug&quot;&gt;https://github.com/WebFreak001/code-debug&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Readings&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;LLDB Cheat Sheet 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.nesono.com/content/lldb-cheat-sheet&quot;&gt;https://www.nesono.com/content/lldb-cheat-sheet&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.nesono.com/sites/default/files/lldb%20cheat%20sheet.pdf&quot;&gt;https://www.nesono.com/sites/default/files/lldb%20cheat%20sheet.pdf&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;LLDB for GDB Users – Command Summary 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://developer.apple.com/library/content/documentation/General/Conceptual/lldb-guide/chapters/A3-GDB-Summary.html&quot;&gt;https://developer.apple.com/library/content/documentation/General/Conceptual/lldb-guide/chapters/A3-GDB-Summary.html&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;LLDB Scripts - Debugging the Swift Compiler 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/apple/swift/blob/master/docs/DebuggingTheCompiler.rst#lldb-scripts&quot;&gt;https://github.com/apple/swift/blob/master/docs/DebuggingTheCompiler.rst#lldb-scripts&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;LLDB to GDB Command Map - &lt;a href=&quot;https://lldb.llvm.org/lldb-gdb.html&quot;&gt;https://lldb.llvm.org/lldb-gdb.html&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;Beyond Debug Information: Improving Program Reconstruction in LLDB using C++ Modules 
  &lt;ul&gt; 
   &lt;li&gt;2019 Master’s Thesis; Raphael Isemann&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://hdl.handle.net/20.500.12380/300037&quot;&gt;https://hdl.handle.net/20.500.12380/300037&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Talks&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;Support for mini-debuginfo in LLDB 
  &lt;ul&gt; 
   &lt;li&gt;How to read the .gnu_debugdata section.&lt;/li&gt; 
   &lt;li&gt;FOSDEM 2020; Konrad Kleine&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://fosdem.org/2020/schedule/event/debugging_mini/&quot;&gt;https://fosdem.org/2020/schedule/event/debugging_mini/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Better C++ debugging using Clang Modules in LLDB 
  &lt;ul&gt; 
   &lt;li&gt;2019 LLVM Developers’ Meeting; Raphael Isemann&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=vuNZLlHhy0k&quot;&gt;https://www.youtube.com/watch?v=vuNZLlHhy0k&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://llvm.org/devmtg/2019-10/talk-abstracts.html#tech13&quot;&gt;http://llvm.org/devmtg/2019-10/talk-abstracts.html#tech13&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Bringing RenderScript to LLDB 
  &lt;ul&gt; 
   &lt;li&gt;2016 EuroLLVM Developers&apos; Meeting; Luke Drummond &amp;amp; Ewan Crawford, Codeplay&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=BBC61L0QKCM&quot;&gt;https://www.youtube.com/watch?v=BBC61L0QKCM&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://www.llvm.org/devmtg/2016-03/Presentations/EuroLLVM2016-E.Crawford_and_L.Drummond-Bringing_RenderScript_to_LLDB.pdf&quot;&gt;http://www.llvm.org/devmtg/2016-03/Presentations/EuroLLVM2016-E.Crawford_and_L.Drummond-Bringing_RenderScript_to_LLDB.pdf&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Debugging Tips and Tricks 
  &lt;ul&gt; 
   &lt;li&gt;WWDC 2016; Kate Stone, Enrico Granata, Sean Callanan, Jim Ingham&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://developer.apple.com/videos/play/wwdc2016/417&quot;&gt;https://developer.apple.com/videos/play/wwdc2016/417&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Debugging with LLDB 
  &lt;ul&gt; 
   &lt;li&gt;WWDC 2012; Greg Clayton&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://developer.apple.com/videos/play/wwdc2012/415/&quot;&gt;https://developer.apple.com/videos/play/wwdc2012/415/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Debugging with LLVM: A quick introduction to LLDB and LLVM sanitizers 
  &lt;ul&gt; 
   &lt;li&gt;FOSDEM 2020; Andrzej Warzynski; Graham Hunter&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://fosdem.org/2020/schedule/event/debugging_with_llvm/&quot;&gt;https://fosdem.org/2020/schedule/event/debugging_with_llvm/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;ds2: a tiny debug server used with lldb 
  &lt;ul&gt; 
   &lt;li&gt;2015 LLVM Developers’ Meeting; Stephane Sezer, Facebook&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=n00EhLskJWk&quot;&gt;https://www.youtube.com/watch?v=n00EhLskJWk&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/facebook/ds2&quot;&gt;https://github.com/facebook/ds2&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;LLDB - a new C++ debugger 
  &lt;ul&gt; 
   &lt;li&gt;DevConf.CZ 2019; Jan Kratochvíl&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=2BjKNaiB3yM&quot;&gt;https://www.youtube.com/watch?v=2BjKNaiB3yM&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://devconfcz2019.sched.com/event/Jcht&quot;&gt;https://devconfcz2019.sched.com/event/Jcht&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;LLDB Reproducers 
  &lt;ul&gt; 
   &lt;li&gt;2019 EuroLLVM Developers’ Meeting; Jonas Devlieghere&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=ygdzXnfyvbg&quot;&gt;https://www.youtube.com/watch?v=ygdzXnfyvbg&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://llvm.org/devmtg/2019-04/talks.html#Talk_12&quot;&gt;http://llvm.org/devmtg/2019-04/talks.html#Talk_12&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;LLDB Tutorial: Adding debugger support for your target 
  &lt;ul&gt; 
   &lt;li&gt;2016 EuroLLVM Developers&apos; Meeting; Deepak Panickal &amp;amp; Andrzej Warzynski, Codeplay&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/codeplaysoftware/lldb-msp430&quot;&gt;https://github.com/codeplaysoftware/lldb-msp430&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://www.llvm.org/devmtg/2016-03/Tutorials/LLDB-tutorial.pdf&quot;&gt;http://www.llvm.org/devmtg/2016-03/Tutorials/LLDB-tutorial.pdf&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=9hhDZeV0fYU&quot;&gt;https://www.youtube.com/watch?v=9hhDZeV0fYU&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;LLDB: Beyond &quot;po&quot; 
  &lt;ul&gt; 
   &lt;li&gt;WWDC 2019; Davide Italiano, Jonas Devlieghere&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://developer.apple.com/videos/play/wwdc2019/429/&quot;&gt;https://developer.apple.com/videos/play/wwdc2019/429/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.raywenderlich.com/3868932-wwdc-2019-top-10-videos#toc-anchor-011&quot;&gt;https://www.raywenderlich.com/3868932-wwdc-2019-top-10-videos#toc-anchor-011&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Migrating from GDB to LLDB 
  &lt;ul&gt; 
   &lt;li&gt;WWDC 2011; Jim Ingham&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://developer.apple.com/videos/play/wwdc2011/321/&quot;&gt;https://developer.apple.com/videos/play/wwdc2011/321/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;RR&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;RR: Record and Replay Framework 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;http://rr-project.org/&quot;&gt;http://rr-project.org/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/mozilla/rr&quot;&gt;https://github.com/mozilla/rr&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;rr Paper: &quot;Lightweight User-Space Record And Replay&quot; 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;http://robert.ocallahan.org/2016/10/rr-paper-lightweight-user-space-record.html&quot;&gt;http://robert.ocallahan.org/2016/10/rr-paper-lightweight-user-space-record.html&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Control Flow Visualizer (CFViz): an rr / gdb plugin 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://botondballo.wordpress.com/2017/12/22/control-flow-visualizer-cfviz-an-rr-gdb-plugin/&quot;&gt;https://botondballo.wordpress.com/2017/12/22/control-flow-visualizer-cfviz-an-rr-gdb-plugin/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://bitbucket.org/botond/cfviz&quot;&gt;https://bitbucket.org/botond/cfviz&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Engineering Record And Replay For Deployability 
  &lt;ul&gt; 
   &lt;li&gt;USENIX ATC 2017&lt;/li&gt; 
   &lt;li&gt;Robert O&apos;Callahan, Chris Jones, Nathan Froyd, Kyle Huey, Albert Noll, Nimrod Partush&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://arxiv.org/abs/1705.05937&quot;&gt;https://arxiv.org/abs/1705.05937&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.usenix.org/conference/atc17/technical-sessions/presentation/ocallahan&quot;&gt;https://www.usenix.org/conference/atc17/technical-sessions/presentation/ocallahan&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Improved debugging with rr - &lt;a href=&quot;https://techtalk.intersec.com/2018/03/improved-debugging-with-rr/&quot;&gt;https://techtalk.intersec.com/2018/03/improved-debugging-with-rr/&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;rr-dataflow: An &apos;origin&apos; command that continues to the origin of a piece of data in rr 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/jrmuizel/rr-dataflow&quot;&gt;https://github.com/jrmuizel/rr-dataflow&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Using rr-dataflow: Why and How? - &lt;a href=&quot;https://www.mgaudet.ca/technical/2018/10/18/using-rr-dataflow-why-and-how&quot;&gt;https://www.mgaudet.ca/technical/2018/10/18/using-rr-dataflow-why-and-how&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Timeless Debugging of Complex Software: Root Cause Analysis of a Non-Deterministic JavaScriptCore Bug 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;http://blog.ret2.io/2018/06/19/pwn2own-2018-root-cause-analysis/&quot;&gt;http://blog.ret2.io/2018/06/19/pwn2own-2018-root-cause-analysis/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;OS-specific&lt;/h2&gt; 
&lt;h3&gt;iOS&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;Chisel: a collection of LLDB commands to assist debugging iOS apps 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/facebook/chisel&quot;&gt;https://github.com/facebook/chisel&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;KTRW: An iOS kernel debugger based on a KTRR bypass for A11 iPhones that works with LLDB 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/googleprojectzero/ktrw&quot;&gt;https://github.com/googleprojectzero/ktrw&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;KTRW: The journey to build a debuggable iPhone 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://googleprojectzero.blogspot.com/2019/10/ktrw-journey-to-build-debuggable-iphone.html&quot;&gt;https://googleprojectzero.blogspot.com/2019/10/ktrw-journey-to-build-debuggable-iphone.html&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Linux&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;crash-python: a semantic debugger for the Linux kernel 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/jeffmahoney/crash-python&quot;&gt;https://github.com/jeffmahoney/crash-python&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;debuginfod 
  &lt;ul&gt; 
   &lt;li&gt;elfutils debuginfod is a client/server in elfutils 0.178+ that automatically distributes elf/dwarf/source-code from servers to clients such as debuggers across HTTP 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://sourceware.org/elfutils/Debuginfod.html&quot;&gt;https://sourceware.org/elfutils/Debuginfod.html&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;Deploying debuginfod servers for your developers 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://developers.redhat.com/blog/2019/12/17/deploying-debuginfod-servers-for-your-developers/&quot;&gt;https://developers.redhat.com/blog/2019/12/17/deploying-debuginfod-servers-for-your-developers/&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;The elfutils debuginfod server 
    &lt;ul&gt; 
     &lt;li&gt;FOSDEM 2020; Mark Wielaard, Frank Ch. Eigler&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://fosdem.org/2020/schedule/event/debugging_debuginfod/&quot;&gt;https://fosdem.org/2020/schedule/event/debugging_debuginfod/&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;Introducing debuginfod, the elfutils debuginfo server 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://developers.redhat.com/blog/2019/10/14/introducing-debuginfod-the-elfutils-debuginfo-server/&quot;&gt;https://developers.redhat.com/blog/2019/10/14/introducing-debuginfod-the-elfutils-debuginfo-server/&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;elfutils debuginfo-server 
    &lt;ul&gt; 
     &lt;li&gt;GNU Tools Cauldron 2019; Frank Ch. Eigler, Aaron Merey&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=cyOXWT_EBJ0&quot;&gt;https://www.youtube.com/watch?v=cyOXWT_EBJ0&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://gcc.gnu.org/wiki/cauldron2019talks?action=AttachFile&amp;amp;do=view&amp;amp;target=dbgserver.pdf&quot;&gt;https://gcc.gnu.org/wiki/cauldron2019talks?action=AttachFile&amp;amp;do=view&amp;amp;target=dbgserver.pdf&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;drgn: Scriptable debugger library 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/osandov/drgn/&quot;&gt;https://github.com/osandov/drgn/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://drgn.readthedocs.io/&quot;&gt;https://drgn.readthedocs.io/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;A kernel debugger in Python: drgn 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://lwn.net/Articles/789641/&quot;&gt;https://lwn.net/Articles/789641/&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;edb: a cross platform x86/x86-64 debugger 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/eteran/edb-debugger&quot;&gt;https://github.com/eteran/edb-debugger&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;ich: Linux crash harness with runtime process instrumentation 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/zznop/ich&quot;&gt;https://github.com/zznop/ich&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;libkdumpfile: Kernel coredump file access 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/ptesarik/libkdumpfile&quot;&gt;https://github.com/ptesarik/libkdumpfile&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;libthread_db 
  &lt;ul&gt; 
   &lt;li&gt;Notes about an odd, esoteric, yet incredibly useful library: libthread_db 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;http://timetobleed.com/notes-about-an-odd-esoteric-yet-incredibly-useful-library-libthread_db/&quot;&gt;http://timetobleed.com/notes-about-an-odd-esoteric-yet-incredibly-useful-library-libthread_db/&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;ORC (Oops Rewind Capability) Unwinder 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=ee9f8fce99640811b2b8e79d0d1dbe8bab69ba67&quot;&gt;Commit ee9f8fce9964&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=39358a033b2e4432052265c1fa0f36f572d8cfb5&quot;&gt;Commit 39358a033b2e&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;orc-unwinder.txt - &lt;a href=&quot;https://github.com/torvalds/linux/blob/master/Documentation/x86/orc-unwinder.txt&quot;&gt;https://github.com/torvalds/linux/blob/master/Documentation/x86/orc-unwinder.txt&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;The Linux x86 ORC Stack Unwinder - &lt;a href=&quot;http://www.codeblueprint.co.uk/2017/07/31/the-orc-unwinder.html&quot;&gt;http://www.codeblueprint.co.uk/2017/07/31/the-orc-unwinder.html&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;The ORCs are coming - &lt;a href=&quot;https://lwn.net/Articles/728339/&quot;&gt;https://lwn.net/Articles/728339/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;x86: ORC unwinder (previously undwarf) - &lt;a href=&quot;https://lwn.net/Articles/727553/&quot;&gt;https://lwn.net/Articles/727553/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;plutonium-dbg: A kernel-based debugger for Linux applications 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/plutonium-dbg/plutonium-dbg&quot;&gt;https://github.com/plutonium-dbg/plutonium-dbg&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Kernel-Assisted Debugging of Linux Applications 
    &lt;ul&gt; 
     &lt;li&gt;Reversing and Offensive-oriented Trends Symposium (ROOTS) 2018&lt;/li&gt; 
     &lt;li&gt;Tobias Holl, Philipp Klocke, Fabian Franzen, and Julian Kirsch&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://vimeo.com/307238462&quot;&gt;https://vimeo.com/307238462&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://dl.acm.org/citation.cfm?id=3289596&quot;&gt;https://dl.acm.org/citation.cfm?id=3289596&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Scout - Instruction based research debugger 
  &lt;ul&gt; 
   &lt;li&gt;an extendable basic debugger designed for use in those cases that there is no built-in debugger / gdb-stub in the debugee process / firmware&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/CheckPointSW/Scout&quot;&gt;https://github.com/CheckPointSW/Scout&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://scout-debugger.readthedocs.io/&quot;&gt;https://scout-debugger.readthedocs.io/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;sdb: The Slick/Simple Debugger 
  &lt;ul&gt; 
   &lt;li&gt;A postmortem and live debugger&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/delphix/sdb&quot;&gt;https://github.com/delphix/sdb&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Debugging ZFS: From Illumos to Linux 
    &lt;ul&gt; 
     &lt;li&gt;OpenZFS Developer Summit 2019; Serapheim Dimitropoulos&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://drive.google.com/file/d/1oho9X5bkW-I-yJ-pVD8VqkaloxhGepzT/view&quot;&gt;https://drive.google.com/file/d/1oho9X5bkW-I-yJ-pVD8VqkaloxhGepzT/view&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;vmlinux-to-elf: A tool to recover a fully analyzable ELF from a raw kernel, through extracting the kernel symbol table (kallsyms) 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/marin-m/vmlinux-to-elf&quot;&gt;https://github.com/marin-m/vmlinux-to-elf&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Linux - Talks&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;Linux Kernel Debugging: Going Beyond Printk Messages 
  &lt;ul&gt; 
   &lt;li&gt;Embedded Linux Conference Europe (ELCE) 2019; Sergio Prado&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=NDXYpR_m1CU&quot;&gt;https://www.youtube.com/watch?v=NDXYpR_m1CU&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://elinux.org/images/1/14/Linuxkerneldebugging.pdf&quot;&gt;https://elinux.org/images/1/14/Linuxkerneldebugging.pdf&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://e-labworks.com/talks/elce2019&quot;&gt;https://e-labworks.com/talks/elce2019&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;macOS&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;LLDBagility 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/quarkslab/LLDBagility/&quot;&gt;https://github.com/quarkslab/LLDBagility/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;a tool for debugging macOS virtual machines with the aid of the Fast Debugging Protocol (FDP)&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://blog.quarkslab.com/an-overview-of-macos-kernel-debugging.html&quot;&gt;https://blog.quarkslab.com/an-overview-of-macos-kernel-debugging.html&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://blog.quarkslab.com/lldbagility-practical-macos-kernel-debugging.html&quot;&gt;https://blog.quarkslab.com/lldbagility-practical-macos-kernel-debugging.html&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Mac OS X Debugging Magic - &lt;a href=&quot;https://developer.apple.com/library/content/technotes/tn2124/_index.html&quot;&gt;https://developer.apple.com/library/content/technotes/tn2124/_index.html&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Windows&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;An RPC Debugging Framework with Visual Studio 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;http://donw.io/post/rpc-debugging-vs/&quot;&gt;http://donw.io/post/rpc-debugging-vs/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;ArkDasm: 64-bit interactive disassembler and debugger for Windows 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;http://www.arkdasm.com/&quot;&gt;http://www.arkdasm.com/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Creating a Public Symbol Server, Easily 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://randomascii.wordpress.com/2020/03/14/creating-a-public-symbol-server-easily/&quot;&gt;https://randomascii.wordpress.com/2020/03/14/creating-a-public-symbol-server-easily/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;DbgShell: A PowerShell front-end for the Windows debugger engine 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/Microsoft/DbgShell/&quot;&gt;https://github.com/Microsoft/DbgShell/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Debug Recipes (.NET and Windows problems) - &lt;a href=&quot;https://github.com/lowleveldesign/debug-recipes&quot;&gt;https://github.com/lowleveldesign/debug-recipes&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;Debugging in Visual Studio - &lt;a href=&quot;https://docs.microsoft.com/en-us/visualstudio/debugger/debugger-feature-tour&quot;&gt;https://docs.microsoft.com/en-us/visualstudio/debugger/debugger-feature-tour&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;Debugging Tools for Windows (WinDbg, KD, CDB, NTSD) 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://docs.microsoft.com/en-us/windows-hardware/drivers/debugger/&quot;&gt;https://docs.microsoft.com/en-us/windows-hardware/drivers/debugger/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;DuBStep (Dynamic Breakpoint API): A Library for creating hardware execution and data breakpoints at runtime on Win32/Win64 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/justinboswell/dubstep&quot;&gt;https://github.com/justinboswell/dubstep&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;kdmp-parser: Windows kernel dump C++ parser 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/0vercl0k/kdmp-parser&quot;&gt;https://github.com/0vercl0k/kdmp-parser&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;makin - reveal anti-debug tricks (Windows) - &lt;a href=&quot;https://github.com/secrary/makin&quot;&gt;https://github.com/secrary/makin&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;Nanomite - Windows Debugger for x64 and x86 - &lt;a href=&quot;https://github.com/zer0fl4g/Nanomite/&quot;&gt;https://github.com/zer0fl4g/Nanomite/&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;OllyDbg - &lt;a href=&quot;http://www.ollydbg.de/&quot;&gt;http://www.ollydbg.de/&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;ScyllaHide: Advanced usermode anti-anti-debugger 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/x64dbg/ScyllaHide&quot;&gt;https://github.com/x64dbg/ScyllaHide&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;TitanHide: Hiding kernel-driver for x86/x64 
  &lt;ul&gt; 
   &lt;li&gt;a driver intended to hide debuggers from certain processes&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/mrexodia/TitanHide&quot;&gt;https://github.com/mrexodia/TitanHide&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Windows Debugging Tools - Debugging Resources 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://docs.microsoft.com/en-us/windows-hardware/drivers/debugger/debugging-resources&quot;&gt;https://docs.microsoft.com/en-us/windows-hardware/drivers/debugger/debugging-resources&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;x64dbg 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://x64dbg.com/&quot;&gt;https://x64dbg.com/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/x64dbg/x64dbg&quot;&gt;https://github.com/x64dbg/x64dbg&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Visual Studio Debugger&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://docs.microsoft.com/en-us/visualstudio/debugger/&quot;&gt;https://docs.microsoft.com/en-us/visualstudio/debugger/&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://devblogs.microsoft.com/visualstudio/tag/debug/&quot;&gt;https://devblogs.microsoft.com/visualstudio/tag/debug/&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;WinDbg&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;Introduction to WinDbg and debugging Windows - series by Anand George 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/playlist?list=PLhx7-txsG6t6n_E2LgDGqgvJtCHPL7UFu&quot;&gt;https://www.youtube.com/playlist?list=PLhx7-txsG6t6n_E2LgDGqgvJtCHPL7UFu&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Modern Debugging with WinDbg Preview 
  &lt;ul&gt; 
   &lt;li&gt;DEFCON 27 (2019) Workshop Materials&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/hugsy/defcon_27_windbg_workshop/&quot;&gt;https://github.com/hugsy/defcon_27_windbg_workshop/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;WinDbg cheatsheet 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://github.com/hugsy/defcon_27_windbg_workshop/blob/master/windbg_cheatsheet.md&quot;&gt;https://github.com/hugsy/defcon_27_windbg_workshop/blob/master/windbg_cheatsheet.md&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Time Travel Debugging - James McNellis 
  &lt;ul&gt; 
   &lt;li&gt;Meeting C++ 2018 - &lt;a href=&quot;https://www.youtube.com/watch?v=MyVQnP-U_ho&quot;&gt;https://www.youtube.com/watch?v=MyVQnP-U_ho&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Pacific++ 2018 - &lt;a href=&quot;https://www.youtube.com/watch?v=BVslyei0804&quot;&gt;https://www.youtube.com/watch?v=BVslyei0804&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;WinDbg Basics for Malware Analysis 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=QuFJpH3My7A&quot;&gt;https://www.youtube.com/watch?v=QuFJpH3My7A&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;Readings&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;Collection of WinDBG resources - &lt;a href=&quot;https://blogs.msdn.microsoft.com/reiley/2012/07/28/collection-of-windbg-resources/&quot;&gt;https://blogs.msdn.microsoft.com/reiley/2012/07/28/collection-of-windbg-resources/&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;Break On Process Creation in WinDbg 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://shakreiner.com/posts/break-on-process-windbg/&quot;&gt;https://shakreiner.com/posts/break-on-process-windbg/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Debugger Data Model, Javascript &amp;amp; X64 Exception Handling - &lt;a href=&quot;https://doar-e.github.io/blog/2017/12/01/debugger-data-model/&quot;&gt;https://doar-e.github.io/blog/2017/12/01/debugger-data-model/&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;Debugging Tools for Windows - &lt;a href=&quot;https://blogs.msdn.microsoft.com/windbg/&quot;&gt;https://blogs.msdn.microsoft.com/windbg/&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;Exploiting flaws in Windbg: how to escape or fool debuggers from existing flaws 
  &lt;ul&gt; 
   &lt;li&gt;Journal of Computer Virology and Hacking Techniques (2020)&lt;/li&gt; 
   &lt;li&gt;François Plumerault, Baptiste David&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://dx.doi.org/10.1007/s11416-020-00347-x&quot;&gt;http://dx.doi.org/10.1007/s11416-020-00347-x&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;JavaScript bridge makes malware analysis with WinDbg easier 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://blog.talosintelligence.com/2019/02/windbg-malware-analysis-with-javascript.html&quot;&gt;https://blog.talosintelligence.com/2019/02/windbg-malware-analysis-with-javascript.html&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Stupid debugger tricks: Calling functions and methods - &lt;a href=&quot;https://blogs.msdn.microsoft.com/oldnewthing/20070427-00/?p=27083&quot;&gt;https://blogs.msdn.microsoft.com/oldnewthing/20070427-00/?p=27083&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;Time travel debugging: It’s a blast! (from the past) 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://blogs.technet.microsoft.com/srd/2019/05/29/time-travel-debugging-its-a-blast-from-the-past/&quot;&gt;https://blogs.technet.microsoft.com/srd/2019/05/29/time-travel-debugging-its-a-blast-from-the-past/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Tutorial: Using WinDBG to call arbitrary functions — WinDBG kung-fu series 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;http://cfc.kizzx2.com/index.php/tutorial-using-windbg-to-call-arbitrary-functions-windbg-kung-fu-series/&quot;&gt;http://cfc.kizzx2.com/index.php/tutorial-using-windbg-to-call-arbitrary-functions-windbg-kung-fu-series/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Undocumented WinDBG - &lt;a href=&quot;https://blogs.msdn.microsoft.com/reiley/2011/10/30/undocumented-windbg/&quot;&gt;https://blogs.msdn.microsoft.com/reiley/2011/10/30/undocumented-windbg/&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;Use Windows Debuggers for Non-Debugging Tasks - &lt;a href=&quot;https://blogs.msdn.microsoft.com/reiley/2011/10/23/use-windows-debuggers-for-non-debugging-tasks/&quot;&gt;https://blogs.msdn.microsoft.com/reiley/2011/10/23/use-windows-debuggers-for-non-debugging-tasks/&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;Using Function Evaluation in WinDBG - &lt;a href=&quot;https://blogs.msdn.microsoft.com/reiley/2012/08/18/using-function-evaluation-in-windbg/&quot;&gt;https://blogs.msdn.microsoft.com/reiley/2012/08/18/using-function-evaluation-in-windbg/&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;Windbg automation and extensions - &lt;a href=&quot;https://nativecoding.wordpress.com/2016/01/10/automate-attach-to-process-on-windows-with-windbg/&quot;&gt;https://nativecoding.wordpress.com/2016/01/10/automate-attach-to-process-on-windows-with-windbg/&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;WinDbg Malware Analysis Cheat Sheet 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://oalabs.openanalysis.net/2019/02/18/windbg-for-malware-analysis/&quot;&gt;https://oalabs.openanalysis.net/2019/02/18/windbg-for-malware-analysis/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;WinDbg, Debugger Objects, and JavaScript! Oh, My! - &lt;a href=&quot;https://www.osr.com/blog/2017/05/18/windbg-debugger-objects-javascript-oh/&quot;&gt;https://www.osr.com/blog/2017/05/18/windbg-debugger-objects-javascript-oh/&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;Yet Another Hello World - &lt;a href=&quot;https://blogs.msdn.microsoft.com/reiley/2011/09/29/yet-another-hello-world/&quot;&gt;https://blogs.msdn.microsoft.com/reiley/2011/09/29/yet-another-hello-world/&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;Projects&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;0CCh Windbg extension - &lt;a href=&quot;https://github.com/0cch/0cchext&quot;&gt;https://github.com/0cch/0cchext&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;DbgModelCppLib: A header-only C++ library for producing and consuming data from the debugger data model 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/Microsoft/WinDbg-Libraries/tree/master/DbgModelCppLib&quot;&gt;https://github.com/Microsoft/WinDbg-Libraries/tree/master/DbgModelCppLib&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/Microsoft/WinDbg-Samples/tree/master/DataModelHelloWorld/Cpp&quot;&gt;https://github.com/Microsoft/WinDbg-Samples/tree/master/DataModelHelloWorld/Cpp&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;PyKd - Python extension for WinDBG to access Debug Engine 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://githomelab.ru/pykd/pykd&quot;&gt;https://githomelab.ru/pykd/pykd&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;windbg-pack: Set of python scripts for WinDBG - &lt;a href=&quot;https://githomelab.ru/pykd/windbg-pack&quot;&gt;https://githomelab.ru/pykd/windbg-pack&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;TWindbg: PEDA-like debugger UI for WinDbg - &lt;a href=&quot;https://github.com/bruce30262/TWindbg&quot;&gt;https://github.com/bruce30262/TWindbg&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;WDBGARK: WinDBG Anti-RootKit extension - &lt;a href=&quot;https://github.com/swwwolf/wdbgark&quot;&gt;https://github.com/swwwolf/wdbgark&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;Winbagility: a tool to connect WinDbg on non /DEBUG Windows x64 systems 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;http://winbagility.github.io&quot;&gt;http://winbagility.github.io&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/Winbagility/Winbagility&quot;&gt;https://github.com/Winbagility/Winbagility&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;WinDbg-Samples: Sample extensions, scripts, and API uses for WinDbg 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/Microsoft/WinDbg-Samples&quot;&gt;https://github.com/Microsoft/WinDbg-Samples&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;WinDBGtree: A command tree based on commands and extensions for Windows Kernel Debugging 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/vagnerpilar/windbgtree&quot;&gt;https://github.com/vagnerpilar/windbgtree&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;Time Travel Debugging&lt;/h5&gt; 
&lt;ul&gt; 
 &lt;li&gt;Time Travel Debugging FAQ - &lt;a href=&quot;https://blogs.msdn.microsoft.com/windbg/2017/10/20/time-travel-debugging-faq/&quot;&gt;https://blogs.msdn.microsoft.com/windbg/2017/10/20/time-travel-debugging-faq/&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;Time Travel Debugging - Overview - &lt;a href=&quot;https://docs.microsoft.com/en-us/windows-hardware/drivers/debugger/time-travel-debugging-overview&quot;&gt;https://docs.microsoft.com/en-us/windows-hardware/drivers/debugger/time-travel-debugging-overview&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;Time Travel Debugging - Sample App Walkthrough - &lt;a href=&quot;https://aka.ms/ttdtutorial&quot;&gt;https://aka.ms/ttdtutorial&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;CppCon 2017: Time Travel Debugging: Root Causing Bugs in Commercial Scale Software 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=l1YJTg_A914&quot;&gt;https://www.youtube.com/watch?v=l1YJTg_A914&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Defrag Tools #186 - Time Travel Debugging - Advanced 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://channel9.msdn.com/Shows/Defrag-Tools/Defrag-Tools-186-Time-Travel-Debugging-Advanced&quot;&gt;https://channel9.msdn.com/Shows/Defrag-Tools/Defrag-Tools-186-Time-Travel-Debugging-Advanced&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Stack Trace &amp;amp; Unwinding&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;BacktraceResolver: Very fast backtraces resolver 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/markpapadakis/BacktraceResolver&quot;&gt;https://github.com/markpapadakis/BacktraceResolver&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Backward-cpp: a beautiful stack trace pretty printer for C++ 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/bombela/backward-cpp&quot;&gt;https://github.com/bombela/backward-cpp&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Boost.Stacktrace 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;http://boostorg.github.io/stacktrace/&quot;&gt;http://boostorg.github.io/stacktrace/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/boostorg/stacktrace&quot;&gt;https://github.com/boostorg/stacktrace&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://www.boost.org/doc/libs/release/doc/html/stacktrace.html&quot;&gt;http://www.boost.org/doc/libs/release/doc/html/stacktrace.html&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;CppCon 2017: Dave Watson “C++ Exceptions and Stack Unwinding” 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=_Ivd3qzgT7U&quot;&gt;https://www.youtube.com/watch?v=_Ivd3qzgT7U&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;libgcc_s (GNU) - &lt;a href=&quot;https://gcc.gnu.org/onlinedocs/gccint/Libgcc.html&quot;&gt;https://gcc.gnu.org/onlinedocs/gccint/Libgcc.html&lt;/a&gt; 
  &lt;ul&gt; 
   &lt;li&gt;Data Definitions for libgcc_s - &lt;a href=&quot;https://refspecs.linuxfoundation.org/LSB_5.0.0/LSB-Core-generic/LSB-Core-generic/libgcc-s-ddefs.html&quot;&gt;https://refspecs.linuxfoundation.org/LSB_5.0.0/LSB-Core-generic/LSB-Core-generic/libgcc-s-ddefs.html&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Interfaces for libgcc_s - &lt;a href=&quot;https://refspecs.linuxfoundation.org/LSB_5.0.0/LSB-Core-generic/LSB-Core-generic/libgcc-s.html&quot;&gt;https://refspecs.linuxfoundation.org/LSB_5.0.0/LSB-Core-generic/LSB-Core-generic/libgcc-s.html&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Interfaces Definitions for libgcc_s - &lt;a href=&quot;https://refspecs.linuxfoundation.org/LSB_5.0.0/LSB-Core-generic/LSB-Core-generic/libgcc-sman.html&quot;&gt;https://refspecs.linuxfoundation.org/LSB_5.0.0/LSB-Core-generic/LSB-Core-generic/libgcc-sman.html&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;libunwind (nongnu.org) - &lt;a href=&quot;http://www.nongnu.org/libunwind/&quot;&gt;http://www.nongnu.org/libunwind/&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;libunwind (PathScale) - &lt;a href=&quot;https://github.com/pathscale/libunwind&quot;&gt;https://github.com/pathscale/libunwind&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;Programmatic access to the call stack in C++ - &lt;a href=&quot;https://eli.thegreenplace.net/2015/programmatic-access-to-the-call-stack-in-c/&quot;&gt;https://eli.thegreenplace.net/2015/programmatic-access-to-the-call-stack-in-c/&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;pstack: Print stack traces of running processes. Uses its own ELF and DWARF parsing 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/peadar/pstack&quot;&gt;https://github.com/peadar/pstack&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;quickstack: a tool to take call stack traces with minimal overheads 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/yoshinorim/quickstack&quot;&gt;https://github.com/yoshinorim/quickstack&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Unwind specification draft for GNU/Linux/ia64 (extends the exception ABI) - &lt;a href=&quot;https://www.kernel.org/pub/linux/devel/gcc/unwind/&quot;&gt;https://www.kernel.org/pub/linux/devel/gcc/unwind/&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;hr&gt; 
&lt;h1&gt;Talks&lt;/h1&gt; 
&lt;h2&gt;2019&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;Modern Linux C++ Debugging Tools: Under the Covers 
  &lt;ul&gt; 
   &lt;li&gt;CppCon 2019; Greg Law&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=WoRmXjVxuFQ&quot;&gt;https://www.youtube.com/watch?v=WoRmXjVxuFQ&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/CppCon/CppCon2019/tree/master/Presentations/modern_linux_cpp_debugging_tools__under_the_covers&quot;&gt;https://github.com/CppCon/CppCon2019/tree/master/Presentations/modern_linux_cpp_debugging_tools__under_the_covers&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;2018&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;GNU Tools Cauldron 2018 
  &lt;ul&gt; 
   &lt;li&gt;gOlogy: impact of -O* on -g 
    &lt;ul&gt; 
     &lt;li&gt;Alexandre Oliva&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;http://people.redhat.com/aoliva/writeups/gOlogy/slides.pdf&quot;&gt;http://people.redhat.com/aoliva/writeups/gOlogy/slides.pdf&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;http://www.fsfla.org/~lxoliva/writeups/gOlogy/gOlogy.txt&quot;&gt;http://www.fsfla.org/~lxoliva/writeups/gOlogy/gOlogy.txt&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;A collection of debug info improvements for the GNU Compiler Collection 
    &lt;ul&gt; 
     &lt;li&gt;Alexandre Oliva, Mark J. Wielaard&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://gnu.wildebeest.org/~mark/cauldron-2018/DebuginfoImprovements.pdf&quot;&gt;https://gnu.wildebeest.org/~mark/cauldron-2018/DebuginfoImprovements.pdf&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Let&apos;s Write a Debugger! 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://rego.linux.conf.au/schedule/presentation/91/&quot;&gt;linux.conf.au 2018&lt;/a&gt; - &lt;a href=&quot;https://www.doc.ic.ac.uk/~lk1015/publications.html&quot;&gt;Levente Kurusa&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.doc.ic.ac.uk/~lk1015/research/lca2018/talk_lca2018.pdf&quot;&gt;https://www.doc.ic.ac.uk/~lk1015/research/lca2018/talk_lca2018.pdf&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://opensource.com/article/18/1/how-debuggers-really-work&quot;&gt;https://opensource.com/article/18/1/how-debuggers-really-work&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=qS51kIHWARM&quot;&gt;https://www.youtube.com/watch?v=qS51kIHWARM&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/levex/debugger-talk&quot;&gt;https://github.com/levex/debugger-talk&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;2017&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;Debugging the debugger - BSDCan 2017, Samy Bahra 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=wyF-hGGPJMs&quot;&gt;https://www.youtube.com/watch?v=wyF-hGGPJMs&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Compiler debug quality suite - &lt;a href=&quot;https://github.com/backtrace-labs/cdqs&quot;&gt;https://github.com/backtrace-labs/cdqs&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://www.bsdcan.org/2017/schedule/events/787.en.html&quot;&gt;http://www.bsdcan.org/2017/schedule/events/787.en.html&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Debugging Under Fire: Keep your Head when Systems have Lost their Mind • GOTO 2017 • Bryan Cantrill 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=30jNsCVLpAE&quot;&gt;https://www.youtube.com/watch?v=30jNsCVLpAE&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;How C++ Debuggers work - Simon Brand 
  &lt;ul&gt; 
   &lt;li&gt;C++ Edinburgh 2018 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=UiW24hzLy1M&quot;&gt;https://www.youtube.com/watch?v=UiW24hzLy1M&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;Meeting C++ 2017 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://meetingcpp.com/2017/talks/items/How_Cpp_Debuggers_Work.html&quot;&gt;https://meetingcpp.com/2017/talks/items/How_Cpp_Debuggers_Work.html&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=Q3Rm95Mk03c&quot;&gt;https://www.youtube.com/watch?v=Q3Rm95Mk03c&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;2016&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;Building a Debugging Mindset - QConSF 2016 - Devon H. O&apos;Dell 
  &lt;ul&gt; 
   &lt;li&gt;video: &lt;a href=&quot;https://www.infoq.com/presentations/debugging-mindset&quot;&gt;https://www.infoq.com/presentations/debugging-mindset&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;slides: &lt;a href=&quot;https://speakerdeck.com/dho/building-a-debugging-mindset&quot;&gt;https://speakerdeck.com/dho/building-a-debugging-mindset&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;transcript: &lt;a href=&quot;https://9vx.org/post/building-a-debugging-mindset/&quot;&gt;https://9vx.org/post/building-a-debugging-mindset/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;How do Debuggers (Really) Work - Pawel Moll 
  &lt;ul&gt; 
   &lt;li&gt;Linux Piter 2016 - &lt;a href=&quot;https://www.youtube.com/watch?v=xqrxg3hl10o&quot;&gt;https://www.youtube.com/watch?v=xqrxg3hl10o&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;ELC 2015 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=N1QSEY1El9o&quot;&gt;https://www.youtube.com/watch?v=N1QSEY1El9o&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://vimeo.com/220644951&quot;&gt;https://vimeo.com/220644951&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;http://events.linuxfoundation.org/sites/events/files/slides/slides_16.pdf&quot;&gt;http://events.linuxfoundation.org/sites/events/files/slides/slides_16.pdf&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Post-mortem Debugging: could you be the one? - Surge 2016 - Abel Mathew 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=WHhorNLa934&quot;&gt;https://www.youtube.com/watch?v=WHhorNLa934&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Timeless Debugging - USENIX Enigma 2016 - George Hotz 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=eGl6kpSajag&quot;&gt;https://www.youtube.com/watch?v=eGl6kpSajag&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;2015&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;Debugging using an exact recording of a program&apos;s execution - C++Now 2015 - Julian Smith 
  &lt;ul&gt; 
   &lt;li&gt;Undo&apos;s Live Recorder&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=NWWMogzgLS4&quot;&gt;https://www.youtube.com/watch?v=NWWMogzgLS4&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;2014&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;The VS Debugger: How It Works + Tips and Tricks - GoingNative 28 - Gabriel Ha, Gregg Miskelly, Steve Carroll 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://channel9.msdn.com/Shows/C9-GoingNative/GoingNative-28-The-VS-Debugger-How-It-Works-Tips-and-Tricks&quot;&gt;https://channel9.msdn.com/Shows/C9-GoingNative/GoingNative-28-The-VS-Debugger-How-It-Works-Tips-and-Tricks&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>CRISP software design</title>
      <link>https://tedneward.github.io/Research/reading/development/crisp/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">reading/development/crisp/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://bitfieldconsulting.com/golang/crisp-code&quot;&gt;Article&lt;/a&gt;: Instead of &lt;a href=&quot;../clean-code&quot;&gt;CLEAN&lt;/a&gt; code, write code that is...&lt;/p&gt; 
&lt;h4&gt;Correct&lt;/h4&gt; 
&lt;p&gt;Your code may have lots of other wonderful things to be said for it, but if it’s not correct, they don’t really matter. And, indeed, if we’re willing to give up correctness, we can presumably obtain any other attribute fairly easily. It might seem obvious and not worth saying, but if incorrect code exists, and I think it does, then surely it is worth saying, because apparently someone didn’t get the memo.&lt;/p&gt; 
&lt;p&gt;What does it mean for code to be correct, actually? The straightforward answer is “it does what the writer intended”, but even that’s not quite right, because I might have intended the wrong thing! For example, I might write a prime number generator while labouring under the erroneous impression that all odd numbers are prime. In this case, my code might produce the odd integers, as I requested, but still not be correct.&lt;/p&gt; 
&lt;p&gt;A good suite of tests, again like apple pie, is something just about everyone would love to have, even if they don’t always feel like putting in the necessary labour. And tests are a necessary, though not sufficient, part of any good program. No doubt there are some correct programs that don’t have tests, but who knows which ones they are? A well-written test expresses what the programmer thinks the code should do under a given set of circumstances, and running it should give us a certain level of confidence about whether it actually does or not. Tests themselves can be incorrect, though.&lt;/p&gt; 
&lt;p&gt;This is one reason why we need to be very suspicious and sceptical of any given test. What does it look like it says? Does it actually say that? Is it the right thing to say? If it verifies the program’s result against some expected result, is the expectation correct? If the test claims to cover some particular section of code, does it actually test the behaviour of that code in all important ways, or does it merely cause it to be executed?&lt;/p&gt; 
&lt;p&gt;Not having tests is a terrible situation to be in, but it’s actually slightly preferable to having tests that don’t work. A malfunctioning or insufficient test may give us false confidence in code that also happens to be incorrect. Therefore, once you’ve written your tests, read them all again extremely carefully, with an adversarial eye. Programmers are incurable optimists: we always think our code will work, despite much evidence to the contrary. Instead, we should assume that if there can be a bug, then there is a bug. Humility isn’t a virtue often associated with software engineers, but it’s certainly something that good test writers know all about.&lt;/p&gt; 
&lt;p&gt;Even the most thoroughly tested code should not be assumed to be correct. It should be assumed to be incorrect. It almost certainly is.&lt;/p&gt; 
&lt;p&gt;&lt;em&gt;(Sounds more like &quot;Correct&quot; should be &quot;Testable&quot; or &quot;Verifiable&quot;, if you ask me.)&lt;/em&gt;&lt;/p&gt; 
&lt;h4&gt;Readable&lt;/h4&gt; 
&lt;p&gt;Again, this might sound like something that doesn’t need saying: who’s arguing for unreadable code? Not me, but there seems to be a lot of it around, all the same. It’s not that anyone deliberately sets out to write unreadable code, of course; it just ends up that way because we mistakenly prioritise other virtues over readability.&lt;/p&gt; 
&lt;p&gt;Performance is one such virtue, and there are cases where performance genuinely matters. Not as many as you might think, though: computers are pretty fast these days, and since most of what they do is in the service of us humans, they can usually afford to take their time about it.&lt;/p&gt; 
&lt;p&gt;So, while readability isn’t quite as important as correctness, it’s more important than anything else. Readability, as Churchill said of courage, is rightly esteemed the first of qualities, because it is the quality which guarantees all others.&lt;/p&gt; 
&lt;p&gt;What is it that makes code readable, or not? I don’t think readability is something that you can add to your code: I think it’s what you’re left with when you’ve taken away all the things that make it hard to understand.&lt;/p&gt; 
&lt;p&gt;For example, a poorly-chosen variable name can put a bump in the reader’s path. Using different names for the same thing, or the same name for different things, is confusing. An unnecessary function call, added purely to satisfy some rule like “methods should be less than 10 lines”, breaks the reader’s flow.&lt;/p&gt; 
&lt;p&gt;It’s like reading an article and coming across an unfamiliar word: should you pause to look it up, and risk losing the train of thought, or struggle on and try to infer the meaning from context?&lt;/p&gt; 
&lt;p&gt;The best way to make any code more readable is, oddly enough, to start by reading it. But I mean something special by that. I don’t mean scrolling hurriedly through pages and pages of code, glancing and skimming to get a sense of what’s happening. That is a useful skill, but for other tasks.&lt;/p&gt; 
&lt;p&gt;Instead, we need to read code in a careful, sequential, intentional way. We need to begin at the beginning, and go on till we come to the end. If it’s not clear where the program begins, then that’s the first thing we need to fix.&lt;/p&gt; 
&lt;p&gt;As we follow the thread of execution of the program, we need to read each line carefully and then try to answer two questions about it:&lt;/p&gt; 
&lt;ol&gt; 
 &lt;li&gt;What does it say?&lt;/li&gt; 
 &lt;li&gt;What does it mean?&lt;/li&gt; 
&lt;/ol&gt; 
&lt;p&gt;For example, consider the following line:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;requests++
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;What it says is clear: it increases the value of some numeric variable requests by one. What’s not so easy to work out is what that means. What is being counted in the requests variable? Why is it being incremented? What significance does that have? Where did requests get its current value? What is its current value? When and where will that value be checked? Is there some maximum value? What happens when we reach it? And so on.&lt;/p&gt; 
&lt;p&gt;There may be perfectly good answers to all these questions, but that’s not the point. The point is, can the reader answer them just by looking at the code? If not, what can we do to provide the answers, or make them easier to find? By reading our own code as though we were new to it, we see it with fresh eyes and discover the parts that need more cognitive effort to follow.&lt;/p&gt; 
&lt;p&gt;&lt;em&gt;(Goes back to the fundamental question: What is &quot;good code&quot;?)&lt;/em&gt;&lt;/p&gt; 
&lt;h4&gt;Idiomatic&lt;/h4&gt; 
&lt;p&gt;I don’t think this is quite the right word: I’d prefer “conventional”, but again that doesn’t fit with the CRISP backronym. Still, when people say “such and such is idiomatic”, what they really mean is “this is the conventional way to do it.”&lt;/p&gt; 
&lt;p&gt;Conventions are useful: there are lots of possible ways to lay out the controls for a car, for example, and the one we’re used to isn’t demonstrably optimal. We’re just used to it. There’s no law stopping a car manufacturer from putting the pedals in a different arrangement, but they don’t. Even if there were some demonstrable benefit, it wouldn’t be worth the cognitive cost to users: getting confused between the accelerator and brake pedal would be unfortunate.&lt;/p&gt; 
&lt;p&gt;Similarly, I think there’s great value in using conventional names for things: in an HTTP handler, the request pointer is always called r and the response writer w. If there’s a universal convention, it’s worth following. You’ll also have local and personal conventions. In my code, an arbitrary bytes.Buffer is always named buf, the compared values in my tests are always named want and got, and so on.&lt;/p&gt; 
&lt;p&gt;An obvious example of a universal convention is err: Go programmers always use this name to refer to an arbitrary error value. While we wouldn’t usually re-use variable names within the same function, we do re-use err for all the various errors that there can be throughout the function. It’s a mistake to try to avoid this by creating variant names like err2, err3, and so on.&lt;/p&gt; 
&lt;p&gt;Why? Because it requires a tiny bit more cognitive effort from the reader. If you see err, your mind glides right over it with perfect understanding. If you see some other name, your mind has to stop to resolve the puzzle.&lt;/p&gt; 
&lt;p&gt;I call these tiny roadblocks “cognitive microaggressions”. Each is so tiny that its individual effect is almost unnoticeable, yet they soon pile up, and if you encounter them all day and every day, they have a significant effect on your quality of life.&lt;/p&gt; 
&lt;p&gt;As you write each line of code, you should be thinking “How much effort does it take to understand this? Could I reduce that somehow?” The secret of great software engineering is doing a lot of little things well. Picking the right names, organising code in a logical fashion, having one idea per line of code: all these go towards cumulatively making your code readable and pleasant to work with.&lt;/p&gt; 
&lt;p&gt;How do you learn what’s idiomatic and conventional? By reading other people’s programs, in the same careful and intentional way that we read our own. You can’t write a good novel if you’ve never read a novel, and the same applies to programming.&lt;/p&gt; 
&lt;p&gt;Programs found in the wild are of variable quality, and you should make sure to sample as wide a range as you can. It’s just as useful to read bad programs as good ones, though for different reasons. You’ll find mistakes even in good programs, and when you do, you’ll have learned something. But the most useful thing of all is to learn what everybody does.&lt;/p&gt; 
&lt;p&gt;&lt;em&gt;(This is probably the bigger issue around good code, because the code needs to be readable far more than it needs to be anything else. Now, the hard part is, how do we think about &quot;conventional&quot; here such that it can be measurable or testable, as in via static language analysis tools?)&lt;/em&gt;&lt;/p&gt; 
&lt;h4&gt;Simple&lt;/h4&gt; 
&lt;p&gt;Ah, simplicity. Is there any more slippery and deceptive concept? Everyone thinks they know simplicity when they see it, but oddly enough no two people agree on what “simple” means in practice. As Rich Hickey has pointed out, simple isn’t the same as easy. “Easy” is familiar, low-effort, the thing we reach for without thinking. That usually results in “complex”, so getting it to “simple” can take a good deal of effort and thought.&lt;/p&gt; 
&lt;p&gt;One attribute that simple code tends to have is directness: it does just what it says on the tin. It doesn’t have weird and unexpected side effects, or conflate several unrelated things. Directness is inversely related to concision: if there are three similar tasks to do, a simple program will do it with three similar functions.&lt;/p&gt; 
&lt;p&gt;This is one reason people find it hard to write simple code: we’re all terrified of repeating ourselves. The DRY principle is so ingrained that we even use it as a verb: “we need to DRY up this function” (as Calvin noted, verbing weirds language).&lt;/p&gt; 
&lt;p&gt;&lt;em&gt;(I am just one good push away from writing a &quot;DRY is an antipattern&quot; post.)&lt;/em&gt;&lt;/p&gt; 
&lt;p&gt;But there’s nothing wrong with repetition in itself. I say again, there’s nothing wrong with repetition in itself (see?) It can be a valuable way of conveying emphasis. And if we find ourselves creating new abstractions to no purpose other than avoiding repetition, then we’ve gone wrong somewhere: that makes the program more complex, not more simple.&lt;/p&gt; 
&lt;p&gt;That leads us to another aspect of simplicity: frugality. Doing a lot with a little. A package that does one thing is simpler than one that does ten things. The fewer functions there are, and the shallower the stack, the simpler the program. That might result in some long functions, and that’s okay. All due respect to Uncle Bob, but a function should be as long as it needs to be. Adding complexity purely to reduce the length of a function is a good example of a blindly-applied rule defeating common sense.&lt;/p&gt; 
&lt;p&gt;Simplicity, as Alan Perlis observed, does not precede complexity, but follows it. In other words, write the program first, then make it simple. Read the code and ask what it says, then ask yourself if you can find a simpler way to write the same thing.&lt;/p&gt; 
&lt;p&gt;Another place you can find simplicity is in naturalness. Any given language has its own Tao, its own natural forms and structures, and working with them generally gets better results than working against them. For example, you can use Go as though it were Java, or Python, or Rust, but it’s simpler to write Go programs in Go. Easier, too. &lt;em&gt;(This goes back to conventionality, I think.)&lt;/em&gt;&lt;/p&gt; 
&lt;h4&gt;Performant&lt;/h4&gt; 
&lt;p&gt;You might think it strange that I’ve listed this one last. Isn’t practically everything you hear or read about programming related to performance in some way? Yes, it is. But I don’t think that’s necessarily because performance is important so much as that it’s easy to talk about. What can be measured is what will be maximised, and it’s easy to measure performance: you can use a stopwatch. It’s much harder to quantify things like simplicity, or even correctness. But if the code isn’t correct, who cares how fast it runs? To put it another way, we can make a given function arbitrarily efficient if it doesn’t have to be correct.&lt;/p&gt; 
&lt;p&gt;Similarly, if it’s not simple, we will waste far more programmer time on understanding it than we could ever have shaved off the CPU time it takes. And programmers are more expensive to run, per hour, than any CPU. Doesn’t it make sense to write code in a way that optimises for programmer time, not CPU time? As I’ve noted elsewhere, performance doesn’t matter for the vast majority of programs. When it does, the best solution isn’t usually to make your code harder to read. The saying “slow is smooth, and smooth is fast” applies here. If you tangle up your program in hopeless complexity to save a couple of microseconds off some loop, great, but that’s the last optimisation anyone will ever make to it. Attempting to speed up complex code is usually counterproductive, because if you don’t understand it you can’t optimise it. On the other hand, simple programs are easy to speed up when you have to.&lt;/p&gt; 
&lt;p&gt;Nevertheless, we should be aware of the performance implications of the choices we make. If we didn’t need this task doing fairly quickly, we wouldn’t have given it to a computer. Another way to think about it is that an efficient program can do more in a given time, even if the actual time taken is irrelevant.&lt;/p&gt; 
&lt;p&gt;To be fair, even an inefficient program will run pretty fast: “the inside of a computer is dumb as hell,” Richard Feynman observed, “but it goes like mad”. That’s not to say that we can afford to waste compute cycles, because all computation costs energy, and we are already heating up our planet at a ludicrously unsustainable rate. It would be a shame if we ended up emitting a few extra gigatons of carbon just because we made some clumsy choice of data structure.&lt;/p&gt; 
&lt;p&gt;The idea of “mechanical sympathy” is helpful to bear in mind when you’re programming. It means that you have some understanding of how the machine works, fundamentally, and you take care not to abuse it or get in its way. For example, if you don’t know what memory is, how can you write efficient programs?&lt;/p&gt; 
&lt;p&gt;I often see code that blithely slurps in entire data files into a single structure, then proceeds to actually process them just a few bytes at a time. I learned to program on a machine with 1K of memory, or about a thousand words, and that will teach you the value of a byte, believe me. I’m writing this, some years later, on a machine with about 16 million words of memory, and don’t run out of them quite so frequently, but nonetheless, memory matters. &lt;em&gt;(Ehh.... it matters when it matters, but not until then. Getting it right still trumps getting it fast.)&lt;/em&gt;&lt;/p&gt; 
&lt;p&gt;For one thing, the more data you’re schlepping around the system, the longer it takes. And for another thing, however big your Kubernetes cluster, it nonetheless consists of physical machines with fixed, finite memory, and no container can use more than the total RAM of a single node. So look after your bytes, and the gigabytes will look after themselves. &lt;em&gt;(Yeah, not sure I&apos;m a fan of this, tbh. Performance should be a deliberate choice, not something that is done by rote.)&lt;/em&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Clean Code</title>
      <link>https://tedneward.github.io/Research/reading/development/clean-code/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">reading/development/clean-code/index.html</guid>
      	<description>
	&lt;p&gt;&lt;em&gt;(by Robert Martin, aka &quot;Uncle Bob&quot;, aka &quot;the most misogynistic man in tech&quot;)&lt;/em&gt;&lt;/p&gt; 
&lt;p&gt;A nice &lt;a href=&quot;https://qntm.org/clean&quot;&gt;takedown&lt;/a&gt; of the book.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Reading list: Computer Science</title>
      <link>https://tedneward.github.io/Research/reading/development/compsci/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">reading/development/compsci/index.html</guid>
      	<description>
	&lt;h1&gt;Intermediate-level material&lt;/h1&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://smile.amazon.com/Algorithm-Design-Manual-Steven-Skiena/dp/1848000693/&quot;&gt;&lt;em&gt;The Algorithm Design Manual&lt;/em&gt;&lt;/a&gt;, with &lt;a href=&quot;https://www3.cs.stonybrook.edu/~skiena/373/videos/&quot;&gt;video lectures&lt;/a&gt; from the author (Steven Skiena).&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://smile.amazon.com/How-Solve-Mathematical-Princeton-Science/dp/069116407X/&quot;&gt;&lt;em&gt;How to Solve It&lt;/em&gt;&lt;/a&gt; by Polya, and there&apos;s a &lt;a href=&quot;https://www.amazon.com/How-Solve-Heuristics-Zbigniew-Michalewicz/dp/3540224947&quot;&gt;modern edition&lt;/a&gt; that&apos;s more expansive and detailed. Both should be read, front to back.&lt;/li&gt; 
 &lt;li&gt;&lt;em&gt;Structure and Interpretation of Computer Programs&lt;/em&gt; (SICP): &lt;a href=&quot;https://mitpress.mit.edu/sites/default/files/sicp/full-text/book/book.html&quot;&gt;book&lt;/a&gt; and &lt;a href=&quot;http://ocw.mit.edu/courses/electrical-engineering-and-computer-science/6-001-structure-and-interpretation-of-computer-programs-spring-2005/video-lectures/&quot;&gt;MIT video lectures&lt;/a&gt; or &lt;a href=&quot;https://archive.org/details/ucberkeley-webcast-PL3E89002AA9B9879E?sort=titleSorter&quot;&gt;Brian Harvey&apos;s SICP lectures, UCBerkeley 61A&lt;/a&gt;. Mind-blowing concepts around code, data, and the malleability of the two that comes from spending time in a Lisp/Scheme. 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://composingprograms.com/&quot;&gt;&lt;em&gt;Composing Programs&lt;/em&gt;&lt;/a&gt;, &quot;in the tradition&quot; of SICP but uses Python&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://www.htdp.org/&quot;&gt;&lt;em&gt;How to Design Programs&lt;/em&gt;&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h1&gt;Most influential books for programmers&lt;/h1&gt; 
&lt;p&gt;These are books considered most influential for programmers from this &lt;a href=&quot;http://stackoverflow.com/questions/1711/what-is-the-single-most-influential-book-every-programmer-should-read&quot;&gt;StackOverflow thread&lt;/a&gt;.&lt;/p&gt; 
&lt;h2&gt;Influential Books List&lt;/h2&gt; 
&lt;p&gt;&lt;em&gt;(I need to break this list out into other list categories)&lt;/em&gt;&lt;/p&gt; 
&lt;ol&gt; 
 &lt;li&gt;&lt;a href=&quot;http://cc2e.com/&quot;&gt;Code Complete (2nd edition)&lt;/a&gt; by Steve McConnell&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://pragprog.com/the-pragmatic-programmer&quot;&gt;The Pragmatic Programmer&lt;/a&gt; by Andrew Hunt and David Thomas&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://cm.bell-labs.com/cm/cs/cbook/&quot;&gt;The C Programming Language&lt;/a&gt; by Brian Kernighan and Dennis Ritchie&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://mitpress.mit.edu/books/introduction-algorithms&quot;&gt;Introduction to Algorithms&lt;/a&gt; by Cormen, Leiserson, Rivest &amp;amp; Stein&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://c2.com/cgi/wiki?DesignPatternsBook&quot;&gt;Design Patterns&lt;/a&gt; by the Gang of Four&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://martinfowler.com/books/refactoring.html&quot;&gt;Refactoring: Improving the Design of Existing Code&lt;/a&gt; by Martin Fowler&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.amazon.com/The-Mythical-Man-Month-Engineering-Anniversary/dp/0201835959&quot;&gt;The Mythical Man Month&lt;/a&gt; by Fred Brooks&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www-cs-faculty.stanford.edu/~uno/taocp.html&quot;&gt;The Art of Computer Programming&lt;/a&gt; by Donald Knuth&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.amazon.com/Compilers-Principles-Techniques-Tools-Edition/dp/0321486811&quot;&gt;Compilers: Principles, Techniques and Tools&lt;/a&gt; by Alfred V. Aho, Ravi Sethi and Jeffrey D. Ullman&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.amazon.com/G%C3%B6del-Escher-Bach-Eternal-Golden/dp/0465026567&quot;&gt;Gödel, Escher, Bach&lt;/a&gt; by Douglas Hofstadter&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.aristeia.com/books.html&quot;&gt;Effective C++&lt;/a&gt; by Scott Meyers&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.aristeia.com/books.html&quot;&gt;More Effective C++&lt;/a&gt; by Scott Meyers&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.charlespetzold.com/code/&quot;&gt;CODE&lt;/a&gt; by Charles Petzold&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.cs.bell-labs.com/cm/cs/pearls/&quot;&gt;Programming Pearls&lt;/a&gt; by Jon Bentley&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.informit.com/store/working-effectively-with-legacy-code-9780131177055?aid=15d186bd-1678-45e9-8ad3-fe53713e811b&quot;&gt;Working Effectively with Legacy Code&lt;/a&gt; by Michael C. Feathers&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.amazon.com/Peopleware-Productive-Projects-Second-Edition/dp/0932633439&quot;&gt;Peopleware&lt;/a&gt; by Demarco and Lister&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.codersatwork.com/&quot;&gt;Coders at Work&lt;/a&gt; by Peter Seibel&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.amazon.com/Surely-Feynman-Adventures-Curious-Character/dp/0393316041&quot;&gt;Surely You&apos;re Joking, Mr. Feynman!&lt;/a&gt; by Richard Feynman&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.amazon.com/Effective-Java-Edition-Joshua-Bloch/dp/0321356683&quot;&gt;Effective Java 2nd edition&lt;/a&gt; by Joshua Bloch&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://martinfowler.com/books/eaa.html&quot;&gt;Patterns of Enterprise Application Architecture&lt;/a&gt; by Martin Fowler&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://mitpress.mit.edu/books/little-schemer-fourth-edition&quot;&gt;The Little Schemer&lt;/a&gt; by Matthias Felleisen and Daniel P. Friedman&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://mitpress.mit.edu/books/seasoned-schemer-second-edition&quot;&gt;The Seasoned Schemer&lt;/a&gt; by Matthias Felleisen and Daniel P. Friedman&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.rubyinside.com/media/poignant-guide.pdf&quot;&gt;Why&apos;s (Poignant) Guide to Ruby&lt;/a&gt; by why the lucky stiff (free PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.amazon.com/The-Inmates-Are-Running-Asylum/dp/0672326140&quot;&gt;The Inmates Are Running The Asylum: Why High Tech Products Drive Us Crazy and How to Restore the Sanity&lt;/a&gt; by Alan Cooper&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.catb.org/~esr/writings/taoup/&quot;&gt;The Art of Unix Programming&lt;/a&gt; by Eric S. Raymond&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.eecs.yorku.ca/course_archive/2003-04/W/3311/sectionM/case_studies/money/KentBeck_TDD_byexample.pdf&quot;&gt;Test-Driven Development: By Example&lt;/a&gt; by Kent Beck (free PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://pragprog.com/book/pad/practices-of-an-agile-developer&quot;&gt;Practices of an Agile Developer&lt;/a&gt; by Venkat Subramaniam and Andy Hunt&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.sensible.com/dmmt.html&quot;&gt;Don&apos;t Make Me Think&lt;/a&gt; by Steve Krug&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.amazon.com/Software-Development-Principles-Patterns-Practices/dp/0135974445&quot;&gt;Agile Software Development, Principles, Patterns, and Practices&lt;/a&gt; by Robert C. Martin&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.amazon.com/Domain-Driven-Design-Tackling-Complexity-Software/dp/0321125215&quot;&gt;Domain Driven Designs&lt;/a&gt; by Eric Evans&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.jnd.org/books/the-design-of-everyday-things.html&quot;&gt;The Design of Everyday Things&lt;/a&gt; by Donald Norman&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://erdani.com/index.php/books/modern-c-design/&quot;&gt;Modern C++ Design&lt;/a&gt; by Andrei Alexandrescu&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://joelonsoftware.com/articles/BestSoftwareWriting.html&quot;&gt;Best Software Writing I&lt;/a&gt; by Joel Spolsky&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://cm.bell-labs.com/cm/cs/tpop/&quot;&gt;The Practice of Programming&lt;/a&gt; by Kernighan and Pike&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://pragprog.com/press_releases/pragmatic-thinking-and-learning-refactor-your-wetware&quot;&gt;Pragmatic Thinking and Learning: Refactor Your Wetware&lt;/a&gt; by Andy Hunt&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.stevemcconnell.com/est.htm&quot;&gt;Software Estimation: Demystifying the Black Art&lt;/a&gt; by Steve McConnel&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://pragprog.com/book/cfcar2/the-passionate-programmer&quot;&gt;The Passionate Programmer&lt;/a&gt; by Chad Fowler&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.gutenberg.org/ebooks/729&quot;&gt;Hackers: Heroes of the Computer Revolution&lt;/a&gt; by Steven Levy (free ebook)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.ethoberon.ethz.ch/WirthPubl/AD.pdf&quot;&gt;Algorithms + Data Structures = Programs&lt;/a&gt; by Niklaus Wirth (free PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://c2.com/cgi/wiki?WritingSolidCode&quot;&gt;Writing Solid Code&lt;/a&gt; by Steve Maguire&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://javascript.crockford.com/&quot;&gt;JavaScript - The Good Parts&lt;/a&gt; by Douglas Crockford&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://gettingreal.37signals.com/&quot;&gt;Getting Real&lt;/a&gt; by 37 Signals (free PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://openmymind.net/FoundationsOfProgramming.pdf&quot;&gt;Foundations of Programming&lt;/a&gt; by Karl Seguin (free PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.amazon.com/Computer-Graphics-Principles-Practice-Edition/dp/0201848406&quot;&gt;Computer Graphics: Principles and Practice in C (2nd Edition)&lt;/a&gt; by Foley, Dam, Feiner, Hughes&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.mindviewinc.com/Books/TIJ4/&quot;&gt;Thinking in Java&lt;/a&gt; by Bruce Eckel&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.nand2tetris.org/&quot;&gt;The Elements of Computing Systems&lt;/a&gt; by Noam Nisan and Shimon Schocken(free ebook)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://industriallogic.com/xp/refactoring/&quot;&gt;Refactoring to Patterns&lt;/a&gt; by Joshua Kerievsky&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.cs.vu.nl/~ast/books/mos2/&quot;&gt;Modern Operating Systems&lt;/a&gt; by Andrew S. Tanenbaum&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.theannotatedturing.com/&quot;&gt;The Annotated Turing&lt;/a&gt; by Charles Petzold&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.jnd.org/books/things-that-make-us-smart-defending-human-attributes-in-the-age-of-the-machine.html&quot;&gt;Things That Make Us Smart&lt;/a&gt; by Donald Norman&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.amazon.com/The-Timeless-Building-Christopher-Alexander/dp/0195024028&quot;&gt;The Timeless Way of Building&lt;/a&gt; by Christopher Alexander&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://tomdemarco.com/Books/deadline.html&quot;&gt;The Deadline: A Novel About Project Management&lt;/a&gt; by Tom DeMarco&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.stroustrup.com/3rd.html&quot;&gt;The C++ Programming Language (3rd edition)&lt;/a&gt; by Stroustrup&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://csapp.cs.cmu.edu/&quot;&gt;Computer Systems - A Programmer&apos;s Perspective&lt;/a&gt; by Bryant and O&apos;Hallaron&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.amazon.com/Agile-Principles-Patterns-Practices-C/dp/0131857258&quot;&gt;Agile Principles, Patterns, and Practices in C#&lt;/a&gt; by Robert C. Martin&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.growing-object-oriented-software.com/&quot;&gt;Growing Object-Oriented Software, Guided by Tests&lt;/a&gt; by Steve Freeman and Nat Pryce&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.amazon.com/Framework-Design-Guidelines-Conventions-Libraries/dp/0321545613&quot;&gt;Framework Design Guidelines&lt;/a&gt; by Brad Abrams&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.microsoft.com/learning/en-us/book.aspx?ID=6820&quot;&gt;Object Thinking&lt;/a&gt; by Dr. David West&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.cs.stevens.edu/~jschauma/810D/&quot;&gt;Advanced Programming in the UNIX Environment&lt;/a&gt; by W. Richard Stevens&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.paulgraham.com/hackpaint.html&quot;&gt;Hackers and Painters: Big Ideas from the Computer Age&lt;/a&gt; by Paul Graham&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.tracykidder.com/books/soul/&quot;&gt;The Soul of a New Machine&lt;/a&gt; by Tracy Kidder&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://shop.oreilly.com/product/9780735627048.do&quot;&gt;CLR via C#&lt;/a&gt; by Jeffrey Richter&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.amazon.com/Design-Patterns-C-Software/dp/0321718933&quot;&gt;Design Patterns in C#&lt;/a&gt; by Steve Metsker&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.amazon.com/Zen-Art-Motorcycle-Maintenance-Inquiry/dp/0060589469&quot;&gt;Zen and the Art of Motorcycle Maintenance&lt;/a&gt; by Robert M. Pirsig&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.amazon.com/About-Face-Essentials-Interaction-Design/dp/0470084111&quot;&gt;About Face - The Essentials of Interaction Design&lt;/a&gt; by Alan Cooper&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.amazon.com/Here-Comes-Everybody-Organizing-Organizations/dp/0143114948&quot;&gt;Here Comes Everybody: The Power of Organizing Without Organizations&lt;/a&gt; by Clay Shirky&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.canonical.org/~kragen/tao-of-programming.html&quot;&gt;The Tao of Programming&lt;/a&gt; by Geoffrey James (free ebook)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://mitpress.mit.edu/books/computational-beauty-nature&quot;&gt;Computational Beauty of Nature&lt;/a&gt; by Gary William Flake&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://philip.greenspun.com/panda/&quot;&gt;Philip and Alex&apos;s Guide to Web Publishing&lt;/a&gt; (free ebook)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.amazon.com/Object-Oriented-Analysis-Design-Applications-Edition/dp/020189551X&quot;&gt;Object-Oriented Analysis and Design with Applications&lt;/a&gt; by Grady Booch&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.amazon.com/Computability-Introduction-Recursive-Function-Theory/dp/0521294657&quot;&gt;Computability&lt;/a&gt; by N. J. Cutland&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.amazon.com/Masterminds-Programming-Conversations-Creators-Languages/dp/0596515170&quot;&gt;Masterminds of Programming&lt;/a&gt; by Federico Biancuzzi&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://acc6.its.brooklyn.cuny.edu/~phalsall/texts/taote-v3.html&quot;&gt;The Tao Te Ching&lt;/a&gt; by Lao-tzu&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://nealford.com/books/productiveprogrammer&quot;&gt;The Productive Programmer&lt;/a&gt; by Neil Ford&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.amazon.com/exec/obidos/tg/detail/-/0764569597&quot;&gt;The Art of Deception&lt;/a&gt; by Kevin Mitnick&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.christopherduncan.com/thecareerprogrammer.aspx&quot;&gt;The Career Programmer: Guerilla Tactics for an Imperfect World&lt;/a&gt; by Christopher Duncan&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://norvig.com/paip.html&quot;&gt;Paradigms of Artificial Intelligence Programming: Case studies in Common Lisp&lt;/a&gt; by Peter Norvig (free ebook)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.amazon.com/Masters-Doom-Created-Transformed-Culture/dp/0812972155&quot;&gt;Masters of Doom&lt;/a&gt; by David Kushner&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://pragprog.com/book/utc2/pragmatic-unit-testing-in-c-with-nunit&quot;&gt;Pragmatic Unit Testing in C# with NUnit&lt;/a&gt; by Andy Hunt and Dave Thomas&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://notendur.hi.is/hei2/teaching/Polya_HowToSolveIt.pdf&quot;&gt;How To Solve It&lt;/a&gt; by George Polya (free PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://stephane.ducasse.free.fr/FreeBooks/BlueBook/Bluebook.pdf&quot;&gt;Smalltalk-80: The Language and its Implementation&lt;/a&gt; by Adele Goldberg&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.microsoft.com/learning/en-us/book.aspx?ID=5957&quot;&gt;Writing Secure Code (2nd Edition)&lt;/a&gt; by Michael Howard&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.cs.ox.ac.uk/publications/publication2613-abstract.html&quot;&gt;Introduction to Functional Programming&lt;/a&gt; by Richard Bird&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.amazon.com/No-Bugs-Delivering-Error-Free/dp/0201608901&quot;&gt;No Bugs!&lt;/a&gt; by David Thielen&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.manning.com/tahchiev/&quot;&gt;JUnit in Action&lt;/a&gt; by Petar Tahchiev&lt;/li&gt; 
&lt;/ol&gt;
	</description>
    </item>
    <item>
      <title>Continuation-passing style</title>
      <link>https://tedneward.github.io/Research/reading/development/cps/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">reading/development/cps/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Continuation-passing_style&quot;&gt;Wikipedia&lt;/a&gt;:&lt;br&gt; ... a style of programming in which control is passed explicitly in the form of a continuation. ... A function written in continuation-passing style takes an extra argument: an explicit &quot;continuation&quot;; i.e., a function of one argument. When the CPS function has computed its result value, it &quot;returns&quot; it by calling the continuation function with this value as the argument. That means that when invoking a CPS function, the calling function is required to supply a procedure to be invoked with the subroutine&apos;s &quot;return&quot; value. Expressing code in this form makes a number of things explicit which are implicit in direct style. These include: procedure returns, which become apparent as calls to a continuation; intermediate values, which are all given names; order of argument evaluation, which is made explicit; and tail calls, which simply call a procedure with the same continuation, unmodified, that was passed to the caller.&lt;/p&gt; 
&lt;p&gt;In CPS, each procedure takes an extra argument representing what should be done with the result the function is calculating. This, along with a restrictive style prohibiting a variety of constructs usually available, is used to expose the semantics of programs, making them easier to analyze. This style also makes it easy to express unusual control structures, like catch/throw or other non-local transfers of control.&lt;/p&gt; 
&lt;p&gt;The key to CPS is to remember that (a) every function takes an extra argument known as its continuation, and (b) every argument in a function call must be either a variable or a lambda expression (not a more complex expression). This has the effect of turning expressions &quot;inside-out&quot; because the innermost parts of the expression must be evaluated first, thus CPS makes explicit the order of evaluation as well as the control flow. Some examples of code in direct style and the corresponding CPS appear below. These examples are written in the Scheme programming language; by convention the continuation function is represented as a parameter named &quot;k&quot;:&lt;/p&gt; 
&lt;p&gt;Direct style:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;(define (pyth x y)
  (sqrt (+ (* x x) (* y y))))
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;CPS:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;(define (pyth&amp;amp; x y k)
 (*&amp;amp; x x (lambda (x2)
          (*&amp;amp; y y (lambda (y2)
                   (+&amp;amp; x2 y2 (lambda (x2py2)
                              (sqrt&amp;amp; x2py2 k))))))))
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Direct style:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;(define (factorial n)
 (if (= n 0)
     1     ; NOT tail-recursive
     (* n (factorial (- n 1)))))
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;CPS:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;(define (factorial&amp;amp; n k)
 (=&amp;amp; n 0 (lambda (b)
          (if b                    ; growing continuation
              (k 1)                ; in the recursive call
              (-&amp;amp; n 1 (lambda (nm1)
                       (factorial&amp;amp; nm1 (lambda (f)
                                        (*&amp;amp; n f k)))))))))
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Direct style:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;(define (factorial n)
 (f-aux n 1))
(define (f-aux n a)
 (if (= n 0)
     a        ; tail-recursive
     (f-aux (- n 1) (* n a))))
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;CPS:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;(define (factorial&amp;amp; n k) (f-aux&amp;amp; n 1 k))
(define (f-aux&amp;amp; n a k)
 (=&amp;amp; n 0 (lambda (b)
          (if b                    ; unmodified continuation
              (k a)                ; in the recursive call
              (-&amp;amp; n 1 (lambda (nm1) 
                       (*&amp;amp; n a (lambda (nta)
                                (f-aux&amp;amp; nm1 nta k)))))))))
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Functions using more than one continuation can be defined to capture various control flow paradigms, for example (in Scheme):&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;(define (/&amp;amp; x y ok err)
 (=&amp;amp; y 0.0 (lambda (b)
            (if b
                (err (list &quot;div by zero!&quot; x y))
                (ok (/ x y))))))
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;Haskell examples&lt;/h3&gt; 
&lt;p&gt;Direct:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;pow2 :: Float -&amp;gt; Float
pow2 a = a ** 2

add :: Float -&amp;gt; Float -&amp;gt; Float
add a b = a + b

pyth :: Float -&amp;gt; Float -&amp;gt; Float
pyth a b = sqrt (add (pow2 a) (pow2 b))
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;CPS:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;pow2&apos; :: Float -&amp;gt; (Float -&amp;gt; a) -&amp;gt; a
pow2&apos; a cont = cont (a ** 2)

add&apos; :: Float -&amp;gt; Float -&amp;gt; (Float -&amp;gt; a) -&amp;gt; a
add&apos; a b cont = cont (a + b)

-- Types a -&amp;gt; (b -&amp;gt; c) and a -&amp;gt; b -&amp;gt; c are equivalent, so CPS function
-- may be viewed as a higher order function
sqrt&apos; :: Float -&amp;gt; ((Float -&amp;gt; a) -&amp;gt; a)
sqrt&apos; a = \cont -&amp;gt; cont (sqrt a)

pyth&apos; :: Float -&amp;gt; Float -&amp;gt; (Float -&amp;gt; a) -&amp;gt; a
pyth&apos; a b cont = pow2&apos; a (\a2 -&amp;gt; pow2&apos; b (\b2 -&amp;gt; add&apos; a2 b2 (\anb -&amp;gt; sqrt&apos; anb cont)))
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;Continuations as objects&lt;/h3&gt; 
&lt;p&gt;Programming with continuations can also be useful when a caller does not want to wait until the callee completes. For example, in user-interface (UI) programming, a routine can set up dialog box fields and pass these, along with a continuation function, to the UI framework. This call returns right away, allowing the application code to continue while the user interacts with the dialog box. Once the user presses the &quot;OK&quot; button, the framework calls the continuation function with the updated fields.&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;function confirmName() {
    fields.name = name;
    framework.Show_dialog_box(fields, confirmNameContinuation);
}

function confirmNameContinuation(fields) {
    name = fields.name;
}
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;A similar idea can be used when the function must run in a different thread or on a different processor. The framework can execute the called function in a worker thread, then call the continuation function in the original thread with the worker&apos;s results. This is in Java 8 using the Swing UI framework:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;void buttonHandler() {
    // This is executing in the Swing UI thread.
    // We can access UI widgets here to get query parameters.
    int parameter = getField();

    new Thread(() =&amp;gt; {
        // This code runs in a separate thread.
        // We can do things like access a database or a 
        // blocking resource like the network to get data.
        int result = lookup(parameter);

        javax.swing.SwingUtilities.invokeLater(() =&amp;gt; {
            // This code runs in the UI thread and can use
            // the fetched data to fill in UI widgets.
            setField(result);
        });
    }).start();
}
&lt;/code&gt;&lt;/pre&gt;
	</description>
    </item>
    <item>
      <title>Clean Architecture</title>
      <link>https://tedneward.github.io/Research/reading/development/clean-architecture/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">reading/development/clean-architecture/index.html</guid>
      	<description>
	&lt;p&gt;&lt;em&gt;(by Robert Martin, aka &quot;Uncle Bob&quot;, aka &quot;the most misogynistic man in tech&quot;)&lt;/em&gt;&lt;/p&gt; 
&lt;h1&gt;Part I:&lt;/h1&gt; 
&lt;h1&gt;1: What is Design and Architecture?&lt;/h1&gt; 
&lt;p&gt;&quot;I’ll assert that there is no difference between [design and architecture]. None at all. ... The word “architecture” is often used in the context of something at a high level that is divorced from the lower-level details, whereas “design” more often seems to imply structures and decisions at a lower level. &quot; Does his home have an architecture? It is the shape of the room, etc, but architecture diagrams provide an immense number of details. &lt;em&gt;(Fallacy: database logical schema vs physical schema, as a counter-example)&lt;/em&gt; &quot;The low-level details and the high-level structure are all part of the same whole. They form a continuous fabric that defines the shape of the system. You can’t have one without the other; indeed, no clear dividing line separates them.&quot; &lt;em&gt;(Disagree: design is the expression of code one level above the first-class citizen level of the language being used. Architecture is the set of decisions made ahead of time for developers, so that they are doing the &quot;right&quot; thing--by the project&apos;s standards and influenced by its problems--by default. They overlap, they influence each other, but architecture is clearly apart from design.)&lt;/em&gt;&lt;/p&gt; 
&lt;p&gt;&quot;&lt;strong&gt;The goal of software architecture is to minimize the human resources required to build and maintain the required system.&lt;/strong&gt; The measure of design quality is simply the measure of the effort required to meet the needs of the customer. If that effort is low, and stays low throughout the lifetime of the system, the design is good. If that effort grows with each new release, the design is bad.&quot;&lt;/p&gt; 
&lt;p&gt;[Anonymized case study showing engineering growth growing yet productivity declining.]&lt;/p&gt; 
&lt;p&gt;[Tortoise v the Hare; counterexample is a 6-day experiment of one developer writing with TDD, and one day without.] &quot;The only way to go fast, is to go well.&quot; &lt;em&gt;(The apples-to-oranges nature of the comparison here is just appalling. Nobody argues that quick-and-dirty yields great results every time--but the arrogance to assert that quick-and-dirty is never acceptable, particularly when executives are agreed on the consequences of doing so, is just beyond credulity.)&lt;/em&gt;&lt;/p&gt; 
&lt;h1&gt;2: A Tale of Two Values&lt;/h1&gt; 
&lt;p&gt;&quot;Every software system provides two different values to the stakeholders: behavior and structure. Software developers are responsible for ensuring that both those values remain high. Unfortunately, they often focus on one to the exclusion of the other. Even more unfortunately, they often focus on the lesser of the two values, leaving the software system eventually valueless.&quot;&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Behavior&lt;/strong&gt;: &quot;Programmers are hired to make machines behave in a way that makes or saves money for the stakeholders. &lt;em&gt;(Not all software is just about saving money for stakeholders.)&lt;/em&gt; We do this by helping the stakeholders develop a functional specification, or requirements document. &lt;em&gt;(Fascinating, because this sounds vaguely waterfall-ish, and Bob supposedly embraces agile.)&lt;/em&gt; Then we write the code that causes the stakeholder&apos;s machines to satisfy those requirements.&quot;&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Architecture&lt;/strong&gt;: &quot;The second value of software has to do with the word &quot;software&quot; ... Software was invented to be &quot;soft.&quot; It was intended to be a way to easily change the behavior of machines. Software was invented to be “soft.” It was intended to be a way to easily change the behavior of machines. ... When the stakeholders change their minds about a feature, that change should be simple and easy to make. The difficulty in making such a change should be proportional only to the scope of the change, and not to the shape of the change.&quot;&lt;/p&gt; 
&lt;p&gt;&quot;If you ask the business managers, they’ll often say that it’s more important for the software system to work. Developers, in turn, often go along with this attitude. But it’s the wrong attitude. I can prove that it is wrong with the simple logical tool of examining the extremes.&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&quot;If you give me a program that works perfectly but is impossible to change, then it won’t work when the requirements change, and I won’t be able to make it work. Therefore the program will become useless.&lt;/li&gt; 
 &lt;li&gt;&quot;If you give me a program that does not work but is easy to change, then I can make it work, and keep it working as requirements change. Therefore the program will remain continually useful.&quot;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;[Important/Urgent matrix]&lt;/p&gt; 
&lt;p&gt;&quot;The first value of software—behavior—is urgent but not always particularly important. The second value of software—architecture—is important but never particularly urgent.&quot;&lt;/p&gt; 
&lt;p&gt;[Exhortation to &quot;fight for the architecture&quot;]&lt;/p&gt; 
&lt;h1&gt;Part II: Programming Paradigms&lt;/h1&gt; 
&lt;p&gt;&quot;Paradigms are ways of programming, relatively unrelated to languages. A paradigm tells you which programming structures to use, and when to use them. To date, there have been three such paradigms.&quot; &lt;em&gt;(Not true, there&apos;ve been numerous paradigms, many of which overlap. See &lt;a href=&quot;/languages/paradigms-for-dummies&quot;&gt;VanRoy&lt;/a&gt;. And VanRoy really ignores &lt;a href=&quot;/reading/languages/aspect-oriented.html&quot;&gt;AOP&lt;/a&gt; entirely to boot.)&lt;/em&gt;&lt;/p&gt; 
&lt;h1&gt;3: Paradigm Overview&lt;/h1&gt; 
&lt;p&gt;An overview chapter on structured programming, object-oriented programming, and functional programming. Summarized as follows:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&quot;Structured programming imposes discipline on direct transfer of control.&quot;&lt;/li&gt; 
 &lt;li&gt;&quot;Object-oriented programming imposes discipline on indirect transfer of control.&quot;&lt;/li&gt; 
 &lt;li&gt;&quot;Functional programming imposes discipline upon assignment.&quot;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;&lt;em&gt;(All three of these are really incorrect analyses, because he wants to emphasize discipline on the developer. It&apos;s a very shallow and pretty unidimensional view of each.)&lt;/em&gt;&lt;/p&gt; 
&lt;h1&gt;4: Structured Programming&lt;/h1&gt; 
&lt;p&gt;[History of Dijkstra] &quot;The problem that Dijkstra recognized, early on, was that programming is hard, and that programmers don’t do it very well. A program of any complexity contains too many details for a human brain to manage without help. Overlooking just one small detail results in programs that may seem to work, but fail in surprising ways.&quot; &lt;em&gt;(Language designers refer to this in the large as &quot;separation of concerns&quot;.)&lt;/em&gt; &quot;Dijkstra’s solution was to apply the mathematical discipline of proof. His vision was the construction of a Euclidian hierarchy of postulates, theorems, corollaries, and lemmas. Dijkstra thought that programmers could use that hierarchy the way mathematicians do. In other words, programmers would use proven structures, and tie them together with code that they would then prove correct themselves. ... The very control structures that made a module provable were the same minimum set of control structures from which all programs can be built. Thus structured programming was born.&quot;&lt;/p&gt; 
&lt;p&gt;[&quot;Goto Considered Harmful&quot;]&lt;/p&gt; 
&lt;p&gt;&quot;Structured programming allows modules to be recursively decomposed into provable units, which in turn means that modules can be functionally decomposed. That is, you can take a large-scale problem statement and decompose it into high-level functions.&quot; &lt;em&gt;(Or you could take small problems, collect them into a function, and build up that way--top-down or bottom-up.)&lt;/em&gt; &quot;But the proofs never came. The Euclidean hierarchy of theorems was never built. And programmers at large never saw the benefits of working through the laborious process of formally proving each and every little function correct. In the end, Dijkstra’s dream faded and died. Few of today’s programmers believe that formal proofs are an appropriate way to produce high-quality software.&quot; &lt;em&gt;(Academics are constantly chasing that dream, as are language designers--every language-generation or so has an effort towards provably-correct code, the most recent having found roots in the pure-functional-language world.)&lt;/em&gt;&lt;/p&gt; 
&lt;p&gt;&quot;Science is fundamentally different from mathematics, in that scientific theories and laws cannot be proven correct. ... They are falsifiable but not provable. ... Science does not work by proving statements true, but rather by proving statements false. Those statements that we cannot prove false, after much effort, we deem to be true enough for our purposes.&quot; &lt;em&gt;(Here comes the argument for TDD)&lt;/em&gt; &quot;... a program can be proven incorrect by a test, but it cannot be proven correct. All that tests can do, after sufficient testing effort, is allow us to deem a program to be correct enough for our purposes.&quot;&lt;/p&gt; 
&lt;h1&gt;5: Object-Oriented Programming&lt;/h1&gt; 
&lt;p&gt;What is O-O? &quot;One answer to this question is “The combination of data and function.” Although often cited, this is a very unsatisfying answer because it implies that &lt;code&gt;o.f()&lt;/code&gt; is somehow different from &lt;code&gt;f(o)&lt;/code&gt;. This is absurd. Programmers were passing data structures into functions long before 1966, when Dahl and Nygaard moved the function call stack frame to the heap and invented OO.&quot; &lt;em&gt;(Bob blithely assumes that the paradigm must be tied to the language--in fact, yes, the union of state and behavior is the principal focus of objects, and you can express that paradigm in languages that don&apos;t have objects as first-class citizens. C did it with GUI applications for many years before C++ came along. Paradigms are concepts, and languages are expressions of concepts, making it much easier to write code in a particular paradigm if you use a language that embraces that same paradigm.)&lt;/em&gt;&lt;/p&gt; 
&lt;p&gt;&quot;Some folks fall back on three magic words to explain the nature of OO: encapsulation, inheritance, and polymorphism. The implication is that OO is the proper admixture of these three things, or at least that an OO language must support these three things.&quot; &lt;em&gt;(Warning: Strawman argument coming up.)&lt;/em&gt;&lt;/p&gt; 
&lt;p&gt;Encapsulation: C had &quot;perfect&quot; encapsulation, then C++ broke it, and Java/C# refuse to allow for separation of declaration and definition. &lt;em&gt;(Not surprisingly, he is skating very fast over lots of details here in his rush to prove a meaningless point.)&lt;/em&gt;&lt;/p&gt; 
&lt;p&gt;Inheritance: Again with the &quot;we had this in C&quot; discussion, relying on C compiler behavior to not rearrange order of fields in a struct to provide &quot;effective&quot; substitution capabilities of a &lt;code&gt;NamedPoint&lt;/code&gt; for a &lt;code&gt;Point&lt;/code&gt;. &lt;em&gt;(Never mind the fact that there was zero compiler enforcement or recognition of the relationship, and therefore these two could easily drift out of sync and lead to extremely subtle bugs that would only manifest at runtime.)&lt;/em&gt;&lt;/p&gt; 
&lt;p&gt;&lt;em&gt;(Readers may get the feeling that Bob wants to go back to the days of C. This is common among the elderly.)&lt;/em&gt;&lt;/p&gt; 
&lt;p&gt;Polymorphism: UNIX and its &quot;everything is a file&quot;/file descriptors design as an example of polymorphic behavior. &lt;em&gt;(He&apos;s falling back again on the &quot;because we could do this before by hand, it&apos;s not that interesting to have&quot; argument. Ironically, it&apos;s the exact opposite of Dijkstra&apos;s argument earlier: We could always do structured programming in assembly by using &lt;code&gt;goto&lt;/code&gt; as necessary to implement it. It&apos;s a hugely inconsistent argument.)&lt;/em&gt; &quot;The bottom line is that polymorphism is an application of pointers to functions.&quot; &lt;em&gt;(Yup, I heard this argument from C programmers about C++ way back in the day.)&lt;/em&gt; &quot;OO languages may not have given us polymorphism, but they have made it much safer and much more convenient. ... Using an OO language makes polymorphism trivial. That fact provides an enormous power that old C programmers could only dream of. On this basis, we can conclude that OO imposes discipline on indirect transfer of control.&quot; &lt;em&gt;(That was some pretty fast skating there.)&lt;/em&gt;&lt;/p&gt; 
&lt;p&gt;Power of polymorphism lies in being able to abstract without details. [Example of a copy program, where the source or target can be any file descriptor]&lt;/p&gt; 
&lt;p&gt;&quot;module HL1 calls the F() function in module ML1. The fact that it calls this function through an interface is a source code contrivance. At runtime, the interface doesn’t exist. HL1 simply calls F() within ML1. ... Note, however, that the source code dependency (the inheritance relationship) between ML1 and the interface I points in the opposite direction compared to the flow of control. This is called dependency inversion, and its implications for the software architect are profound.&quot; &lt;em&gt;(That... really isn&apos;t what dependency inversion refers to, at least not among the people who coined the term.)&lt;/em&gt; &quot;With this approach, software architects working in systems written in OO languages have absolute control over the direction of all source code dependencies in the system. They are not constrained to align those dependencies with the flow of control. No matter which module does the calling and which module is called, the software architect can point the source code dependency in either direction. ... you can rearrange the source code dependencies of your system so that the database and the user interface (UI) depend on the business rules, rather than the other way around. ... This means that the UI and the database can be plugins to the business rules. It means that the source code of the business rules never mentions the UI or the database. As a consequence, the business rules, the UI, and the database can be compiled into three separate components or deployment units (e.g., jar files, DLLs, or Gem files) that have the same dependencies as the source code. The component containing the business rules will not depend on the components containing the UI and database. In turn, the business rules can be deployed independently of the UI and the database. Changes to the UI or the database need not have any effect on the business rules. Those components can be deployed separately and independently. In short, when the source code in a component changes, only that component needs to be redeployed. This is independent deployability. If the modules in your system can be deployed independently, then they can be developed independently by different teams. That’s independent developability.&quot;&lt;/p&gt; 
&lt;p&gt;&lt;em&gt;(This is all great in theory, but in practice, it never manifests this way. Tellingly, there&apos;s no example here, even a simple one.)&lt;/em&gt;&lt;/p&gt; 
&lt;h1&gt;6: Functional Programming&lt;/h1&gt; 
&lt;p&gt;[Example: Squaring the first 25 integers in Java, Clojure/Lisp] &quot;Variables in functional languages do not vary.&quot; &lt;em&gt;(sigh. That&apos;s why they usually don&apos;t get called variables, but values. Or name-value bindings. And only in pure-functional languages. And...)&lt;/em&gt;&lt;/p&gt; 
&lt;p&gt;[Concurrency and immutability] &quot;One of the most common compromises in regard to immutability is to segregate the application, or the services within the application, into mutable and immutable components. The immutable components perform their tasks in a purely functional way, without using any mutable variables. The immutable components communicate with one or more other components that are not purely functional, and allow for the state of variables to be mutated. Since mutating state exposes those components to all the problems of concurrency, it is common practice to use some kind of transactional memory to protect the mutable variables from concurrent updates and race conditions.&quot; &lt;em&gt;(Not sure where he&apos;s getting that STM is &apos;common practice&apos;; it certainly isn&apos;t in any system I&apos;m familiar with....)&lt;/em&gt;&lt;/p&gt; 
&lt;p&gt;[Event sourcing] &lt;em&gt;(Greg Young strikes again)&lt;/em&gt;&lt;/p&gt; 
&lt;h1&gt;Part III: Design Principles&lt;/h1&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;strong&gt;SRP: The Single Responsibility Principle&lt;/strong&gt;: An active corollary to Conway’s law: The best structure for a software system is heavily influenced by the social structure of the organization that uses it so that each software module has one, and only one, reason to change.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;OCP: The Open-Closed Principle&lt;/strong&gt;: Bertrand Meyer made this principle famous in the 1980s. The gist is that for software systems to be easy to change, they must be designed to allow the behavior of those systems to be changed by adding new code, rather than changing existing code.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;LSP: The Liskov Substitution Principle&lt;/strong&gt;: Barbara Liskov’s famous definition of subtypes, from 1988. In short, this principle says that to build software systems from interchangeable parts, those parts must adhere to a contract that allows those parts to be substituted one for another.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;ISP: The Interface Segregation Principle&lt;/strong&gt;: This principle advises software designers to avoid depending on things that they don’t use.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;DIP: The Dependency Inversion Principle&lt;/strong&gt;: The code that implements high-level policy should not depend on the code that implements low-level details. Rather, details should depend on policies.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h1&gt;Part IV: Component Principles&lt;/h1&gt; 
&lt;h1&gt;12: Components&lt;/h1&gt; 
&lt;p&gt;&quot;Components are the units of deployment. They are the smallest entities that can be deployed as part of a system.&quot; &lt;em&gt;(Not exactly, but it&apos;s not a terrible summation of Szyperski.)&lt;/em&gt;&lt;/p&gt; 
&lt;p&gt;[PDP history around linking and loading and relocation] &lt;em&gt;(I have really no idea what his point here is with this.)&lt;/em&gt;&lt;/p&gt; 
&lt;h1&gt;13: Component Cohesion&lt;/h1&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;strong&gt;REP: The Reuse/Release Equivalence Principle&lt;/strong&gt; (The granule of reuse is the granule of release)&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;CCP: The Common Closure Principle&lt;/strong&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;CRP: The Common Reuse Principle&lt;/strong&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h1&gt;14: Component Coupling&lt;/h1&gt; 
&lt;h1&gt;Part V: Architecture&lt;/h1&gt; 
&lt;h1&gt;15: What is Architecture?&lt;/h1&gt; 
&lt;h1&gt;16: Independence&lt;/h1&gt; 
&lt;h1&gt;17: Boundaries: Drawing Lines&lt;/h1&gt; 
&lt;h1&gt;18: Boundary Anatomy&lt;/h1&gt; 
&lt;h1&gt;19: Policy and Level&lt;/h1&gt; 
&lt;h1&gt;20: Business Rules&lt;/h1&gt; 
&lt;h1&gt;21: Screaming Architecture&lt;/h1&gt; 
&lt;h1&gt;22: The Clean Architecture&lt;/h1&gt; 
&lt;h1&gt;23: Presenters and Humble Objects&lt;/h1&gt; 
&lt;h1&gt;24: Partial Boundaries&lt;/h1&gt; 
&lt;h1&gt;25: Layers and Boundaries&lt;/h1&gt; 
&lt;h1&gt;26: The Main Component&lt;/h1&gt; 
&lt;h1&gt;27: Services: Great and Small&lt;/h1&gt; 
&lt;h1&gt;28: The Test Boundary&lt;/h1&gt; 
&lt;h1&gt;29: Clean Embedded Architecture&lt;/h1&gt; 
&lt;h1&gt;Part VI: Details&lt;/h1&gt; 
&lt;h1&gt;30: The Database is a Detail&lt;/h1&gt; 
&lt;h1&gt;31: The Web is a Detail&lt;/h1&gt; 
&lt;h1&gt;32: Frameworks are Details&lt;/h1&gt; 
&lt;h1&gt;33: Case Study: Video Sales&lt;/h1&gt; 
&lt;h1&gt;34: The Missing Chapter&lt;/h1&gt; 
&lt;h1&gt;Part VII: Appendix&lt;/h1&gt; 
&lt;h1&gt;A: Architecture Archaeology&lt;/h1&gt;
	</description>
    </item>
    <item>
      <title>Software development for beginners</title>
      <link>https://tedneward.github.io/Research/reading/development/beginners/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">reading/development/beginners/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/microsoft/Web-Dev-For-Beginners&quot;&gt;Microsoft 12-week program&lt;/a&gt;: 12-week, 24-lesson; HTML, CSS, JavaScript.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Blockchain reading</title>
      <link>https://tedneward.github.io/Research/reading/development/blockchain/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">reading/development/blockchain/index.html</guid>
      	<description>
	&lt;h2&gt;Reading&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;http://bitcoinbook.cs.princeton.edu&quot;&gt;Bitcoin and Cryptocurrency Technologies&lt;/a&gt; - Arvind Narayanan, Joseph Bonneau, Edward Felten, Andrew Miller, Steven Goldfeder, Jeremy Clark (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.ibm.com/downloads/cas/36KBMBOG&quot;&gt;Blockchain for Dummies, 2nd IBM Limited Edition&lt;/a&gt; - Manav Gupta (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://chain.courses&quot;&gt;chain.courses&lt;/a&gt; - James Gan, Rishub Kumar&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.ibm.com/downloads/cas/RYWXAR0M&quot;&gt;Getting Started with Enterprise Blockchain: A Guide to Design and Development&lt;/a&gt; - Michael Bradley, David Gorman, Matt Lucas, Matthew Golby-Kirk (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.ibm.com/downloads/cas/GZPPMWM5&quot;&gt;IBM Blockchain: The Founder’s Handbook, Third Edition&lt;/a&gt; - Antonio Banda, Matthew Hamilton, Eileen Lowry, John Widdifield et al. (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://schadokar.dev/ebooks/playtime-with-hyperledger-composer/&quot;&gt;Playtime with Hyperledger Composer&lt;/a&gt; - Shubham Chadokar (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.distributed-systems.net/my-data/papers/2021.blockchains.pdf&quot;&gt;The Difficulty in Scaling Blockchains: A Simple Explanation&lt;/a&gt; - Maarten van Steen - &quot; In this paper, we provide a laymen&apos;s description of what may turn out to be a fundamental hurdle in attaining blockchains that combine scalability, high transaction processing capabilities, and are indeed fully decentralized.&quot;&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Browser Reading</title>
      <link>https://tedneward.github.io/Research/reading/development/browser/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">reading/development/browser/index.html</guid>
      	<description>
	&lt;h2&gt;Articles&lt;/h2&gt; 
&lt;p&gt;&lt;a href=&quot;https://nolanlawson.com/2023/12/02/lets-learn-how-modern-javascript-frameworks-work-by-building-one/&quot;&gt;&quot;How modern Javascript Frameworks Work, By Building One&quot;&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Reading in Algorithms and Data Structures</title>
      <link>https://tedneward.github.io/Research/reading/development/algorithms-data-structures/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">reading/development/algorithms-data-structures/index.html</guid>
      	<description>
	&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://web.archive.org/web/20191020195105/http://www0.cs.ucl.ac.uk/staff/W.Langdon/ftp/papers/poli08_fieldguide.pdf&quot;&gt;A Field Guide To Genetic Programming&lt;/a&gt; - Riccardo Poli et al. (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://archive.org/details/AlgorithmDesign1stEditionByJonKleinbergAndEvaTardos2005PDF&quot;&gt;Algorithm Design&lt;/a&gt; - Jon Kleinberg and Éva Tardos (&lt;a href=&quot;./AlgorithmDesign.pdf&quot;&gt;PDF&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;Algorithms and Data Structures - Wirth (&lt;a href=&quot;./AlgorithmsDataStructures.pdf&quot;&gt;PDF&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://code.google.com/p/graphbook/&quot;&gt;Algorithmic Graph Theory&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://en.wikibooks.org/wiki/Algorithms&quot;&gt;Algorithms&lt;/a&gt; - Wikibooks&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;./Algorithms.pdf&quot;&gt;Algorithms&lt;/a&gt; - by Vazirani and Dasgupta&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://algs4.cs.princeton.edu/home/&quot;&gt;Algorithms, 4th Edition&lt;/a&gt; (&lt;a href=&quot;./Algorithms-4E.pdf&quot;&gt;PDF&lt;/a&gt;)- Robert Sedgewick and Kevin Wayne&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://archive.org/details/Algorithms_And_Automatic_Computing_Machines&quot;&gt;Algorithms and Automatic Computing Machines (1963)&lt;/a&gt; - B. A. Trakhtenbrot&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.math.upenn.edu/~wilf/AlgoComp.pdf&quot;&gt;Algorithms and Complexity&lt;/a&gt; - Herbert S. Wilf (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://jeffe.cs.illinois.edu/teaching/algorithms/&quot;&gt;Algorithms Course Materials&lt;/a&gt; - Jeff Erickson&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://goalkicker.com/AlgorithmsBook&quot;&gt;Algorithms Notes for Professionals&lt;/a&gt; - Compiled from StackOverflow Documentation (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.cse.iitd.ernet.in/~ssen/csl356/admin356.html&quot;&gt;Analysis and Design of Algorithms&lt;/a&gt; - Sandeep Sen, IIT Delhi&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://visualgo.net&quot;&gt;Animated Algorithm and Data Structure Visualization&lt;/a&gt; (Resource)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/mdipierro/nlib&quot;&gt;Annotated Algorithms in Python: Applications in Physics, Biology, and Finance&lt;/a&gt; - Massimo di Pierro&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://cslibrary.stanford.edu/110/BinaryTrees.pdf&quot;&gt;Binary Trees&lt;/a&gt; (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://austinhenley.com/blog/challengingalgorithms.html&quot;&gt;Challenging algorithms and data structures every programmer should try&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://adityacse.weebly.com/uploads/2/4/0/7/24078687/data-structures.pdf&quot;&gt;Data Structures&lt;/a&gt; - Aditya CSE (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://en.wikibooks.org/wiki/Data_Structures&quot;&gt;Data Structures&lt;/a&gt; - Wikibooks&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.cse.iitd.ernet.in/~suban/cs130/index.html&quot;&gt;Data Structures&lt;/a&gt; - Prof. Subhashis Banerjee, IIT Delhi&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www-inst.eecs.berkeley.edu/~cs61b/fa14/book2/data-structures.pdf&quot;&gt;Data Structures (Into Java) - Paul N. Hilfinger&lt;/a&gt; (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://web.archive.org/web/20170715160229/http://dotnetslackers.com/Community/files/folders/data-structures-and-algorithms/entry30283.aspx&quot;&gt;Data Structures and Algorithms: Annotated Reference with Examples&lt;/a&gt; - G. Barnett and L. Del Tongo&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.syncfusion.com/resources/techportal/ebooks/datastructurespart1&quot;&gt;Data Structures Succinctly Part 1, Syncfusion&lt;/a&gt; (PDF, Kindle) (email address &lt;em&gt;requested&lt;/em&gt;, not required)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.syncfusion.com/resources/techportal/ebooks/datastructurespart2&quot;&gt;Data Structures Succinctly Part 2, Syncfusion&lt;/a&gt; (PDF, Kindle) (email address &lt;em&gt;requested&lt;/em&gt;, not required)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/liuxinyu95/AlgoXY&quot;&gt;Elementary Algorithms&lt;/a&gt; (&lt;a href=&quot;./ElementaryAlgorithms.pdf&quot;&gt;PDF&lt;/a&gt;) - Larry LIU Xinyu&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://infolab.stanford.edu/~ullman/focs.html&quot;&gt;Foundations of Computer Science&lt;/a&gt; - Al Aho and Jeff Ullman&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Fractal_tree_index&quot;&gt;Fractal tree index - Wikipedia&lt;/a&gt;: A refinement of the B-epsilon tree.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;./FundamentalsComputerAlgorithm.pdf&quot;&gt;Fundamentals of Computer Algorithms&lt;/a&gt; - by Horowitz and Sahni&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://geomalgorithms.com&quot;&gt;Geometry Algorithms&lt;/a&gt; - Dan Sunday&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://ianparberry.com/books/free/license.html&quot;&gt;Lectures Notes on Algorithm Analysis and Computational Complexity (Fourth Edition)&lt;/a&gt; - Ian Parberry (use form at bottom of license)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://people.mpi-inf.mpg.de/~mehlhorn/LEDAbook.html&quot;&gt;LEDA: A Platform for Combinatorial and Geometric Computing&lt;/a&gt; - K. Mehlhorn et al.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://cslibrary.stanford.edu/103/LinkedListBasics.pdf&quot;&gt;Linked List Basics&lt;/a&gt; (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://cslibrary.stanford.edu/105/LinkedListProblems.pdf&quot;&gt;Linked List Problems&lt;/a&gt; (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.jjj.de/fxt/fxtbook.pdf&quot;&gt;Matters Computational: Ideas, Algorithms, Source Code&lt;/a&gt; (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://opendatastructures.org&quot;&gt;Open Data Structures: An Introduction&lt;/a&gt; - Pat Morin&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://planning.cs.uiuc.edu&quot;&gt;Planning Algorithms&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://ianparberry.com/books/free/license.html&quot;&gt;Problems on Algorithms (Second Edition)&lt;/a&gt; - Ian Parberry (use form at bottom of license)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://web.archive.org/web/20210917054102/http://www.cs.cmu.edu/~rwh/theses/okasaki.pdf&quot;&gt;Purely Functional Data Structures (1996)&lt;/a&gt; - Chris Okasaki (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.inf.fh-flensburg.de/lang/algorithmen/sortieren/algoen.htm&quot;&gt;Sequential and parallel sorting algorithms&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://igm.univ-mlv.fr/~mac/REC/text-algorithms.pdf&quot;&gt;Text Algorithms&lt;/a&gt; (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www8.cs.umu.se/kurser/TDBAfl/VT06/algorithms/BOOK/BOOK/BOOK.HTM&quot;&gt;The Algorithm Design Manual&lt;/a&gt; (&lt;a href=&quot;./TheAlgorithmDesignManual.pdf&quot;&gt;PDF&lt;/a&gt;) (&lt;a href=&quot;https://github.com/SkienaBooks/Algorithm-Design-Manual-Programs&quot;&gt;code&lt;/a&gt;) - by Steven S. Skiena&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.designofapproxalgs.com/book.pdf&quot;&gt;The Design of Approximation Algorithms&lt;/a&gt; (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://cslibrary.stanford.edu/109/TreeListRecursion.pdf&quot;&gt;The Great Tree List Recursion Problem&lt;/a&gt; (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.syncfusion.com/ebooks/kademlia_protocol_succinctly&quot;&gt;The Kademlia Protocol Succinctly&lt;/a&gt; - Marc Clifton&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://greenteapress.com/wp/think-complexity-2e/&quot;&gt;Think Complexity&lt;/a&gt; - Allen B. Downey (2nd Edition) (PDF, HTML)&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;Others not linked:&lt;/p&gt; 
&lt;p&gt;Introduction to Algorithms (4th Ed) by Corman&lt;/p&gt; 
&lt;p&gt;Grokking Algorithms (2nd Ed) by Bhargava&lt;/p&gt; 
&lt;p&gt;Algorithms in a Nutshell by Heineman, Police and Selkow&lt;/p&gt; 
&lt;p&gt;Introduction to Algorithms: A Creative Approach by Manber&lt;/p&gt; 
&lt;p&gt;The Design and Analysis of Algorithms by Levitin&lt;/p&gt; 
&lt;p&gt;Data Structures and Algorithms by Aho, Ullman &amp;amp; Hopcroft&lt;/p&gt; 
&lt;p&gt;Python Algorithms: Mastering the Basic Algorithms in the Python Language by Hetland&lt;/p&gt; 
&lt;p&gt;Papers:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;http://supertech.csail.mit.edu/papers/BenderFaJa15.pdf&quot;&gt;An Introduction to Bε (B-epsilon) trees and Write-Optimization&lt;/a&gt;: &quot;A Bε-tree is an example of a write-optimized data structure and can be used to organize on-disk storage for an application such as a database or filesystem. A Bε-tree provides a key-value API, similar to a B-tree, but with better performance, particularly for inserts, range queries, and key-value updates. This article describes the Bε-tree,compares its asymptotic performance to B-trees and Log-Structured Merge trees (LSM-trees), and presents real-world performance measurements. After finishing this article, a reader should have a basic understanding of how a Bε-treeworks, its performance characteristics, how it compares to other key-value stores, and how to design applications to gain the most performance from a Bε-tree.&quot;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://essay.utwente.nl/87368/1/Khavrona_BA_EEMCS.pdf&quot;&gt;B-epsilon-tree and cache-oblivious lookahead array: a comparative study of two write-optimised data structures&lt;/a&gt;: &quot;The ever-growing amounts of data stored in the world require efficient and fast data structures to store and process it. Due to the large size of such massive datasets, the data structures that operate on them grow so large that they can no longer fit in main memory. Thus, the number of I/O operations between fast main memory and slow disk becomes the performance bottleneck of these data structures. To properly assess their performance, these data structures are analysed in the external memory model that puts emphasis on the number of blocks transferred between main memory and disk.Multiple data structures and their variations were developed in the external memory model to optimise the number of block transfers, among which the B-tree is the most well-known one. One of the research areas related to designing data structures in the external memory model has been focused on making data structures that keep the same search performance as the B-tree but asymptotically improve the speed of writes. Despite extensive theoretical results in the area, little experimental data about performance of such write-optimised data structures is available. In this research study,we analysed two write optimised data structures--the B-tree and cache-oblivious lookahead array(COLA)--and performed experiments to determine which data structure performs better under which conditions. As our results show, &lt;strong&gt;&lt;em&gt;the COLA has much better write speeds than the B-tree when inserted elements are not sorted, but achieves worse results when the data is sorted. Point queries are faster in the B-tree, which makes it a better choice for workloads that require more querying than updating data.&lt;/em&gt;&lt;/strong&gt; Lastly, &lt;strong&gt;&lt;em&gt;the support of an efficient read-and-update operation and more streamlined experience of implementing the B-tree compared to the COLA make it an even more favourable data structure to consider for a use in data storage systems.&quot;&lt;/em&gt;&lt;/strong&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/rahulyesantharao/b-epsilon-tree&quot;&gt;b-epsilon-tree&lt;/a&gt;: A simple implementation of the write-optimized B-epsilon tree&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://driftingin.space/posts/you-might-not-need-a-crdt&quot;&gt;You might not need a CRDT&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Program analysis</title>
      <link>https://tedneward.github.io/Research/reading/development/analysis/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">reading/development/analysis/index.html</guid>
      	<description>
	&lt;h1&gt;General&lt;/h1&gt; 
&lt;ul&gt; 
 &lt;li&gt;Program Analysis Reading List - Rolf Rolles - &lt;a href=&quot;http://www.msreverseengineering.com/program-analysis-reading-list/&quot;&gt;http://www.msreverseengineering.com/program-analysis-reading-list/&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;Reading for graduate students in static analysis - &lt;a href=&quot;http://matt.might.net/articles/books-papers-materials-for-graduate-students/#analysis&quot;&gt;http://matt.might.net/articles/books-papers-materials-for-graduate-students/#analysis&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;Program Analysis Resources - &lt;a href=&quot;http://reversing.io/resources/&quot;&gt;http://reversing.io/resources/&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;Conferences on Software Verification and Analysis - &lt;a href=&quot;https://github.com/soarlab/conferences&quot;&gt;https://github.com/soarlab/conferences&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;Static Analysis Roadmap - &lt;a href=&quot;https://tpiazza.me/posts/2017-11-01-static-analysis-roadmap.html&quot;&gt;https://tpiazza.me/posts/2017-11-01-static-analysis-roadmap.html&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h1&gt;Symbolic Execution&lt;/h1&gt; 
&lt;ul&gt; 
 &lt;li&gt;Awesome Symbolic Execution - &lt;a href=&quot;https://github.com/ksluckow/awesome-symbolic-execution&quot;&gt;https://github.com/ksluckow/awesome-symbolic-execution&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;Symbolic execution history timeline: &lt;a href=&quot;https://github.com/enzet/symbolic-execution&quot;&gt;https://github.com/enzet/symbolic-execution&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;Symbolic Execution: Intuition and Implementation - &lt;a href=&quot;http://www.usrsb.in/symbolic-execution-intuition-and-implementation.html&quot;&gt;http://www.usrsb.in/symbolic-execution-intuition-and-implementation.html&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;A bibliography of papers related to symbolic execution - &lt;a href=&quot;https://github.com/saswatanand/symexbib&quot;&gt;https://github.com/saswatanand/symexbib&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;A Survey of Symbolic Execution Techniques 
  &lt;ul&gt; 
   &lt;li&gt;ACM Computing Surveys 51(3) 2018&lt;/li&gt; 
   &lt;li&gt;Roberto Baldoni, Emilio Coppa, Daniele Cono D&apos;Elia, Camil Demetrescu, Irene Finocchi&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/season-lab/survey-symbolic-execution&quot;&gt;https://github.com/season-lab/survey-symbolic-execution&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://arxiv.org/abs/1610.00502&quot;&gt;https://arxiv.org/abs/1610.00502&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;All You Ever Wanted to Know About Dynamic Taint Analysis and Forward Symbolic Execution (but might have been afraid to ask) 
  &lt;ul&gt; 
   &lt;li&gt;Security and Privacy (SP), 2010&lt;/li&gt; 
   &lt;li&gt;Edward J. Schwartz, Thanassis Avgerinos, David Brumley&lt;/li&gt; 
   &lt;li&gt;Paper: &lt;a href=&quot;https://edmcman.github.io/papers/oakland10.pdf&quot;&gt;https://edmcman.github.io/papers/oakland10.pdf&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Slides: &lt;a href=&quot;https://edmcman.github.io/pres/oakland10.pdf&quot;&gt;https://edmcman.github.io/pres/oakland10.pdf&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Systematic Comparison of Symbolic Execution Systems: Intermediate Representation and its Generation 
  &lt;ul&gt; 
   &lt;li&gt;Annual Computer Security Applications Conference (ACSAC) 2019&lt;/li&gt; 
   &lt;li&gt;Sebastian Poeplau and Aurélien Francillon&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://s3.eurecom.fr/tools/symbolic_execution/&quot;&gt;http://s3.eurecom.fr/tools/symbolic_execution/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://s3.eurecom.fr/docs/acsac19_poeplau.pdf&quot;&gt;http://s3.eurecom.fr/docs/acsac19_poeplau.pdf&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://hal.archives-ouvertes.fr/hal-02305914/&quot;&gt;https://hal.archives-ouvertes.fr/hal-02305914/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Scaling Symbolic Evaluation for Automated Verification of Systems Code with Serval 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://sosp19.rcs.uwaterloo.ca/program.html&quot;&gt;SOSP 2019&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Luke Nelson, James Bornholt, Ronghui Gu, Andrew Baumann, Emina Torlak, Xi Wang&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://unsat.cs.washington.edu/projects/serval/&quot;&gt;https://unsat.cs.washington.edu/projects/serval/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://blog.acolyer.org/2019/11/13/scaling-symbolic-evaluation-serval/&quot;&gt;https://blog.acolyer.org/2019/11/13/scaling-symbolic-evaluation-serval/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h1&gt;Lectures &amp;amp; Courses&lt;/h1&gt; 
&lt;ul&gt; 
 &lt;li&gt;Foundations of Programming Languages 
  &lt;ul&gt; 
   &lt;li&gt;M-PS (WS 2014/2015): Concepts of Programming Languages&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://sepl.cs.uni-frankfurt.de/2014-ws/m-ps/index.en.html&quot;&gt;http://sepl.cs.uni-frankfurt.de/2014-ws/m-ps/index.en.html&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://web.archive.org/web/http://sepl.cs.uni-frankfurt.de/2014-ws/m-ps/index.en.html&quot;&gt;http://web.archive.org/web/http://sepl.cs.uni-frankfurt.de/2014-ws/m-ps/index.en.html&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;lectures (videos &amp;amp; slides): 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/channel/UCpSoGwyH5yHHvQut3x6c_2g/playlists&quot;&gt;https://www.youtube.com/channel/UCpSoGwyH5yHHvQut3x6c_2g/playlists&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;http://sepl.cs.uni-frankfurt.de/2014-ws/m-ps/sessions.en.html&quot;&gt;http://sepl.cs.uni-frankfurt.de/2014-ws/m-ps/sessions.en.html&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;http://web.archive.org/web/http://sepl.cs.uni-frankfurt.de/2014-ws/m-ps/sessions.en.html&quot;&gt;http://web.archive.org/web/http://sepl.cs.uni-frankfurt.de/2014-ws/m-ps/sessions.en.html&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Static Program Analysis 
  &lt;ul&gt; 
   &lt;li&gt;Anders Møller and Michael I. Schwartzbach&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://cs.au.dk/~amoeller/spa/&quot;&gt;https://cs.au.dk/~amoeller/spa/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;PLISS 2019 - Anders Møller 
    &lt;ul&gt; 
     &lt;li&gt;Static Program Analysis (part 1/2) - &lt;a href=&quot;https://www.youtube.com/watch?v=Lr4cMmaJHrg&quot;&gt;https://www.youtube.com/watch?v=Lr4cMmaJHrg&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;Static Program Analysis (part 2/2) - &lt;a href=&quot;https://www.youtube.com/watch?v=6QQSIIvH-F0&quot;&gt;https://www.youtube.com/watch?v=6QQSIIvH-F0&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;25 Years of Program Analysis 
  &lt;ul&gt; 
   &lt;li&gt;DEF CON 25 (2017) - Yan Shoshitaishvili (Zardus)&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=XL9kWQ3YpLo&quot;&gt;https://www.youtube.com/watch?v=XL9kWQ3YpLo&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://media.defcon.org/DEF%20CON%2025/DEF%20CON%2025%20presentations/DEFCON-25-Zardus-25-Years-of-Program-Analysis-UPDATED.pdf&quot;&gt;https://media.defcon.org/DEF%20CON%2025/DEF%20CON%2025%20presentations/DEFCON-25-Zardus-25-Years-of-Program-Analysis-UPDATED.pdf&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Software Analysis and Testing - &lt;a href=&quot;http://www.cis.upenn.edu/~mhnaik/&quot;&gt;Mayur Naik&lt;/a&gt; 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;http://rightingcode.org/&quot;&gt;http://rightingcode.org/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://www.cis.upenn.edu/~mhnaik/edu/cis700/&quot;&gt;http://www.cis.upenn.edu/~mhnaik/edu/cis700/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/channel/UCvwqRhlkE_Wm2FF9qzvHfJw&quot;&gt;https://www.youtube.com/channel/UCvwqRhlkE_Wm2FF9qzvHfJw&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Program Analysis and Reliability - Nick Sumner, CMPT 886, Spring 2015, SFU 
  &lt;ul&gt; 
   &lt;li&gt;Playlist: &lt;a href=&quot;https://www.youtube.com/playlist?list=PLNC6lmsIySCOPjY8IwKBtD2cqe-MMgIGM&quot;&gt;https://www.youtube.com/playlist?list=PLNC6lmsIySCOPjY8IwKBtD2cqe-MMgIGM&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Schedule &amp;amp; Slides: &lt;a href=&quot;http://www.cs.sfu.ca/~wsumner/teaching/886/15/schedule.html&quot;&gt;http://www.cs.sfu.ca/~wsumner/teaching/886/15/schedule.html&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Program analysis for reverse engineers: from T to ⊥ 
  &lt;ul&gt; 
   &lt;li&gt;BSides Canberra 2018; Adrian Herrera&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=vOmGmjbVff4&quot;&gt;https://www.youtube.com/watch?v=vOmGmjbVff4&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;slides (not displayed in the video, may be a good idea to watch alongside):&lt;br&gt; &lt;a href=&quot;https://drive.google.com/file/d/1j9rfMt14pubi6G9PKK3akddyeet5bf0x/view&quot;&gt;https://drive.google.com/file/d/1j9rfMt14pubi6G9PKK3akddyeet5bf0x/view&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;CS 252r: Advanced Topics in Programming Languages 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;http://web-static-aws.seas.harvard.edu/courses/cs252/2011sp/&quot;&gt;http://web-static-aws.seas.harvard.edu/courses/cs252/2011sp/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.seas.harvard.edu/courses/cs252/2015fa/schedule.html&quot;&gt;https://www.seas.harvard.edu/courses/cs252/2015fa/schedule.html&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;A Gentle Introduction to Program Analysis 
  &lt;ul&gt; 
   &lt;li&gt;Programming Languages Mentoring Workshop 2014&lt;/li&gt; 
   &lt;li&gt;Isıl Dillig (University of Texas)&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.cis.upenn.edu/~alur/CIS673/isil-plmw.pdf&quot;&gt;https://www.cis.upenn.edu/~alur/CIS673/isil-plmw.pdf&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h1&gt;Software&lt;/h1&gt; 
&lt;ul&gt; 
 &lt;li&gt;SPARTA: a library that provides the basic blocks for building high-performance static code analyzers based on Abstract Interpretation 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/facebookincubator/SPARTA&quot;&gt;https://github.com/facebookincubator/SPARTA&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;SPARTA: a C++ library of software components for building high-performance static analyzers&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://code.fb.com/open-source/sparta/&quot;&gt;https://code.fb.com/open-source/sparta/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Bill Torpey - &lt;a href=&quot;http://btorpey.github.io/blog/categories/static-analysis/&quot;&gt;static analysis posts&lt;/a&gt; 
  &lt;ul&gt; 
   &lt;li&gt;Static Analysis with Clang - &lt;a href=&quot;http://btorpey.github.io/blog/2015/04/27/static-analysis-with-clang/&quot;&gt;http://btorpey.github.io/blog/2015/04/27/static-analysis-with-clang/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Mo&apos; Static - &lt;a href=&quot;http://btorpey.github.io/blog/2016/04/07/mo-static/&quot;&gt;http://btorpey.github.io/blog/2016/04/07/mo-static/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Even Mo&apos; Static - &lt;a href=&quot;http://btorpey.github.io/blog/2016/11/12/even-mo-static/&quot;&gt;http://btorpey.github.io/blog/2016/11/12/even-mo-static/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Lots o&apos; static - &lt;a href=&quot;http://btorpey.github.io/blog/2017/09/17/lotso-static/&quot;&gt;http://btorpey.github.io/blog/2017/09/17/lotso-static/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;LLVM&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;awesome-llvm: A curated list of awesome LLVM related docs, tools, and other resources 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/HongxuChen/awesome-llvm&quot;&gt;https://github.com/HongxuChen/awesome-llvm&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;LLVM Weekly - &lt;a href=&quot;http://llvmweekly.org/&quot;&gt;http://llvmweekly.org/&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://eli.thegreenplace.net/tag/llvm-clang&quot;&gt;https://eli.thegreenplace.net/tag/llvm-clang&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;Building a Checker in 24 hours 
  &lt;ul&gt; 
   &lt;li&gt;2012 LLVM Developers’ Meeting; Anna Zaks, Jordan Rose&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://llvm.org/devmtg/2012-11/Zaks-Rose-Checker24Hours.pdf&quot;&gt;https://llvm.org/devmtg/2012-11/Zaks-Rose-Checker24Hours.pdf&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=kdxlsP5QVPw&quot;&gt;https://www.youtube.com/watch?v=kdxlsP5QVPw&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Code transformation and analysis using Clang and LLVM 
  &lt;ul&gt; 
   &lt;li&gt;Static and Dynamic Analysis&lt;/li&gt; 
   &lt;li&gt;HPC Summer School 2017; Hal Finkel&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://llvm.org/devmtg/2017-06/2-Hal-Finkel-LLVM-2017.pdf&quot;&gt;https://llvm.org/devmtg/2017-06/2-Hal-Finkel-LLVM-2017.pdf&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/hfinkel/llvm-ss-2017&quot;&gt;https://github.com/hfinkel/llvm-ss-2017&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Compiler-assisted Performance Analysis 
  &lt;ul&gt; 
   &lt;li&gt;2016 LLVM Developers’ Meeting; Adam Nemet&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/llvm-mirror/llvm/tree/master/tools/opt-viewer&quot;&gt;https://github.com/llvm-mirror/llvm/tree/master/tools/opt-viewer&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://llvm.org/devmtg/2016-11/Slides/Nemet-Compiler-assistedPerformanceAnalysis.pdf&quot;&gt;https://llvm.org/devmtg/2016-11/Slides/Nemet-Compiler-assistedPerformanceAnalysis.pdf&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=qq0q1hfzidg&quot;&gt;https://www.youtube.com/watch?v=qq0q1hfzidg&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Dg: LLVM Static Slicer 
  &lt;ul&gt; 
   &lt;li&gt;Dependence graph for programs. A set of generic program analyses and a static slicer for LLVM bitcode&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/mchalupa/dg&quot;&gt;https://github.com/mchalupa/dg&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;FPSCEV: Floating-Point Scalar Evolution in LLVM 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/sheredom/fpscev&quot;&gt;https://github.com/sheredom/fpscev&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://www.duskborn.com/posts/fpscev/&quot;&gt;http://www.duskborn.com/posts/fpscev/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://www.duskborn.com/posts/fpscev-fast-math-propagation/&quot;&gt;http://www.duskborn.com/posts/fpscev-fast-math-propagation/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://www.duskborn.com/posts/fpscev-inst-simplify/&quot;&gt;http://www.duskborn.com/posts/fpscev-inst-simplify/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://www.duskborn.com/posts/fpscev-improved-range/&quot;&gt;http://www.duskborn.com/posts/fpscev-improved-range/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;LLVM Dataflow Info Printer Pass 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/regehr/llvm-dataflow-info&quot;&gt;https://github.com/regehr/llvm-dataflow-info&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Tell us what some of LLVM&apos;s dataflow analyses think about the code being compiled.&lt;/li&gt; 
   &lt;li&gt;Testing Dataflow Analyses for Precision and Soundness 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://blog.regehr.org/archives/1709&quot;&gt;https://blog.regehr.org/archives/1709&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;Testing Static Analyses for Precision and Soundness 
    &lt;ul&gt; 
     &lt;li&gt;CGO (Code Generation and Optimization) 2020&lt;/li&gt; 
     &lt;li&gt;Jubi Taneja, Zhengyang Liu, John Regehr&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;http://www.cs.utah.edu/~regehr/cgo20.pdf&quot;&gt;http://www.cs.utah.edu/~regehr/cgo20.pdf&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;LLVM Debugging Tips and Tricks 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;http://bholt.org/posts/llvm-debugging.html&quot;&gt;http://bholt.org/posts/llvm-debugging.html&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Phasar - A LLVM-based static code analysis framework 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;http://phasar.org/&quot;&gt;http://phasar.org/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/secure-software-engineering/phasar&quot;&gt;https://github.com/secure-software-engineering/phasar&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Static Analysis for C++ with Phasar&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://pldi18.sigplan.org/event/pldi-2018-pldi-tutorials-static-analysis-for-c-with-phasar&quot;&gt;https://pldi18.sigplan.org/event/pldi-2018-pldi-tutorials-static-analysis-for-c-with-phasar&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;PhASAR: An Inter-Procedural Static Analysis Framework for C/C++ 
    &lt;ul&gt; 
     &lt;li&gt;TACAS 2019&lt;/li&gt; 
     &lt;li&gt;Philipp D. Schubert, Ben Hermann, Eric Bodden&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;http://www.thewhitespace.de/publications/shb19-phasar.pdf&quot;&gt;http://www.thewhitespace.de/publications/shb19-phasar.pdf&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;SVF: Interprocedural Static Value-Flow Analysis in LLVM 
  &lt;ul&gt; 
   &lt;li&gt;Pointer Analysis and Program Dependence Analysis for C and C++ Programs&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://svf-tools.github.io/SVF/&quot;&gt;http://svf-tools.github.io/SVF/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/unsw-corg/SVF&quot;&gt;https://github.com/unsw-corg/SVF&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;SVF: Interprocedural Static Value-Flow Analysis in LLVM 
    &lt;ul&gt; 
     &lt;li&gt;Compiler Construction (CC &apos;16)&lt;/li&gt; 
     &lt;li&gt;Yulei Sui and Jingling Xue&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://yuleisui.github.io/publications/cc16.pdf&quot;&gt;https://yuleisui.github.io/publications/cc16.pdf&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;2016 EuroLLVM Developers&apos; Meeting: Y. Sui &quot;SVF: Static Value-Flow Analysis in LLVM&quot;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=nD-i-enA8rc&quot;&gt;https://www.youtube.com/watch?v=nD-i-enA8rc&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;LLVM - Symbolic Execution&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;haybale: Symbolic execution of LLVM IR with an engine written in Rust 
  &lt;ul&gt; 
   &lt;li&gt;operates on LLVM IR, which allows it to analyze programs written in C/C++, Rust, Swift, or any other language which compiles to LLVM IR&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/PLSysSec/haybale&quot;&gt;https://github.com/PLSysSec/haybale&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;KLEE Symbolic Virtual Machine 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;http://klee.github.io/&quot;&gt;http://klee.github.io/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://klee.github.io/publications/&quot;&gt;http://klee.github.io/publications/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/klee/klee&quot;&gt;https://github.com/klee/klee&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;LLVM - Verification&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;LLBMC: The Low-Level Bounded Model Checker 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;http://llbmc.org/&quot;&gt;http://llbmc.org/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://llbmc.org/publications.html&quot;&gt;http://llbmc.org/publications.html&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;LLBMC: Bounded Model Checking of C and C++ Programs Using a Compiler IR 
    &lt;ul&gt; 
     &lt;li&gt;Verified Software: Theories, Tools and Experiments (VSTTE) 2012&lt;/li&gt; 
     &lt;li&gt;Florian Merz, Stephan Falke, Carsten Sinz&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://doi.org/10.1007/978-3-642-27705-4_12&quot;&gt;https://doi.org/10.1007/978-3-642-27705-4_12&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;http://llbmc.org/files/papers/VSTTE12.pdf&quot;&gt;http://llbmc.org/files/papers/VSTTE12.pdf&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;http://llbmc.org/files/talks/vstte-2012.pdf&quot;&gt;http://llbmc.org/files/talks/vstte-2012.pdf&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;llrêve: Automatic regression verification for LLVM programs 
  &lt;ul&gt; 
   &lt;li&gt;Automatically check programs for equivalence&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/mattulbrich/llreve&quot;&gt;https://github.com/mattulbrich/llreve&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://formal.iti.kit.edu/projects/improve/reve/&quot;&gt;https://formal.iti.kit.edu/projects/improve/reve/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Relational Program Reasoning Using Compiler IR – Combining Static Verification and Dynamic Analysis 
    &lt;ul&gt; 
     &lt;li&gt;Journal of Automated Reasoning 60(3) 2017&lt;/li&gt; 
     &lt;li&gt;Moritz Kiefer, Vladimir Klebanov, Mattias Ulbrich&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;http://dx.doi.org/10.1007/s10817-017-9433-5&quot;&gt;http://dx.doi.org/10.1007/s10817-017-9433-5&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;SAW: Software Analysis Workbench 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://saw.galois.com/&quot;&gt;https://saw.galois.com/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Constructing Semantic Models of Programs with the Software Analysis Workbench 
    &lt;ul&gt; 
     &lt;li&gt;Verified Software: Theories, Tools and Experiments (VSTTE) 2016&lt;/li&gt; 
     &lt;li&gt;Robert Dockins, Adam Foltzer, Joe Hendrix, Brian Huffman, Dylan McNamee, Aaron Tomb&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://doi.org/10.1007/978-3-319-48869-1_5&quot;&gt;https://doi.org/10.1007/978-3-319-48869-1_5&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;SeaHorn Verification Framework: A fully automated analysis framework for LLVM-based languages 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;http://seahorn.github.io/&quot;&gt;http://seahorn.github.io/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/seahorn/seahorn&quot;&gt;https://github.com/seahorn/seahorn&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://seahorn.github.io/#publications&quot;&gt;http://seahorn.github.io/#publications&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;The SeaHorn Verification Framework 
    &lt;ul&gt; 
     &lt;li&gt;Computer Aided Verification (CAV) 2015&lt;/li&gt; 
     &lt;li&gt;A. Gurfinkel, T. Kahsai, A. Komuravelli, J.A.Navas&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;http://seahorn.github.io/papers/cav15.pdf&quot;&gt;http://seahorn.github.io/papers/cav15.pdf&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;A Context-Sensitive Memory Model for Verification of C/C++ Programs 
    &lt;ul&gt; 
     &lt;li&gt;Slides: &lt;a href=&quot;http://seahorn.github.io/papers/sas17_slides.pdf&quot;&gt;http://seahorn.github.io/papers/sas17_slides.pdf&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;Paper: &lt;a href=&quot;http://seahorn.github.io/papers/sea-dsa-SAS17.pdf&quot;&gt;http://seahorn.github.io/papers/sea-dsa-SAS17.pdf&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;Crab-llvm: Abstract Interpretation of LLVM bitcode 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://github.com/seahorn/crab-llvm&quot;&gt;https://github.com/seahorn/crab-llvm&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;SMACK Software Verifier and Verification Toolchain 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;http://smackers.github.io&quot;&gt;http://smackers.github.io&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/smackers/smack&quot;&gt;https://github.com/smackers/smack&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;SMACK: Decoupling Source Language Details from Verifier Implementations 
    &lt;ul&gt; 
     &lt;li&gt;Computer Aided Verification (CAV) 2014&lt;/li&gt; 
     &lt;li&gt;Zvonimir Rakamaric, Michael Emmi&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://soarlab.org/publications/2014_CAV_SMACK/&quot;&gt;https://soarlab.org/publications/2014_CAV_SMACK/&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;SMACK Software Verification Toolchain 
    &lt;ul&gt; 
     &lt;li&gt;International Conference on Software Engineering (ICSE) Companion 2016&lt;/li&gt; 
     &lt;li&gt;Montgomery Carter, Shaobo He, Jonathan Whitaker, Zvonimir Rakamaric, Michael Emmi&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://soarlab.org/publications/2016_ICSE_SMACK/&quot;&gt;https://soarlab.org/publications/2016_ICSE_SMACK/&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;Leveraging Compiler Intermediate Representation for Multi- and Cross-Language Verification 
    &lt;ul&gt; 
     &lt;li&gt;Verification, Model Checking, and Abstract Interpretation (VMCAI) 2020&lt;/li&gt; 
     &lt;li&gt;Jack Garzella, Marek S. Baranowski, Shaobo He, Zvonimir Rakamaric&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://soarlab.org/publications/2020_vmcai_gbhr/&quot;&gt;https://soarlab.org/publications/2020_vmcai_gbhr/&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Clang&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;clang-tutor: A collection of Clang plugins - learn the API through examples 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/banach-space/clang-tutor/&quot;&gt;https://github.com/banach-space/clang-tutor/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;My First Clang Warning 
  &lt;ul&gt; 
   &lt;li&gt;2019 LLVM Developers’ Meeting&lt;/li&gt; 
   &lt;li&gt;Meike Baumgärtner, Dmitri Gribenko&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=FNnKMSkaLkY&quot;&gt;https://www.youtube.com/watch?v=FNnKMSkaLkY&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://llvm.org/devmtg/2019-10/talk-abstracts.html#tut11&quot;&gt;https://llvm.org/devmtg/2019-10/talk-abstracts.html#tut11&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Clang Static Analyzer&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;Developing the Clang Static Analyzer 
  &lt;ul&gt; 
   &lt;li&gt;2019 LLVM Developers’ Meeting; Artem Dergachev&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=g0Mqx1niUi0&quot;&gt;https://www.youtube.com/watch?v=g0Mqx1niUi0&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Faster, Stronger C++ Analysis with the Clang Static Analyzer 
  &lt;ul&gt; 
   &lt;li&gt;2018 LLVM Developers’ Meeting; George Karpenkov, Artem Dergachev&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=4n3l-ZcDJNY&quot;&gt;https://www.youtube.com/watch?v=4n3l-ZcDJNY&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Introduction&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;Building Program Reasoning Tools using LLVM and Z3 
  &lt;ul&gt; 
   &lt;li&gt;POPL 2020 Tutorial&lt;/li&gt; 
   &lt;li&gt;Introduction to LLVM and Z3; Static Dataflow Analysis, Dynamic Symbolic Execution, Assertion Verification&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://rightingcode.org/tutorials/popl20/&quot;&gt;http://rightingcode.org/tutorials/popl20/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Getting Started With LLVM: Basics 
  &lt;ul&gt; 
   &lt;li&gt;2019 LLVM Developers’ Meeting; Jessica Paquette, Florian Hahn&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=3QQuhL-dSys&quot;&gt;https://www.youtube.com/watch?v=3QQuhL-dSys&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;How to Contribute to LLVM 
  &lt;ul&gt; 
   &lt;li&gt;2019 LLVM Developers’ Meeting; Chris Bieneman, Kit Barton&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=C5Y977rLqpw&quot;&gt;https://www.youtube.com/watch?v=C5Y977rLqpw&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Introduction to LLVM 
  &lt;ul&gt; 
   &lt;li&gt;2019 LLVM Developers’ Meeting&lt;/li&gt; 
   &lt;li&gt;Eric Christopher &amp;amp; Johannes Doerfert&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=J5xExRGaIIY&quot;&gt;https://www.youtube.com/watch?v=J5xExRGaIIY&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://llvm.org/devmtg/2019-10/talk-abstracts.html#tut9&quot;&gt;https://llvm.org/devmtg/2019-10/talk-abstracts.html#tut9&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Intrinsics, Metadata, and Attributes: The story continues! 
  &lt;ul&gt; 
   &lt;li&gt;2016 LLVM Developers’ Meeting&lt;/li&gt; 
   &lt;li&gt;Hal Finkel, Argonne National Laboratory&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=jII0AcgU_5c&quot;&gt;https://www.youtube.com/watch?v=jII0AcgU_5c&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;LLVM IR Tutorial - Phis, GEPs and other things, oh my! 
  &lt;ul&gt; 
   &lt;li&gt;2019 EuroLLVM Developers’ Meeting; Vince Bridgers, Felipe de Azevedo Piovezan (Intel)&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=m8G_S5LwlTo&quot;&gt;https://www.youtube.com/watch?v=m8G_S5LwlTo&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;LLVM Seminar - Northeastern+MIT 
  &lt;ul&gt; 
   &lt;li&gt;2019; Mike Shah&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://www.mshah.io/#Talks&quot;&gt;http://www.mshah.io/#Talks&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/playlist?list=PLvv0ScY6vfd8NDoT7qUab4VVAWV67oH-N&quot;&gt;https://www.youtube.com/playlist?list=PLvv0ScY6vfd8NDoT7qUab4VVAWV67oH-N&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Introduction to LLVM 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=KTMk45Q0d-8&amp;amp;list=PLvv0ScY6vfd8NDoT7qUab4VVAWV67oH-N&quot;&gt;https://www.youtube.com/watch?v=KTMk45Q0d-8&amp;amp;list=PLvv0ScY6vfd8NDoT7qUab4VVAWV67oH-N&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;http://www.mshah.io/LLVM/NortheasternMITIntroduction%20to%20LLVM.pdf&quot;&gt;http://www.mshah.io/LLVM/NortheasternMITIntroduction%20to%20LLVM.pdf&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;http://www.mshah.io/LLVM/llvm_6_3_19.zip&quot;&gt;http://www.mshah.io/LLVM/llvm_6_3_19.zip&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;Introduction to Clang 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=RAzre6PA-WI&amp;amp;list=PLvv0ScY6vfd8NDoT7qUab4VVAWV67oH-N&quot;&gt;https://www.youtube.com/watch?v=RAzre6PA-WI&amp;amp;list=PLvv0ScY6vfd8NDoT7qUab4VVAWV67oH-N&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;http://www.mshah.io/LLVM/NortheasternMITIntroductiontoClang.pdf&quot;&gt;http://www.mshah.io/LLVM/NortheasternMITIntroductiontoClang.pdf&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;Introduction to Program Analysis using LLVM 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;http://www.mshah.io/LLVM/NortheasternMITIntroductiontoProgramAnalysisusingLLVM.pdf&quot;&gt;http://www.mshah.io/LLVM/NortheasternMITIntroductiontoProgramAnalysisusingLLVM.pdf&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=w6SD3ramrwI&amp;amp;list=PLvv0ScY6vfd8NDoT7qUab4VVAWV67oH-N&quot;&gt;https://www.youtube.com/watch?v=w6SD3ramrwI&amp;amp;list=PLvv0ScY6vfd8NDoT7qUab4VVAWV67oH-N&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Security Research and Development with LLVM - Andrew Reiter 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/roachspray/opcde2017&quot;&gt;https://github.com/roachspray/opcde2017&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/comaeio/OPCDE/tree/master/2017/Security%20Research%20and%20Development%20with%20LLVM%20-%20Andrew%20Reiter&quot;&gt;https://github.com/comaeio/OPCDE/tree/master/2017/Security%20Research%20and%20Development%20with%20LLVM%20-%20Andrew%20Reiter&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Examples - &lt;a href=&quot;https://github.com/roachspray/opcde2017/tree/master/code&quot;&gt;https://github.com/roachspray/opcde2017/tree/master/code&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;clang-llvm-tutorial 
  &lt;ul&gt; 
   &lt;li&gt;Clang and LLVM Tutorial Examples (AST Interpreter, Function Pointer Analysis, Value Range Analysis, Data-Flow Analysis, Andersen Pointer Analysis, LLVM Backend)&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/lijiansong/clang-llvm-tutorial/&quot;&gt;https://github.com/lijiansong/clang-llvm-tutorial/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Custom Alias Analysis in LLVM 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://blog.tartanllama.xyz/llvm-alias-analysis/&quot;&gt;https://blog.tartanllama.xyz/llvm-alias-analysis/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Introduction to LLVM: Building simple program analysis tools and instrumentation 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://fosdem.org/2018/schedule/track/llvm_toolchain/&quot;&gt;FOSDEM 2018&lt;/a&gt; - Mike Shah&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://fosdem.org/2018/schedule/event/introduction/&quot;&gt;https://fosdem.org/2018/schedule/event/introduction/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=VKIv_Bkp4pk&quot;&gt;https://www.youtube.com/watch?v=VKIv_Bkp4pk&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;slides &amp;amp; code: &lt;a href=&quot;http://www.mshah.io/fosdem18.html&quot;&gt;http://www.mshah.io/fosdem18.html&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;LLVMPlayground: Small sample programs that use LLVM and Clang APIs. 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/modocache/LLVMPlayground&quot;&gt;https://github.com/modocache/LLVMPlayground&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Mapping High Level Constructs to LLVM IR 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/f0rki/mapping-high-level-constructs-to-llvm-ir&quot;&gt;https://github.com/f0rki/mapping-high-level-constructs-to-llvm-ir&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://mapping-high-level-constructs-to-llvm-ir.readthedocs.io/&quot;&gt;https://mapping-high-level-constructs-to-llvm-ir.readthedocs.io/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.cs.sfu.ca/~wsumner/&quot;&gt;Nick Sumner&lt;/a&gt;&apos;s Examples 
  &lt;ul&gt; 
   &lt;li&gt;slides: &lt;a href=&quot;https://www.cs.sfu.ca/~wsumner/teaching/886/llvm.pdf&quot;&gt;https://www.cs.sfu.ca/~wsumner/teaching/886/llvm.pdf&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;llvm-demo: A simple example of how LLVM can be used to gather static or dynamic facts about a program. 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://github.com/nsumner/llvm-demo&quot;&gt;https://github.com/nsumner/llvm-demo&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;callgraph-profiler-template: A template for an introductory project on dynamic analysis using LLVM 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://github.com/nsumner/callgraph-profiler-template&quot;&gt;https://github.com/nsumner/callgraph-profiler-template&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;clang-plugins-demo: A simple example of defining custom plugins for Clang and the Clang Static Analyzer 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://github.com/nsumner/clang-plugins-demo&quot;&gt;https://github.com/nsumner/clang-plugins-demo&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;llvm-dataflow-analysis: (very simple) static intraprocedural dataflow analyses 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://github.com/nsumner/llvm-dataflow-analysis&quot;&gt;https://github.com/nsumner/llvm-dataflow-analysis&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;overflower-template: Template for a project to teach basic static dataflow analysis using LLVM 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://github.com/nsumner/overflower-template&quot;&gt;https://github.com/nsumner/overflower-template&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;path-profiler-template: A template for a path profiling project using LLVM 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://github.com/nsumner/path-profiler-template&quot;&gt;https://github.com/nsumner/path-profiler-template&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Quarkslab blog 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://blog.quarkslab.com/global-dead-code-elimination-for-llvm-revisited.html&quot;&gt;https://blog.quarkslab.com/global-dead-code-elimination-for-llvm-revisited.html&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://blog.quarkslab.com/turning-regular-code-into-atrocities-with-llvm-the-return.html&quot;&gt;https://blog.quarkslab.com/turning-regular-code-into-atrocities-with-llvm-the-return.html&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://blog.quarkslab.com/turning-regular-code-into-atrocities-with-llvm.html&quot;&gt;https://blog.quarkslab.com/turning-regular-code-into-atrocities-with-llvm.html&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Writing a basic clang static analysis check 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://bbannier.github.io/blog/2015/05/02/Writing-a-basic-clang-static-analysis-check.html&quot;&gt;https://bbannier.github.io/blog/2015/05/02/Writing-a-basic-clang-static-analysis-check.html&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Instrumentation&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;Creating an LLVM Sanitizer from Hopes and Dreams 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://blog.trailofbits.com/2019/06/25/creating-an-llvm-sanitizer-from-hopes-and-dreams/&quot;&gt;https://blog.trailofbits.com/2019/06/25/creating-an-llvm-sanitizer-from-hopes-and-dreams/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;llvm-sanitizer-tutorial and documentation 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://github.com/trailofbits/llvm-sanitizer-tutorial&quot;&gt;https://github.com/trailofbits/llvm-sanitizer-tutorial&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Instrew: Leveraging LLVM for High Performance Dynamic Binary Instrumentation 
  &lt;ul&gt; 
   &lt;li&gt;VEE 2020&lt;/li&gt; 
   &lt;li&gt;Alexis Engelke, Martin Schulz&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://conf.researchr.org/details/vee-2020/vee-2020-papers/5/Instrew-Leveraging-LLVM-for-High-Performance-Dynamic-Binary-Instrumentation&quot;&gt;https://conf.researchr.org/details/vee-2020/vee-2020-papers/5/Instrew-Leveraging-LLVM-for-High-Performance-Dynamic-Binary-Instrumentation&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/aengelke/instrew&quot;&gt;https://github.com/aengelke/instrew&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Loom: LLVM instrumentation library 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/cadets/loom&quot;&gt;https://github.com/cadets/loom&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;PolyTracker: An LLVM-based instrumentation tool for universal taint analysis. 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/trailofbits/polytracker&quot;&gt;https://github.com/trailofbits/polytracker&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://blog.trailofbits.com/2019/11/01/two-new-tools-that-tame-the-treachery-of-files/&quot;&gt;https://blog.trailofbits.com/2019/11/01/two-new-tools-that-tame-the-treachery-of-files/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;QBDI (QuarkslaB Dynamic binary Instrumentation): A Dynamic Binary Instrumentation framework based on LLVM 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://qbdi.quarkslab.com&quot;&gt;https://qbdi.quarkslab.com&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/quarkslab/QBDI&quot;&gt;https://github.com/quarkslab/QBDI&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;34C3 (2017) Implementing an LLVM based Dynamic Binary Instrumentation framework: &lt;a href=&quot;https://events.ccc.de/congress/2017/Fahrplan/events/9006.html&quot;&gt;https://events.ccc.de/congress/2017/Fahrplan/events/9006.html&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Example: plugging Triton on top of QBDI - &lt;a href=&quot;http://shell-storm.org/repo/Notepad/qbdi_with_triton.txt&quot;&gt;http://shell-storm.org/repo/Notepad/qbdi_with_triton.txt&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;A Preliminary Test of QBDI - &lt;a href=&quot;https://www.johnfxgalea.com/2018/01/13/a-preliminary-test-of-qbdi/&quot;&gt;https://www.johnfxgalea.com/2018/01/13/a-preliminary-test-of-qbdi/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Example: SRAC - a Simple Return Address Checker - &lt;a href=&quot;https://github.com/johnfxgalea/SRAC&quot;&gt;https://github.com/johnfxgalea/SRAC&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;sbt-instrumentation: Configurable instrumentation of LLVM bitcode 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/staticafi/sbt-instrumentation&quot;&gt;https://github.com/staticafi/sbt-instrumentation&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Instrumentation of LLVM IR - &lt;a href=&quot;https://is.muni.cz/th/409920/fi_m/?lang=en&quot;&gt;https://is.muni.cz/th/409920/fi_m/?lang=en&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Lifting&lt;/h3&gt; 
&lt;p&gt;Lifting: Disassembly, Decompilation, Recompilation, Reverse Engineering&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;ANVILL Decompiler Toolchain 
  &lt;ul&gt; 
   &lt;li&gt;ANVILL forges beautiful LLVM bitcode out of raw machine code&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/lifting-bits/anvill&quot;&gt;https://github.com/lifting-bits/anvill&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;decomp: Compositional Decompilation using LLVM IR 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/decomp/decomp&quot;&gt;https://github.com/decomp/decomp&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Design documents: &lt;a href=&quot;https://github.com/decomp/doc&quot;&gt;https://github.com/decomp/doc&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;llvm-mctoll 
  &lt;ul&gt; 
   &lt;li&gt;This tool statically (AOT) translates (or raises) binaries to LLVM IR.&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/Microsoft/llvm-mctoll&quot;&gt;https://github.com/Microsoft/llvm-mctoll&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Raising binaries to LLVM IR with MCTOLL 
    &lt;ul&gt; 
     &lt;li&gt;LCTES 2019 (WIP paper)&lt;/li&gt; 
     &lt;li&gt;S. Bharadwaj Yadavalli, Aaron Smith&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://dl.acm.org/citation.cfm?id=3326354&quot;&gt;https://dl.acm.org/citation.cfm?id=3326354&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://conf.researchr.org/details/LCTES-2019/LCTES-2019-papers/15/Raising-Binaries-to-LLVM-IR-with-MCTOLL-Work-in-progress-&quot;&gt;https://conf.researchr.org/details/LCTES-2019/LCTES-2019-papers/15/Raising-Binaries-to-LLVM-IR-with-MCTOLL-Work-in-progress-&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;McSema: Framework for lifting x86, amd64, and aarch64 program binaries to LLVM bitcode 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.trailofbits.com/research-and-development/mcsema/&quot;&gt;https://www.trailofbits.com/research-and-development/mcsema/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/lifting-bits/mcsema&quot;&gt;https://github.com/lifting-bits/mcsema&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Decompiling Binaries into LLVM IR Using McSema and Dyninst 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://is.muni.cz/th/pxe1j/?lang=en&quot;&gt;https://is.muni.cz/th/pxe1j/?lang=en&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Rellic: produces goto-free C output from LLVM bitcode 
  &lt;ul&gt; 
   &lt;li&gt;Rellic is an implementation of the pattern-independent structuring algorithm to produce a goto-free C output from LLVM bitcode.&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/lifting-bits/rellic&quot;&gt;https://github.com/lifting-bits/rellic&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Rellume — Lifts x86-64 to LLVM IR 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/aengelke/rellume&quot;&gt;https://github.com/aengelke/rellume&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Rellume is a lifter for x86-64 machine code to LLVM IR with focus on the performance of the lifted code. The generated LLVM IR can be compiled and executed again, for example using LLVM&apos;s JIT compiler, ideally having the same (or even better) performance as the original code.&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Remill: Library for lifting of x86, amd64, and aarch64 machine code to LLVM bitcode 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/lifting-bits/remill&quot;&gt;https://github.com/lifting-bits/remill&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;RetDec: a retargetable machine-code decompiler based on LLVM 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://retdec.com/&quot;&gt;https://retdec.com/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/avast-tl/retdec&quot;&gt;https://github.com/avast-tl/retdec&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;revng: a static binary translator 
  &lt;ul&gt; 
   &lt;li&gt;revng is a static binary translator. Given a input ELF binary for one of the supported architectures (currently MIPS, ARM and x86-64) it will analyze it and emit an equivalent LLVM IR. To do so, revng employs the QEMU intermediate representation (a series of TCG instructions) and then translates them to LLVM IR.&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://rev.ng/&quot;&gt;https://rev.ng/&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/revng/revng&quot;&gt;https://github.com/revng/revng&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Passes&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;Building, Testing and Debugging a Simple out-of-tree LLVM Pass 
  &lt;ul&gt; 
   &lt;li&gt;2016 EuroLLVM Developers&apos; Meeting&lt;/li&gt; 
   &lt;li&gt;Serge Guelton &amp;amp; Adrien Guinet&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://llvm.org/devmtg/2016-03/Tutorials/Tutorial.pdf&quot;&gt;http://llvm.org/devmtg/2016-03/Tutorials/Tutorial.pdf&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/quarkslab/llvm-dev-meeting-tutorial-2015&quot;&gt;https://github.com/quarkslab/llvm-dev-meeting-tutorial-2015&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://blog.quarkslab.com/goto-llvm_dev_meeting.html&quot;&gt;https://blog.quarkslab.com/goto-llvm_dev_meeting.html&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=Z5KcwVaak3s&quot;&gt;https://www.youtube.com/watch?v=Z5KcwVaak3s&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;llvm-pass-tutorial: A step-by-step tutorial for building an LLVM sample pass 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/abenkhadra/llvm-pass-tutorial&quot;&gt;https://github.com/abenkhadra/llvm-pass-tutorial&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;llvm-tutor: Basic LLVM passes for learning the API 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/banach-space/llvm-tutor&quot;&gt;https://github.com/banach-space/llvm-tutor&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Writing an LLVM Pass: 101 
    &lt;ul&gt; 
     &lt;li&gt;2019 LLVM Developers’ Meeting; Andrzej Warzynski&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=ar7cJl2aBuU&quot;&gt;https://www.youtube.com/watch?v=ar7cJl2aBuU&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;http://llvm.org/devmtg/2019-10/talk-abstracts.html#tut4&quot;&gt;http://llvm.org/devmtg/2019-10/talk-abstracts.html#tut4&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Legacy Pass Manager&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;2007 LLVM Developer&apos;s Meeting 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;http://llvm.org/devmtg/2007-05/03-Patel-Passmanager.pdf&quot;&gt;http://llvm.org/devmtg/2007-05/03-Patel-Passmanager.pdf&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;LLVM Pass Manager Demystified (1 of 3) - &lt;a href=&quot;https://www.youtube.com/watch?v=dZOrlikTaik&quot;&gt;https://www.youtube.com/watch?v=dZOrlikTaik&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;LLVM Pass Manager Demystified (2 of 3) - &lt;a href=&quot;https://www.youtube.com/watch?v=PaUWxVLGBg0&quot;&gt;https://www.youtube.com/watch?v=PaUWxVLGBg0&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;LLVM Pass Manager Demystified (3 of 3) - &lt;a href=&quot;https://www.youtube.com/watch?v=4HEy5EtVdCA&quot;&gt;https://www.youtube.com/watch?v=4HEy5EtVdCA&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;New Pass Manager&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;New PM: taming a custom pipeline of Falcon JIT 
  &lt;ul&gt; 
   &lt;li&gt;2018 EuroLLVM Developers’ Meeting - Fedor Sergeev, Azul Systems&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=6X12D46sRFw&quot;&gt;https://www.youtube.com/watch?v=6X12D46sRFw&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://llvm.org/devmtg/2018-04/slides/Sergeev-Taming%20a%20custom%20pipeline%20of%20Falcon%20JIT.pdf&quot;&gt;http://llvm.org/devmtg/2018-04/slides/Sergeev-Taming%20a%20custom%20pipeline%20of%20Falcon%20JIT.pdf&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;The LLVM Pass Manager, Part 2 
  &lt;ul&gt; 
   &lt;li&gt;2014 LLVM Developers&apos; Meeting&lt;/li&gt; 
   &lt;li&gt;Chandler Carruth, Google&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://llvm.org/devmtg/2014-10/#talk11&quot;&gt;https://llvm.org/devmtg/2014-10/#talk11&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://llvm.org/devmtg/2014-10/Slides/Carruth-TheLLVMPassManagerPart2.pdf&quot;&gt;https://llvm.org/devmtg/2014-10/Slides/Carruth-TheLLVMPassManagerPart2.pdf&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Video: &lt;a href=&quot;http://web.archive.org/web/20160718071630/http://llvm.org/devmtg/2014-10/Videos/The%20LLVM%20Pass%20Manager%20Part%202-720.mov&quot;&gt;http://web.archive.org/web/20160718071630/http://llvm.org/devmtg/2014-10/Videos/The%20LLVM%20Pass%20Manager%20Part%202-720.mov&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Passes in LLVM, Part 1 
  &lt;ul&gt; 
   &lt;li&gt;2014 European LLVM Conference&lt;/li&gt; 
   &lt;li&gt;Chandler Carruth&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=rY02LT08-J8&quot;&gt;https://www.youtube.com/watch?v=rY02LT08-J8&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://llvm.org/devmtg/2014-04/PDFs/Talks/Passes.pdf&quot;&gt;https://llvm.org/devmtg/2014-04/PDFs/Talks/Passes.pdf&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Writing LLVM Pass in 2018 
  &lt;ul&gt; 
   &lt;li&gt;Preface - &lt;a href=&quot;https://medium.com/@mshockwave/writing-llvm-pass-in-2018-preface-6b90fa67ae82&quot;&gt;https://medium.com/@mshockwave/writing-llvm-pass-in-2018-preface-6b90fa67ae82&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Part I: Write a new HelloWorld Pass in new pass manager fashion 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://medium.com/@mshockwave/writing-llvm-pass-in-2018-preface-6b90fa67ae82&quot;&gt;https://medium.com/@mshockwave/writing-llvm-pass-in-2018-preface-6b90fa67ae82&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;Part II - AnalysisManager - &lt;a href=&quot;https://medium.com/@mshockwave/writing-llvm-pass-in-2018-part-ii-640f680978ec&quot;&gt;https://medium.com/@mshockwave/writing-llvm-pass-in-2018-part-ii-640f680978ec&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Part III - In-Tree Pass Integration - &lt;a href=&quot;https://medium.com/@mshockwave/writing-llvm-pass-in-2018-part-iii-d44cd0c2c354&quot;&gt;https://medium.com/@mshockwave/writing-llvm-pass-in-2018-part-iii-d44cd0c2c354&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h1&gt;Readings&lt;/h1&gt; 
&lt;ul&gt; 
 &lt;li&gt;A Few Billion Lines of Code Later: Using Static Analysis to Find Bugs in the Real World 
  &lt;ul&gt; 
   &lt;li&gt;Communications of the ACM, Vol. 53 No. 2, 2010&lt;/li&gt; 
   &lt;li&gt;Al Bessey, Ken Block, Ben Chelf, Andy Chou, Bryan Fulton, Seth Hallem, Charles Henri-Gros, Asya Kamsky, Scott McPeak, Dawson Engler&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://cacm.acm.org/magazines/2010/2/69354-a-few-billion-lines-of-code-later/fulltext&quot;&gt;https://cacm.acm.org/magazines/2010/2/69354-a-few-billion-lines-of-code-later/fulltext&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Analysing the Program Analyser 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://srg.doc.ic.ac.uk/publications/analyse-analyser-icse-v2025.html&quot;&gt;https://srg.doc.ic.ac.uk/publications/analyse-analyser-icse-v2025.html&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Continuous Reasoning: Scaling the Impact of Formal Methods 
  &lt;ul&gt; 
   &lt;li&gt;Logic in Computer Science (LISC) 2018; Peter O&apos;Hearn&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://research.fb.com/publications/continuous-reasoning-scaling-the-impact-of-formal-methods/&quot;&gt;https://research.fb.com/publications/continuous-reasoning-scaling-the-impact-of-formal-methods/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;From Start-ups to Scale-ups: Opportunities and Open Problems for Static and Dynamic Program Analysis 
  &lt;ul&gt; 
   &lt;li&gt;IEEE International Working Conference on Source Code Analysis and Manipulation (SCAM) 2018&lt;/li&gt; 
   &lt;li&gt;Mark Harman, Peter O&apos;Hearn&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://research.fb.com/publications/from-start-ups-to-scale-ups-opportunities-and-open-problems-for-static-and-dynamic-program-analysis/&quot;&gt;https://research.fb.com/publications/from-start-ups-to-scale-ups-opportunities-and-open-problems-for-static-and-dynamic-program-analysis/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;How to Prevent the next Heartbleed 
  &lt;ul&gt; 
   &lt;li&gt;2014; David A. Wheeler&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://dwheeler.com/essays/heartbleed.html&quot;&gt;https://dwheeler.com/essays/heartbleed.html&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Lessons from Building Static Analysis Tools at Google (2018) 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://cacm.acm.org/magazines/2018/4/226371-lessons-from-building-static-analysis-tools-at-google/fulltext&quot;&gt;https://cacm.acm.org/magazines/2018/4/226371-lessons-from-building-static-analysis-tools-at-google/fulltext&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Pointer analysis: haven&apos;t we solved this problem yet? 
  &lt;ul&gt; 
   &lt;li&gt;PASTE 2001&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://dl.acm.org/citation.cfm?id=379665&quot;&gt;https://dl.acm.org/citation.cfm?id=379665&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://www.cs.trinity.edu/~mlewis/CSCI3294-F01/Papers/p54-hind.pdf&quot;&gt;http://www.cs.trinity.edu/~mlewis/CSCI3294-F01/Papers/p54-hind.pdf&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Righting Software 
  &lt;ul&gt; 
   &lt;li&gt;IEEE Software, May 2004&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.microsoft.com/en-us/research/publication/righting-software/&quot;&gt;https://www.microsoft.com/en-us/research/publication/righting-software/&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Source Code Analysis: A Road Map 
  &lt;ul&gt; 
   &lt;li&gt;Future of Software Engineering (FOSE) 2007&lt;/li&gt; 
   &lt;li&gt;David Binkley&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://dl.acm.org/citation.cfm?id=1254713&quot;&gt;https://dl.acm.org/citation.cfm?id=1254713&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Static versus dynamic analysis---an illusory distinction? 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.cs.kent.ac.uk/people/staff/srk21/blog/research/static-and-dynamic-analyses.html&quot;&gt;https://www.cs.kent.ac.uk/people/staff/srk21/blog/research/static-and-dynamic-analyses.html&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>The Art of Concurrency</title>
      <link>https://tedneward.github.io/Research/reading/development/art-of-concurrency/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">reading/development/art-of-concurrency/index.html</guid>
      	<description>
	&lt;p&gt;&lt;em&gt;(by (author), (publisher))&lt;/em&gt;&lt;/p&gt; 
&lt;h1&gt;8 Simple Rules for Designing Multithreaded Applications&lt;/h1&gt; 
&lt;ol&gt; 
 &lt;li&gt;Identify truly independent computations&lt;/li&gt; 
 &lt;li&gt;Implement concurrency at the highest level possible&lt;/li&gt; 
 &lt;li&gt;Plan early for scalability&lt;/li&gt; 
 &lt;li&gt;Make use of thread-safe libraries&lt;/li&gt; 
 &lt;li&gt;Use the right threading model (don&apos;t use explicit threads if an implicit model will do)&lt;/li&gt; 
 &lt;li&gt;Never assume a particular order of execution&lt;/li&gt; 
 &lt;li&gt;Use thread-local storage or associate locks to specific data&lt;/li&gt; 
 &lt;li&gt;Dare to change the algorithm for a better chance of concurrency&lt;/li&gt; 
&lt;/ol&gt; 
&lt;h1&gt;Terminology&lt;/h1&gt; 
&lt;p&gt;&lt;strong&gt;Barrier&lt;/strong&gt; -- sync object that blocks all threads until every thread has arrived; upon arrival of last thread, all threads are released to continue&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Benign Data Race&lt;/strong&gt; -- data race w/no adverse consequences&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Complete Binary Tree&lt;/strong&gt; -- binary tree in which each level (except perhas the deepest) is full; leaf nodes placed as far left as possible&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;CRCW/CREW/ERCW/EREW&lt;/strong&gt; -- Concurrent vs Exclusive Read vs Write&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Data Decomposition&lt;/strong&gt; -- identify independent work forcusing on dividing large data sets that can be processed concurrently&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Data Flow Parallelism&lt;/strong&gt; -- execute an instruction when args are ready (as opposed to the original sequence in which instruction was written)&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Data Race&lt;/strong&gt; -- 2+ threads accessing same resource/location where one is attempting to update&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Deadlock&lt;/strong&gt; -- 1+ threads are waiting for an event that will never occur&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Fork-Join Parallelism&lt;/strong&gt; -- threads are forked/spawned, execute, and join before continuing&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Livelock&lt;/strong&gt; -- threads doing same computation are unable to proceed due to the actions of some other thread (Robin Hood &amp;amp; Little John meeting on the log bridge)&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Modulo Locks&lt;/strong&gt; -- associate multiple indexed objects w/ single lock&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Mutex/Mutual Exclusion&lt;/strong&gt; -- only allow one thread to execute given portion of code&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Race Condition&lt;/strong&gt; -- flaw in which result depends on timing or sequence of multiple threads&apos; execution&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Reduction&lt;/strong&gt; -- computation that takes large data set and computes a value from that data; operation performed must be associative &amp;amp; commutative&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Semaphore&lt;/strong&gt; -- Sync object w/ associated non-negative count w/2 operations: post (increment count) &amp;amp; wait (if ct != 0, decrement count, else block until ct &amp;gt; 0)&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Starvation&lt;/strong&gt; -- thread is not allowed to proceed (usually due to higher-priority threads getting scheduled first)&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Task Decomposition&lt;/strong&gt; -- identify independent work focusing on the computations to be performed by the threads&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Art of UNIX Programming</title>
      <link>https://tedneward.github.io/Research/reading/development/art-of-unix-programming/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:56 +0000</pubDate>
      <guid isPermaLink="false">reading/development/art-of-unix-programming/index.html</guid>
      	<description>
	&lt;p&gt;&lt;em&gt;(by Eric S Raymond (Addison-Wesley, 2004, ISBN 0-13-142901-9))&lt;/em&gt;&lt;/p&gt; 
&lt;h1&gt;Basics of the UNIX Philosophy&lt;/h1&gt; 
&lt;p&gt;&lt;strong&gt;Rule of Modularity&lt;/strong&gt;: Write simple parts connected by clean interfaces&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Rule of Clarity&lt;/strong&gt;: Clarity is better than cleverness&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Rule of Composition&lt;/strong&gt;: Design programs to be connected with other programs&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Rule of Separation&lt;/strong&gt;: Separate policy from mechanism; separate interfaces from engines&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Rule of Simplicity&lt;/strong&gt;: Design for simplicity; add complexity only where you must&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Rule of Parsimony&lt;/strong&gt;: Write a big program only when it is clear by demonstration that nothing else will do&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Rule of Transparency&lt;/strong&gt;: Design for visibility to make inspection and debugging easier&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Rule of Robustness&lt;/strong&gt;: Robustness is the child of transparency and simplicity&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Rule of Representation&lt;/strong&gt;: Fold knowledge into data, so program logic can be stupid and robust&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Rule of Least Surprise&lt;/strong&gt;: In interface design, always do the least surprising thing&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Rule of Silence&lt;/strong&gt;: When a program has nothing surprising to say, it should say nothing&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Rule of Repair&lt;/strong&gt;: Repair what you can--but when you must fail, fail noisily and as soon as possible&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Rule of Economy&lt;/strong&gt;: Programmer time is expensive; conserve it in preference to machine time&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Rule of Generation&lt;/strong&gt;: Avoid hand-hacking; write programs to write programs when you can&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Rule of Optimization&lt;/strong&gt;: Prototype before polishing. Get it working before you optimize it&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Rule of Diversity&lt;/strong&gt;: Distrust all claims for &quot;one true way&quot;&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Rule of Extensibility&lt;/strong&gt;: Design for the future, because it will be here sooner than you think&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Business Reading</title>
      <link>https://tedneward.github.io/Research/reading/business/index/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">reading/business/index/index.html</guid>
      	<description>
	&lt;h2&gt;Reading&lt;/h2&gt; 
&lt;h3&gt;Websites&lt;/h3&gt; 
&lt;p&gt;&lt;a href=&quot;https://commoncog.com/&quot;&gt;Commoncog&lt;/a&gt;: Commoncog helps business leaders and investors make better decisions in uncertain times, by expanding the set of business scenarios that they recognise in their heads. We research and publish business cases that help you do better, organised according to business concepts, using a theory of accelerated expertise that’s proven to work.&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://commoncog.com/syllabus/&quot;&gt;Commoncog Syllabus&lt;/a&gt;: This syllabus is the recommended path to consume Commoncog’s exploration of business expertise. Start Here.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://commoncog.com/goodharts-law-not-useful/&quot;&gt;Goodhart&apos;s Law Isn&apos;t as Useful as you might think&lt;/a&gt;: &quot;It is descriptive; it tells you of the existence of a phenomenon, but it doesn’t tell you what to do about it or how to solve it. ... The first step is to turn Goodhart’s Law as a narrower, more actionable formulation. The one that I like the most is from Deming contemporary Donald Wheeler, who writes, in &lt;a href=&quot;https://www.goodreads.com/book/show/63859&quot;&gt;Understanding Variation&lt;/a&gt;: &lt;pre&gt;&lt;code&gt;&amp;gt; When people are pressured to meet a target value there are three ways they can proceed:
&amp;gt; 
&amp;gt; 1) They can work to improve the system
&amp;gt; 2) They can distort the system
&amp;gt; 3) Or they can distort the data
&lt;/code&gt;&lt;/pre&gt; &lt;p&gt;Joiner’s list suggests a number of solutions:&lt;/p&gt; 
  &lt;ul&gt; 
   &lt;li&gt;Make it difficult to distort the system. 
    &lt;ul&gt; 
     &lt;li&gt;Make it difficult to distort the data, and&lt;/li&gt; 
     &lt;li&gt;Give people the slack necessary to improve the system (a tricky thing to do, which we’ve covered elsewhere).&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;p&gt;The third point is really important. Preventing distortions is just one half of the solution. Avoiding Goodhart’s Law requires you to also give people the space to improve the system.&quot;&lt;/p&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;&lt;a href=&quot;https://newsletter.pragmaticengineer.com/&quot;&gt;Pragmatic Engineer&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://projects.propublica.org/claimfile/&quot;&gt;ProPublica&lt;/a&gt;: Find out why your health insurer denied your claim. ProPublica’s Claim File Helper lets you customize a letter requesting the notes and documents your insurer used when deciding to deny you coverage. Get your claim file before submitting an appeal.&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://theorg.com/&quot;&gt;TheOrg&lt;/a&gt;: Find the right person to contact in any organization. (Commercial?)&lt;/p&gt; 
&lt;h3&gt;Articles/Blogs&lt;/h3&gt; 
&lt;p&gt;&lt;a href=&quot;https://apenwarr.ca/log/20230605&quot;&gt;Tech debt metaphor maximalism&lt;/a&gt;: &quot;I really like the &quot;tech debt&quot; metaphor. A lot of people don&apos;t, but I think that&apos;s because they either don&apos;t extend the metaphor far enough, or because they don&apos;t properly understand financial debt.&quot; &lt;em&gt;Really&lt;/em&gt; good read on how to think about tech debt as a direct extension of financial debt.&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://www.linkedin.com/posts/weskao_most-companies-suck-at-communicating-the-activity-6934551400383201280-ONcW&quot;&gt;12 Ways to Show Your Value&lt;/a&gt;:&lt;/p&gt; 
&lt;ol&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Pour salt on the wound&lt;/strong&gt;: No pain, no sale. People will only value your solution if they value their problem. If they don’t think their problem is that bad, they won’t pay you to solve it. When in doubt, emphasize the pain. Painkillers sell better than vitamins.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Use before-and-after&lt;/strong&gt;: An effective before-and-after skips all the boring parts. It’s like a jump cut in a movie. It emphasizes &lt;em&gt;contrast&lt;/em&gt;. This heightens drama and interest. The best before-and-afters make you say wow.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Don’t jump right to the solution&lt;/strong&gt;: Instead, explain how much $ the problem costs and how it’s making your customer’s life hard. Then talk about your product &amp;amp; how you’ll make their problem go away.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Show, don’t tell&lt;/strong&gt;: I came across AI-driven software that reduces background noise on Zoom calls. Their website has a toggle on/off button where you can hear a sound sample without vs with their tool. That demo was worth 10,000 words.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Increase desire, don’t just decrease friction&lt;/strong&gt;: People jump through hoops for things they want. Did you pick your spouse because they were the most convenient option? Of course not. You picked them despite obstacles.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Explain &quot;why now?&quot;&lt;/strong&gt;: Most folks AGREE that your product is great--but they still don’t buy. What they’re really thinking: “Do I need this enough to pay $ right now? Or can I do this later?&quot; Later often means never.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Be/Do/Have&lt;/strong&gt;: This is a classic framework in leadership coaching but applies to marketing. What does your product let your customer &lt;em&gt;be&lt;/em&gt; that they weren’t before? What can they &lt;em&gt;do&lt;/em&gt; now that they couldn’t do before? What do they &lt;em&gt;have&lt;/em&gt; now that they didn’t have before?&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Aim for “no-brainer status&quot;&lt;/strong&gt;: You need to aim for an instant yes. Not a yes after 100+ touchpoints of nurturing. Think about what would get that reaction. You likely won’t get an instant yes. But if you aim for it, it’ll speed up getting there.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Do what makes their eyes light up (ELU)&lt;/strong&gt;: You can tell when people listen to be polite. But there are moments when aliveness flashes in their eyes--you just said something they care about. Watch for ELU. It&apos;s data on what to do more of.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Avoid backstory scope creep&lt;/strong&gt;: It&apos;s easy to get carried away sharing background info. Remove 90% of it. You need less backstory than you think.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Focus on what your customer wants to hear, not what you want to talk about&lt;/strong&gt;: This is an easy way to trim from your pitch.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Consider overhauling&lt;/strong&gt;: If you’re struggling to describe your product’s value, figure out if the problem is (A) the marketing or (B) the offer itself. If your underlying offer isn’t good, no amount of improving the marketing will help.&lt;/p&gt; &lt;/li&gt; 
&lt;/ol&gt; 
&lt;p&gt;&lt;a href=&quot;https://newsletter.pragmaticengineer.com/p/the-scoop-fast&quot;&gt;&quot;The Scoop: Inside Fast&apos;s Rapid Collapse&quot;&lt;/a&gt;:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;a well-funded scaleup could be closer to bankruptcy than it seems 
  &lt;ul&gt; 
   &lt;li&gt; &lt;p&gt;How was Fast able to hire hundreds of people of this caliber? Money, storytelling, and equity:&lt;/p&gt; 
    &lt;ul&gt; 
     &lt;li&gt; &lt;p&gt;Fast paid very strong base salaries, told a great story, and offered lavish equity. Most engineers joining didn&apos;t know much about why the one-click checkout industry has the potential of billions. What they did know is Fast offered at or above base salaries of Big Tech, directors shared an enthusiastic story of the company being a rocketship, and they were granted equity which seemed like a golden ticket to retirement.&lt;/p&gt; &lt;/li&gt; 
     &lt;li&gt; &lt;p&gt;Fast base salaries were top of the market. For senior software engineers, Fast offered $200-240K/year in base salaries with full remote work. They offered this range not just in the US, but outside it, when hiring in Europe, converting the base salary to Euros (€180-€220K/year).&lt;/p&gt; &lt;/li&gt; 
     &lt;li&gt; &lt;p&gt;Large sign-on bonuses were common for engineers. Those who asked for it all received sign-on bonuses of $20-50K as a one-off payment. These types of sign-on bonuses are not uncommon at Big Tech but are much more rare at startups that are unprofitable. These large sign-on bonuses added to the feeling that Fast is doing well financially. Sign-on bonuses are typically repayable when the employee quits the company within 12 months. In some ways, the sign-on bonuses made the layoffs more bearable for those who joined recently, as they can keep the full amount.&lt;/p&gt; &lt;/li&gt; 
     &lt;li&gt; &lt;p&gt;Equity issued was lavish and presented as potentially life-changing. Senior software engineers received anywhere from 15,000 to 80,000 stock options, vesting over 4 years, with a 1-year cliff.&lt;/p&gt; &lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;Visualizing the potential stock upside was a major reason many candidates chose Fast over Big Tech offers where the stock was liquid.&lt;/p&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;Exploding offers because of “the inevitability of the Series C closing” was used as a tactic to close candidates at the end of 2021.&lt;/p&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;Warning signs within the company:&lt;/p&gt; 
    &lt;ul&gt; 
     &lt;li&gt;A hockey stick of growth presented across the company - but with the Y-axis being employees.&lt;/li&gt; 
     &lt;li&gt;Tiny daily sales numbers that leadership and senior employees received&lt;/li&gt; 
     &lt;li&gt;Fast did less than $300K worth of sales and below $6K in revenue on most days&lt;/li&gt; 
     &lt;li&gt;Not having large clients on their platform&lt;/li&gt; 
     &lt;li&gt;Sales vs engineering and sales winning. I have reports of engineering directly raising concerns to the CEO, and suggesting to focus on larger customers, fewer customizations, and bring in more revenue. Sales, however, wanted the opposite: close many deals and hit their targets of signups. In the end, sales got their way, and the strategy of many small merchants stayed in place.&lt;/li&gt; 
     &lt;li&gt;The new CFO instituting an immediate hiring freeze&lt;/li&gt; 
     &lt;li&gt;A warning sign could have been the annual burn rate just for engineering - for anyone who would have done the math. Most software engineers at Fast were at the senior or above level, making $200K/year or more. Fast had about 150 engineers by early 2022. The burn rate of just the base salaries for engineers would have been around $30M/year (150 x $200,000), not counting sign-on bonuses. Engineering was a third of the company’s headcount, though likely a more expensive third. With this math, it’s not hard to understand how Fast burned through its $100M investment in just over a year.&lt;/li&gt; 
     &lt;li&gt;A cofounder going radio silent starting in March was another warning sign.&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;Advice when joining startups&lt;/p&gt; 
    &lt;ul&gt; 
     &lt;li&gt;Do your research on the company and founders. Do your homework on the history of the company, and past red flags. I did this when I got a reachout to potentially interview for Fast in the second half of 2020. I found some unsettling information about the founder of Fast, Dominic Holland. From his previous startup going bust, him firing staff over a text and threatening to sell sensitive personal records. In the early days of Fast, he terminated contract software engineers in Africa with no justification after the raised funding off the prototype they built, never acknowledging their work.&lt;/li&gt; 
     &lt;li&gt;Ask for numbers. How much runway does the company have left? What is the burn per month? What is the revenue of the company, and what is the spending? Especially when joining at senior levels - Staff engineer or above, Director or above - it should be a red flag if people don’t share these numbers with you, at least verbally. If you get pushback, you can always use the Fast story as reasoning on why you want to know these numbers.&lt;/li&gt; 
     &lt;li&gt;Ask if there is a clear set of key business metrics are and if engineers have access to these close to real-time. Is it the number of users? Revenue? Signups? Percentage of returning daily users? If the answer is “no” to either of the questions, treat it as a red flag. In the case of Fast, these metrics were likely not defined, and the data was not shared with all engineers.&lt;/li&gt; 
     &lt;li&gt;Reverse interview your future manager and a founder. Once you have an offer, ask to talk with your future manager and a founder. Collect all your doubts and questions, and ask them on the spot.&lt;/li&gt; 
     &lt;li&gt;Ask to talk with lead investors. Investors are almost always happy to jump on a call to talk with potential candidates. Expect that this will mostly be a sell call, where the investors share why they invested in the company. Still, you might find out information.&lt;/li&gt; 
     &lt;li&gt;Talk with people who left. Try to find people who left the startup, and who were in a similar position to what you are applying for. Message them on LinkedIn, and ask if they can share why they left. A surprisingly large number of them tend to reply.&lt;/li&gt; 
     &lt;li&gt;For executive positions: reach out to VCs. If you are joining as a Director or above, do backchannel checks through the VC network. If you already have VC connections, ask if they can get you information on the startup. If you don’t yet have VC connections, try reaching out to VCs on Twitter or LinkedIn who work at some of the well-known funds I list in the article Finding the next company to work at.&lt;/li&gt; 
     &lt;li&gt;Make a plan if the stock grant is worthless.&lt;/li&gt; 
     &lt;li&gt;Know that risk and reward are often connected.&lt;/li&gt; 
     &lt;li&gt;Not every startup operates like Fast, but many startups face the same types of problems that Fast had.&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Meeting the Challenge of Disruptive Change</title>
      <link>https://tedneward.github.io/Research/reading/business/meeting-the-challenge/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">reading/business/meeting-the-challenge/index.html</guid>
      	<description>
	&lt;p&gt;&lt;em&gt;(by Clayton M Christensen and Michael Overdorf, from &quot;HBR&apos;s 10 Must Reads: The Essentials&quot;)&lt;/em&gt;&lt;/p&gt; 
&lt;p&gt;Why do so few established companies innovate successfully? When a new venture captures the established firms&apos; imagination, they get their people working on it within organizational structures (such as functional teams) designed to surmount old challenges--not ones that the new venture is facing. To avoid this mistake, ask:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;&quot;Does my organization have the right resources to support this innovation?&quot;&lt;/strong&gt; Resources supporting business-as-usual (people, technologies, product designs, brands, customer and supplier relationships) rarely match those required for new ventures.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;&quot;Does my organization have the right processes to innovate?&quot;&lt;/strong&gt; Processes supporting your established business (decision-making protocols, coordination patterns) may hamstring the new venture.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;&quot;Does my organization have the right values to innovate?&quot;&lt;/strong&gt; Consider how you decide whether to commit to a new venture. For example, can you tolerate lower profit margins than your established enterprise demands?&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;&quot;What team and structure will best support our innovation effort?&quot;&lt;/strong&gt; Should you use a team dedicated to the project within your company? Create a separate spin-off organization?&lt;/p&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;By selecting the right team and organizational structure for your innovation--and infusing it with the right resources, processes, and values--you heighten your chances of innovating successfully.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Selecting the Right Structure for Your Innovation&lt;/strong&gt;&lt;/p&gt; 
&lt;table&gt; 
 &lt;thead&gt; 
  &lt;tr&gt;
   &lt;th&gt;If your innovation... &lt;/th&gt;
   &lt;th&gt; Select this type of team... &lt;/th&gt;
   &lt;th&gt; To operate... &lt;/th&gt;
   &lt;th&gt; Because...&lt;/th&gt;
  &lt;/tr&gt; 
 &lt;/thead&gt; 
 &lt;tbody&gt; 
  &lt;tr&gt;
   &lt;td&gt;Fits &lt;em&gt;well&lt;/em&gt; with your existing values and processes &lt;/td&gt;
   &lt;td&gt; &lt;strong&gt;Functional teams&lt;/strong&gt; who work sequentially on issues, or &lt;strong&gt;lightweight teams&lt;/strong&gt;--ad-hoc cross-functional teams who work simultaneously on multiple issues &lt;/td&gt;
   &lt;td&gt; Within your existing organization &lt;/td&gt;
   &lt;td&gt; Owing to the good fit with existing processes and values, no new capabilities or organizational structures are called for.&lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt;Fits &lt;em&gt;well&lt;/em&gt; with existing values but &lt;em&gt;poorly&lt;/em&gt; with existing processes &lt;/td&gt;
   &lt;td&gt; &lt;strong&gt;Heavyweight team&lt;/strong&gt; dedicated exclusively to the innovation project, with complete responsibility for its success &lt;/td&gt;
   &lt;td&gt; Within your existing organization &lt;/td&gt;
   &lt;td&gt; The poor fit with existing processes requires new types of coordination among groups and individuals.&lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt;Fits &lt;em&gt;poorly&lt;/em&gt; with existing values but &lt;em&gt;well&lt;/em&gt; with existing processes &lt;/td&gt;
   &lt;td&gt; &lt;strong&gt;Heavyweight team&lt;/strong&gt; dedicated exclusively to the innovation project, with complete responsibility for its success &lt;/td&gt;
   &lt;td&gt; Within your existing organization for development, followed by a spin-off for commercialization &lt;/td&gt;
   &lt;td&gt; In-house development capitalizes on existing processes. A spin-off for the commercialization phase facilitates new values--such as a different cost structure with lower profit margins.&lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt;Fits &lt;em&gt;poorly&lt;/em&gt; with your existing processes and values &lt;/td&gt;
   &lt;td&gt; &lt;strong&gt;Heavyweight team&lt;/strong&gt; dedicated exclusively to the innovation project, with complete responsibility for its success &lt;/td&gt;
   &lt;td&gt; In a separate spin-off or acquired organization &lt;/td&gt;
   &lt;td&gt; A spin-off enables the project to be governed by different values and ensures that new processes emerge.&lt;/td&gt;
  &lt;/tr&gt; 
 &lt;/tbody&gt; 
&lt;/table&gt; 
&lt;h3&gt;In more depth&lt;/h3&gt; 
&lt;p&gt;What managers lack is a habit of thinking about their organization&apos;s capabilities as carefully as they think about individual people&apos;s capabilities.&lt;/p&gt; 
&lt;p&gt;Where capabilities reside: its resources, its processes, and its values.&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;strong&gt;Resources&lt;/strong&gt;: (tangible) people, equipment, technologies, cash, (less tangible) product designs, information, brands, relationships with suppliers/distributors/customers.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Processes&lt;/strong&gt;: patterns of interaction, coordination, communication, and decision-making employees use. Processes, by their very nature, are set up so that employees perform tasks in a consistent way time after time--they are meant not to change. When people use a process to do the task it was designed for, the process will perform well; when using it for a very different task, it is likely to perform sluggishly. The most important capabilities and concurrent disabilities aren&apos;t necessarily embodied in the most visible processes; they are more likely to be in the less visible, background processes that support decisions about where to invest resources--those that define how market research is habitually done, how such analysis is translated into financial projections, how plans and budgets are negotiated internally, and so on. It is in those processes that many organizations&apos; most serious disabilities in coping with change reside.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Values&lt;/strong&gt;: An organization&apos;s values are the standards by which employees set priorities that enable them to judge whether an order is attractive or unattractive/whether a customer is more important or less important/whether an idea for a new product is attractive or marginal/etc. Prioritization decisions are made by employees at every level. The larger/more complex a company becomes, the more important it is for senior managers to train employees throughout the organization to make independent decisions about priorities that are consistent with the strategic direction and the business model of the company. A key metric is whether such clear, consistent values have permeated the organization.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;We want to focus on two sets of values in particular that tend to evolve in most companies in very predictable ways. The inexorable evolution of these two values is what makes companies progressively less capable of addressing disruptive change successfully.&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;The way the company judges acceptable gross margins.&lt;/li&gt; 
 &lt;li&gt;How big a business opportunity has to be before it can be interesting. It follows that an opportunity that excites a small company isn&apos;t big enough to be interesting to a large company. One of the bittersweet results of success, in fact, is that as companies become large, they lose the ability to enter into small, emerging markets. This disability is not caused by a change in resources within the companies--rather it&apos;s caused by an evolution in values.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;The Migration of Capabilities&lt;/h3&gt; 
&lt;p&gt;In the early stages of an organization, much of what gets done is attributable to resources--people, in particular. The addition/departure of a few key people can profoundly influence its success. Over time, the locus of the organization&apos;s capabilities shifts towards its processes and values. (One reason that many soaring young companies flame out after an IPO based on a single hot product is that their initial success is grounded in resources--often the founding engineers--and they fail to develop processes that can create a sequence of hot products.) At some successful companies, the processes and values have become so powerful that it almost doesn&apos;t matter which people get assigned to which project teams--the company is able to crank out high-quality work year after year because its core capabilities are rooted in its processes and values rather than its resources.&lt;/p&gt; 
&lt;p&gt;The founder has early influence, and employees experience for themselves the validity of the founder&apos;s problem-solving and decision-making methods. Thus processes become defined. Likewise, if the company becomes financially successful by allocating resources according to criteria that reflect the founder&apos;s priorities, the company&apos;s values coalesce around those criteria. (From here,these processes and values become enshrined as culture, enabling employees to act autonomously but causes them to act consistently.) As long as the organization continues to face the same sorts of problems that its processes and values were designed to address, managing the organization can be straightforward. But because those factos also define what an organization cannot do, they consititute disabilities when the problems facing the company change fundamentally.&lt;/p&gt; 
&lt;h3&gt;Sustaining vs Disruptive Innovation&lt;/h3&gt; 
&lt;p&gt;Sustaining innovations are evolutionary changes in markets, and successful companies are pretty good at responding to them. Disruptive innovations are those that are revolutionary, that create an entirely new market through the introduction of a new kind of product or service, one that&apos;s actually worse, as judged by the performance metrics that mainstream customers value.&lt;/p&gt; 
&lt;p&gt;Sustaining innovations are nearly always developed and introduced by established industry leaders. Those same companies never introduce--or cope well with--disruptive innovations, because the evolution from people to processes and values means that the organization has (through repeated execution) optimized for solving a particular kind of problem--and disruptive innovations are, by definition, not that particular kind of problem. Large companies often surrender emerging growth markets, and smaller, disruptive companies are actually more capable of pursuing them. Startups lack resources, but that doesn&apos;t matter--their values can embrace small markets and their cost structures can embrace low margins. Their market research and resource allocation processes allow managers to proceed intuitively; every decision need not be backed by careful research and analysis. All these advantages add up to the ability to embrace and even initiate disruptive change. But how can a large company develop these capabilities?&lt;/p&gt; 
&lt;h3&gt;Creating Capabilities to Cope with Change&lt;/h3&gt; 
&lt;p&gt;Processes are not nearly as flexible or adaptable as resources are--and values are even less so. So when an org needs new processes and values--because it needs new capabilities--managers must create new organizational space where those capabilities can be developed. There are three ways to do that:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt; &lt;p&gt;create new organizational structures within corporate boundaries in which new processes can be developed.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;spin out an independent organization from the existing organization and develop within it the new processes and values required to solve the new problem.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;acquire a different organization whose processes and values close match the requirements of the new task.&lt;/p&gt; &lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Product Roadmaps</title>
      <link>https://tedneward.github.io/Research/reading/business/product-roadmaps/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">reading/business/product-roadmaps/index.html</guid>
      	<description>
	&lt;p&gt;&lt;em&gt;(by Lombardo, McCarthy, Ryan, Connors)&lt;/em&gt;&lt;/p&gt; 
&lt;h3&gt;Chapter 1: Relaunching Roadmaps&lt;/h3&gt; 
&lt;p&gt;Roadmap is a strategic communication tool, a statement of intent and direction; describes how you intend to achieve your product vision. It focuses on the value you propose to deliver for your customer and your organization in order to rally support and coordinate effort among stakeholders.&lt;/p&gt; 
&lt;p&gt;Product: how you deliver value to your organization&apos;s customers.&lt;/p&gt; 
&lt;p&gt;Stakeholder: all the internal and external colleagues and partners who are involved with the product being developed, marketed, sold, and serviced.&lt;/p&gt; 
&lt;p&gt;Customer: the recipient of the value your product provides. Buyer and user are often the same, but not always.&lt;/p&gt; 
&lt;p&gt;Product roadmap should:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Put the organization&apos;s plans in a strategic context 
  &lt;ul&gt; 
   &lt;li&gt;Problem: Nobody understands why things are on the roadmap&lt;/li&gt; 
   &lt;li&gt;Solution: Tie the roadmap to a compelling vision of the future&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Focus on delivering value to customers and the organization 
  &lt;ul&gt; 
   &lt;li&gt;Problem: You are shipping a lot but not making progress&lt;/li&gt; 
   &lt;li&gt;Solution: Focus the roadmap on delivering value&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Embrace learning as part of a successful product development process 
  &lt;ul&gt; 
   &lt;li&gt;Problem: Executives and customers demand commitments&lt;/li&gt; 
   &lt;li&gt;Solution: Commit to outcomes rather than output&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Rally the organization around a single set of priorities 
  &lt;ul&gt; 
   &lt;li&gt;Problem: Marketing and sales are not selling what you are making&lt;/li&gt; 
   &lt;li&gt;Solution: Align everyone around common goals and priorities&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Get customers excited about the product&apos;s direction 
  &lt;ul&gt; 
   &lt;li&gt;Problem: Customers aren&apos;t excited about your new features&lt;/li&gt; 
   &lt;li&gt;Solution: Use the roadmap to reality-check your direction with customers&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;Product roadmap should NOT:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Make promises a team cannot deliver 
  &lt;ul&gt; 
   &lt;li&gt;Problem: Your stakeholders and customers expect a firm commitment on dates for your product releases&lt;/li&gt; 
   &lt;li&gt;Solution: Prioritization is critical to deliver on your commitments&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Require wasteful up-front design and estimation 
  &lt;ul&gt; 
   &lt;li&gt;Problem: Time spent estimating design and development efforts takes time away from actually implementing them&lt;/li&gt; 
   &lt;li&gt;Solution: Let the teams determine the solutions, and allow them to solve the problem&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Should not be confused with a release plan or a project plan 
  &lt;ul&gt; 
   &lt;li&gt;Problem: Your team looks at the roadmap as if it were a project plan when features will be released&lt;/li&gt; 
   &lt;li&gt;Solution: Commit to outcomes rather than output&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Chapter 2: Components of a Roadmap&lt;/h3&gt; 
&lt;p&gt;Primary components:&lt;br&gt; * Product vision is your guiding principle&lt;br&gt; * Business objectives help to measure progress&lt;br&gt; * Themes focus on outcomes rather than output; &quot;What would need to be true for our product to realize its vision and attain its business objectives?&quot;&lt;br&gt; * Broad timeframes avoid overcommitment&lt;br&gt; * Disclaimer protects you (and your customer)&lt;/p&gt; 
&lt;p&gt;Secondary components to answer the concerns of certain stakeholders:&lt;br&gt; * Features and solutions show how you intend to deliver on your themes&lt;br&gt; * Confidence&lt;br&gt; * Stage of development&lt;br&gt; * Target customers (if your product serves more than one customer)&lt;br&gt; * Product areas&lt;/p&gt; 
&lt;p&gt;Complementary information to provide context for your roadmap:&lt;br&gt; * Project information&lt;br&gt; * Platform considerations&lt;br&gt; * Financial context&lt;br&gt; * External drivers&lt;/p&gt; 
&lt;h3&gt;Chapter 3: Gathering Inputs&lt;/h3&gt; 
&lt;h3&gt;Chapter 4: Establishing the Why with Product Vision and Strategy&lt;/h3&gt; 
&lt;p&gt;Mission defines your intent. Four key elements: value (what value does your mission bring to the world), inspiration (how does your mission inspire your team to make the vision a reality), plausibility (is your mission realistic and achievable), and specificity (is your mission specific to your business, industry and/or sector).&lt;/p&gt; 
&lt;p&gt;Vision is the outcome you seek.&lt;/p&gt; 
&lt;p&gt;Values are beliefs and ideals.&lt;/p&gt; 
&lt;p&gt;Product vision: Why your product exists.&lt;/p&gt; 
&lt;p&gt;Value proposition template:&lt;/p&gt; 
&lt;p&gt;For: (target customer)&lt;/p&gt; 
&lt;p&gt;Who: (target customer&apos;s needs)&lt;/p&gt; 
&lt;p&gt;The: (product name)&lt;/p&gt; 
&lt;p&gt;Is a: (product category)&lt;/p&gt; 
&lt;p&gt;That: (product benefit/reason to buy)&lt;/p&gt; 
&lt;p&gt;Unlike: (competitors)&lt;/p&gt; 
&lt;p&gt;Our product: (differentiator)&lt;/p&gt; 
&lt;p&gt;Supports our: (objective(s))&lt;/p&gt; 
&lt;p&gt;Universal business objectives:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Sustainable value:&lt;br&gt; * Support the product&apos;s core value&lt;br&gt; * Create barriers to competition 
  &lt;ul&gt; 
   &lt;li&gt;Growth 
    &lt;ul&gt; 
     &lt;li&gt;Grow market share&lt;/li&gt; 
     &lt;li&gt;Fulfill more demand&lt;/li&gt; 
     &lt;li&gt;Develop new markets&lt;/li&gt; 
     &lt;li&gt;Improve recurring revenue&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt;Profit 
    &lt;ul&gt; 
     &lt;li&gt;Support higher prices&lt;/li&gt; 
     &lt;li&gt;Improve lifetime value&lt;/li&gt; 
     &lt;li&gt;Lower costs&lt;/li&gt; 
     &lt;li&gt;Leverage existing assets&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Chapter 5: Uncovering Customer Needs Through Themes&lt;/h3&gt; 
&lt;p&gt;Identifying customer needs is the most important aspect of your roadmapping process. Draw a clear distinction between the product roadmap and the release plan. Themes are an organizational construct for defining what&apos;s important to your customers at the present time. A theme is a high-level customer need. A subtheme is a more specific need. Themes are about outcomes, not outputs.&lt;/p&gt; 
&lt;p&gt;Opportunity-Solution Trees (&lt;a href=&quot;https://www.producttalk.org/opportunity-solution-tree&quot;&gt;https://www.producttalk.org/opportunity-solution-tree&lt;/a&gt;)&lt;/p&gt; 
&lt;p&gt;Expected Outcome (Objective)&lt;br&gt; * Opportunity (Themes)&lt;br&gt; * Opportunity&lt;br&gt; * Opportunity&lt;br&gt; * Solution (Features)&lt;br&gt; * Solution&lt;br&gt; * Experiment&lt;br&gt; * Experiment&lt;/p&gt; 
&lt;p&gt;Job stories (similar to user stories):&lt;br&gt; When (situation/motivation)&lt;br&gt; I need (desire)&lt;br&gt; So I can (result)&lt;/p&gt; 
&lt;p&gt;Themes:&lt;br&gt; Ensure (result) for (stakeholder)&lt;/p&gt; 
&lt;p&gt;Tie the themes back to your strategic objective. (Product vision -&amp;gt; Objectives -&amp;gt; Themes and subthemes)&lt;/p&gt; 
&lt;h3&gt;Chapter 6: Deepening Your Roadmap&lt;/h3&gt; 
&lt;p&gt;Add secondary information to flesh out the picture.&lt;/p&gt; 
&lt;p&gt;Features and Solutions: How They Can Work with Themes&lt;br&gt; * Probable solutions (with a relatively high degree of confidence)&lt;br&gt; * Infrastructure solutions&lt;br&gt; * Carryover solutions&lt;/p&gt; 
&lt;p&gt;Stages of Development: discovery, market research, R&amp;amp;D, design, testing, prototyping, development, pre-production, alpha, beta, early access, and so on. Spotify uses &quot;think it&quot;, &quot;ship it&quot; or &quot;tweak it&quot;.&lt;/p&gt; 
&lt;p&gt;Confidence: Nothing should ever be 100% confident. (0.2 to 0.8 confidence levels)&lt;/p&gt; 
&lt;p&gt;Identifying Target Customers.&lt;/p&gt; 
&lt;p&gt;Strive for Balance--don&apos;t bury the roadmap in secondary details.&lt;/p&gt; 
&lt;h3&gt;Chapter 7: Prioritizing--with Science!&lt;/h3&gt; 
&lt;p&gt;Why Prioritization is Crucial&lt;br&gt; * Opportunity Cost&lt;br&gt; * Shiny Object Syndrome&lt;br&gt; * Exponential Test Matrix Growth&lt;br&gt; Bad Ways to Prioritize&lt;br&gt; * Your (or someone else&apos;s) gut&lt;br&gt; * Analyst opinions&lt;br&gt; * Popularity&lt;br&gt; * Sales requests&lt;br&gt; * Support requests&lt;br&gt; * Competitive me-too features&lt;br&gt; Prioritization frameworks&lt;br&gt; * Critical path: What is the one thing (or set of things) our solution needs to get right?&lt;br&gt; * Use to: Identify the &quot;one thing&quot; that will drive a customer to buy&lt;br&gt; * Choose When: Designing an MVP or making a major expansion in product scope&lt;br&gt; * Downsides: Does not take into account effort, risk, or business goals; does not rank needs finer than &quot;critical&quot; or &quot;noncritical&quot;&lt;br&gt; * Kano (from Dr Noriaki Kano): classifying customer expectations into three broad categories: expected needs, normal needs, and exciting needs. Expected needs not met lead to dissatisfiers. Normal needs are satisfiers. Exciting needs are delighters and go beyond the customer&apos;s experience.&lt;br&gt; * Use to: Understand how customers perceive relative value&lt;br&gt; * Choose When: Identifying possible add-ons or enhancements&lt;br&gt; * Downsides: Does not take into account effort, risk or business goals&lt;br&gt; * Desirability (Do customers want it?), Feasibility (Can we--and how easily can we--build it?), Viability (Can we make money on it?); use a 1 (low), 2 (medium), 3 (high) scale for each possibility&lt;br&gt; * Use to: Identify opportunities that meet all key criteria for success&lt;br&gt; * Choose When: Prioritizing a relatively small set of initiatives or solutions to a particular problem&lt;br&gt; * Downsides: Categories are not clearly defined in terms of customer needs, organization goals, or different types of effort or risk&lt;br&gt; * ROI scorecard: Value/Effort = Priority&lt;br&gt; * Strategy defines value; Value = Customer&apos;s Needs + Organization&apos;s Goals&lt;br&gt; * Deliberate imprecision; be wary of complexity here&lt;br&gt; * Estimating effort; don&apos;t scare engineers away; T-shirt sizing&lt;br&gt; * Think cross-functionally&lt;br&gt; * Risks and unknowns&lt;br&gt; * Full Formula: ((CN1 + CN2 + CNn + … + BO1 + BO2 + BOn…) / (E1 + E2 + En…)) x C = P&lt;br&gt; § CN: Customer&apos;s Need&lt;br&gt; § BO: Business Objective&lt;br&gt; § E: Effort&lt;br&gt; § C: Confidence&lt;br&gt; § P: Priority&lt;br&gt; * Use to: Rank ideas according to return-on-investment criteria&lt;br&gt; * Choose When: Weighing multiple factors and/or a long list of possible initiatives, problems to solve, features, or solutions&lt;br&gt; * Downsides: More complex model requires alignment on different components of value and effort&lt;br&gt; * MoSCoW method: Must-have, Should-have, Could-have, Won&apos;t-have&lt;br&gt; * Use to: Communicate launch criteria&lt;br&gt; * Choose When: Feeling uncertain about what must be included in a product/service/release&lt;br&gt; * Downsides: Does not help set priorities, only communicate them&lt;/p&gt; 
&lt;h3&gt;Chapter 8: Achieving Alignment and Buy-in&lt;/h3&gt; 
&lt;p&gt;Alignment (concerted effort to help people understand the issues and what their respective roles are), consensus (a group of people reaching a mutually agreed-upon decision; in practice, a potential for a passive-aggressive mess), collaboration (individuals cooperate to accomplish a common goal or outcome; individuals work together for a shared purpose--they may not concur on everything each step of the way, but they do agree on the final outcome).&lt;/p&gt; 
&lt;p&gt;Shuttle diplomacy: meeting with each party individually to reach decisions that require compromise and trade-offs. Politics (and strong voices drowning out quieter ones) can ruin attempts at alignment--much more manageable in one-on-one meetings. You can focus the conversation on common goals if it&apos;s just you and them, with nobody else in the room for them to answer to or try to impress. Entice stakeholders with a draft of your roadmap and ask for their input; always tie the meeting to goals and objectives. Use GROW (Goals/Reality/Options/Way forward) to guide the conversation.&lt;/p&gt; 
&lt;p&gt;Co-creation workshop. Needs to have clear plan and outcomes before you hold it. Outcome is to finalize the roadmap for the upcoming period. Loose agenda:&lt;br&gt; * Intro and rules (5 min)&lt;br&gt; * Hopes and fears (5 min): each individual writes their hopes for the product&apos;s future on one color of Post-It/index card, and fears on another color. Objective is to draw out everyone&apos;s emotional aspirations and fears and see how they align with each other and with the established business objectives.&lt;br&gt; * Vision and goals (10 min): articulate the product vision (if it&apos;s not already determined). Follow this prompt: &quot;A world where the (target customer) no longer suffers from the (identified problem) because of (product differentiator) they (benefit).&quot; Pare this down to: &quot;To (benefit realized) by (product differentiator).&quot;&lt;br&gt; * Back-plan (15 min): start with the end result of the cover story (PR/FAQ) and work gradually backward to the present. Each step backward must be realistic, so teams are forced to think through all the different changes necessary.&lt;br&gt; * Sizing and prioritizing (40 min): Example: spend $100 on particular customer needs.&lt;br&gt; * Wrap-up (10 min)&lt;/p&gt; 
&lt;h3&gt;Chapter 9: Presenting and Sharing Your Roadmap&lt;/h3&gt; 
&lt;p&gt;(Why, risks, different types of presentations to different kinds of audiences, etc)&lt;/p&gt; 
&lt;h3&gt;Chapter 10: Keeping It Fresh&lt;/h3&gt; 
&lt;p&gt;(When, where and how to incorporate change into the roadmap)&lt;/p&gt; 
&lt;h3&gt;Chapter 11: Relaunching Roadmaps in Your Organization&lt;/h3&gt; 
&lt;p&gt;(Steps for re-launching roadmaps into an organization that has gotten away from them)&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Art of the Start</title>
      <link>https://tedneward.github.io/Research/reading/business/art-of-the-start/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">reading/business/art-of-the-start/index.html</guid>
      	<description>
	&lt;p&gt;&lt;em&gt;(by Guy Kawasaki, ISBN ...)&lt;/em&gt;&lt;/p&gt; 
&lt;h3&gt;Chapter 1: The Art of Starting&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;pg 8: Create a mantra for your employees as a guideline; a tagline is for your customers.&lt;/li&gt; 
 &lt;li&gt;pg 9: Don&apos;t write up a business plan, craft a pitch, or start financial projections until you have a prototype.&lt;/li&gt; 
 &lt;li&gt;pg 13: Don&apos;t revise your product to get prospective customers to love it; revise it because customers already love it.&lt;/li&gt; 
 &lt;li&gt;pg 14: Be sure you can describe your business model in ten words or less, and don&apos;t be afraid to copy one.&lt;/li&gt; 
 &lt;li&gt;pg 16: Important milestones are prove a concept, complete design specifications, build a prototype, raise capital, ship a testable version, ship a final version, and achieve break-even.&lt;/li&gt; 
 &lt;li&gt;pg 17: List the assumptions about the business, and link them to the milestones above so that you can test them as you reach milestones.&lt;/li&gt; 
 &lt;li&gt;pg 24: Never admit you&apos;re scared to other employees -- a CEO can never have a bad day.&lt;/li&gt; 
 &lt;li&gt;pg 24: There is much more to gain by freely discussing your idea than there is to lose.&lt;/li&gt; 
 &lt;li&gt;pg 24: If three close friends tell you to give up, you should listen.&lt;/li&gt; 
 &lt;li&gt;pg 25: Make a web site, business cards, and a letterhead immediately for customers, partners, and investors to look at.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Chapter 2: The Art of Positioning&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;pg 29: Positioning states why an organization was started, why customers should patronize it, and why good people should work at it.&lt;/li&gt; 
 &lt;li&gt;pg 31: Ensure that your positioning is long-lasting, and that it does not sound like your competitors&apos;.&lt;/li&gt; 
 &lt;li&gt;pg 33: Target a small niche -- from there you can establish a beachhead and expand your companies into different areas.&lt;/li&gt; 
 &lt;li&gt;pg 35: When choosing a company name, avoid numbers, try for verb potential, ensure it sounds like nothing else, and it should match what you do.&lt;/li&gt; 
 &lt;li&gt;pg 38: Make your positioning personal so a potential customer can clearly see how your product fills a need.&lt;/li&gt; 
 &lt;li&gt;pg 40: Avoid overfamiliar adjectives and find unique language or offer scientific proof points to describe your product.&lt;/li&gt; 
 &lt;li&gt;pg 41: New hires can provide a rich vein for a positioning statement because it&apos;s from a fresh, outward-facing perspective.&lt;/li&gt; 
 &lt;li&gt;pg 41: Communicating your positioning is every employee&apos;s job; provide a refresh every six months.&lt;/li&gt; 
 &lt;li&gt;pg 43: Don&apos;t lie when projecting your image, but don&apos;t go out of your way to look undercapitalized, premature, and weak.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Chapter 3: The Art of Pitching&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;pg 45: Explain what your organization does in the first minute; don&apos;t make it an auto-biographical narrative.&lt;/li&gt; 
 &lt;li&gt;pg 47: Before pitching, learn from your sponsor what the audience would like to learn, and what attracted them to the idea and gave them an opportunity to meet.&lt;/li&gt; 
 &lt;li&gt;pg 48: Brainstorm to find connections, hooks, and angles to make the pitch more powerful and meaningful to your audience.&lt;/li&gt; 
 &lt;li&gt;pg 49: The pitch is to simulate interest, not to close a deal, so only have ten slides or so; don&apos;t include a stupid slide about liquidity.&lt;/li&gt; 
 &lt;li&gt;pg 50: Be able to give your pitch in 20 minutes, to allow time for discussion, or in case the previous meeting ran late.&lt;/li&gt; 
 &lt;li&gt;pg 56: Get there early to make sure everything works, but bring your own projector, laptop, and printouts of the presentation just in case.&lt;/li&gt; 
 &lt;li&gt;pg 56: At the beginning of the pitch, ask how much time you have, and if there is anything in particular they would like to know.&lt;/li&gt; 
 &lt;li&gt;pg 59: If bold, catalyze fantasy, where you provide a line of reasoning that says everyone needs your product, and market size numbers are irrelevant.&lt;/li&gt; 
 &lt;li&gt;pg 61: Have someone take notes at the pitch, and play it back to make sure you got the correct information. Then follow through, and quickly.&lt;/li&gt; 
 &lt;li&gt;pg 62: Patch your pitch after each meeting in response to the most recent questions and objections, but throw away your presentation after ten or so pitches.&lt;/li&gt; 
 &lt;li&gt;pg 63: Use a dark background with sans serif fonts, with your logo on every slide, and with diagrams and graphs. Never nest bullets, and reveal them one at a time.&lt;/li&gt; 
 &lt;li&gt;pg 65: Don&apos;t send your presentation ahead of time; if you hand it out at the start of the meeting, ask them not to skip ahead.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Chapter 4: The Art of Writing a Business Plan&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;pg 68: A business plan won&apos;t win over investors, but it&apos;s a necessity; use it to find holes in your strategy and in your team.&lt;/li&gt; 
 &lt;li&gt;pg 68: The plan is a detailed vision of a pitch, so only begin working it once you have the pitch right.&lt;/li&gt; 
 &lt;li&gt;pg 70: The executive summary, which takes the place of the title slide in your pitch, is the most important part of the plan.&lt;/li&gt; 
 &lt;li&gt;pg 70: Don&apos;t let it exceed 20 pages, include the key metrics, simplify financial projections to two pages, and state the assumptions behind those projections.&lt;/li&gt; 
 &lt;li&gt;pg 71: Investors require five years of projections to help them understand your scale, the capital required, and consider your inherent assumptions.&lt;/li&gt; 
 &lt;li&gt;pg 73: Write as if you know exactly what the future holds, but react opportunistically when you encounter reality.&lt;/li&gt; 
 &lt;li&gt;pg 74: To make your plan stand out, provide a list of customers the reader can call to discuss how much they need or already love your service.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Chapter 5: The Art of Bootstrapping&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;pg 80: Managing for cash flow means passing up sales that take a long time to collect, and stretching out payments on expenses.&lt;/li&gt; 
 &lt;li&gt;pg 83: Don&apos;t worry about testing; if you would let your mother or father use the product or service in its current state, ship it.&lt;/li&gt; 
 &lt;li&gt;pg 84: When building a team, focus on affordability; young, unproven people don&apos;t know what they don&apos;t know, so they&apos;re willing to try anything.&lt;/li&gt; 
 &lt;li&gt;pg 87: When choosing service providers, hire the right people with good references, even if that means paying more, but always negotiate.&lt;/li&gt; 
 &lt;li&gt;pg 90: Using a reseller isolates you from customers, requires volume to compensate for decreased profit margins, and extends time to delivery.&lt;/li&gt; 
 &lt;li&gt;pg 91: By positioning yourself against a market leader, you can utilize their brand awareness to save marketing, promotion, and advertising dollars.&lt;/li&gt; 
 &lt;li&gt;pg 93: You need someone grounded with ten years of operating experience; typically a CFO, COO, controller, or accountant who can make hard decisions like firing.&lt;/li&gt; 
 &lt;li&gt;pg 94: Intentionally understaff to bootstrap; this may slow your ascent, but its&apos; better than laying people off or running out of money.&lt;/li&gt; 
 &lt;li&gt;pg 95: A great board of directors can provide guidance and help you get money, but can&apos;t be hard to build without funding in the first place.&lt;/li&gt; 
 &lt;li&gt;pg 97: Set and communicate goals, designate people responsible for them, measure the execution of them every 30 days, and praise execution.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Chapter 6: The Art of Recruiting&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;pg 101: The CEO must hire a management team that is better than he is; the management team must hire employees better than it is.&lt;/li&gt; 
 &lt;li&gt;pg 102: If you&apos;re not getting a reference that&apos;s superlative, you&apos;re getting a negative one.&lt;/li&gt; 
 &lt;li&gt;pg 103: A startup needs kamikazes who work long hours, implementers who turn their work into infrastructure, and operators who upkeep the infrastructure.&lt;/li&gt; 
 &lt;li&gt;pg 106: Ignore functional weaknesses; be attracted to candidates with major strengths than those who lack major weaknesses.&lt;/li&gt; 
 &lt;li&gt;pg 107: Ask the candidate who all his important decision makers are, and then work with the candidate to answer their concerns too.&lt;/li&gt; 
 &lt;li&gt;pg 111: Check references early; checking after the interview will lead you to only hear comments that affirm your decision.&lt;/li&gt; 
 &lt;li&gt;pg 113: Establish an initial review period where after 90 days you go over what&apos;s going right, what&apos;s going wrong, and how to improve performance.&lt;/li&gt; 
 &lt;li&gt;pg 114: Reference checking is not to disqualify a candidate, but to look for consistency in how he represented himself.&lt;/li&gt; 
 &lt;li&gt;pg 116: Don&apos;t recruit to make an investory happy; instead, recruit to build a great organization.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Chapter 7: The Art of Raising Capital&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;pg 121: Current investors, other entrepreneurs, and professors can serve as a credible third party to get you an introduction.&lt;/li&gt; 
 &lt;li&gt;pg 124: Your company is flawed if you have friends or roomates in CXO positions, or former employees claiming your technology belongs to them.&lt;/li&gt; 
 &lt;li&gt;pg 126: Openly acknowledge your competitors and evaluate your strengths and weaknesses; if needed, zoom out until you have competitors.&lt;/li&gt; 
 &lt;li&gt;pg 128: Don&apos;t tell investors about deals that will be signed to bring in revenue. Only talk about deals after they&apos;re done.&lt;/li&gt; 
 &lt;li&gt;pg 129: Investors all know one another, so don&apos;t try to play them against one another.&lt;/li&gt; 
 &lt;li&gt;pg 130: The optimal number of times to mention your technology is patentable is one; zero is bad because then you have nothing proprietary.&lt;/li&gt; 
 &lt;li&gt;pg 134: Courting one investor will make it easier to court others.&lt;/li&gt; 
 &lt;li&gt;pg 134: To help court an investor, check-in with them afterward and show improvement and progress after they don&apos;t commit, but don&apos;t nag.&lt;/li&gt; 
 &lt;li&gt;pg 135: When you take outside money, you&apos;re obligated to all shareholders even if they own a minority position.&lt;/li&gt; 
 &lt;li&gt;pg 138: You need people with two kinds of experience on your board: company-building and deep market knowledge.&lt;/li&gt; 
 &lt;li&gt;pg 139: Send reports to your board two days before a meeting, so you spend little time communicating the facts and more time trying to improve upon them.&lt;/li&gt; 
 &lt;li&gt;pg 140: When you have bad news or need to make a key decision, meet privately with each board member in advance.&lt;/li&gt; 
 &lt;li&gt;pg 143: A law firm recognized for its finance/VC work shows what you&apos;re doing, and will assist with the paperwork of a financing.&lt;/li&gt; 
 &lt;li&gt;pg 144: More investors means more people helping you, multiple sources of capital, and can give you allies if you disagree with one investor.&lt;/li&gt; 
 &lt;li&gt;pg 146: When a VC offers a valuation, ask for a 25 percent higher valuation because you&apos;re expected to push back.&lt;/li&gt; 
 &lt;li&gt;pg 147: Freely circulate your executive summary and PowerPoint pitch; only ask for an NDA if an investor wants to learn more at the bits-and-bytes level.&lt;/li&gt; 
 &lt;li&gt;pg 148: Don&apos;t be intimidated by your board of directors; instead, give them assignments and hold them accountable.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Chapter 8: The Art of Partnering&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;pg 152: Never form a partnership to make the press happy or silence critics; do it only to increase revenue.&lt;/li&gt; 
 &lt;li&gt;pg 153: When you form a partnership, always define deliverables and objectives.&lt;/li&gt; 
 &lt;li&gt;pg 155: A partnership requires an internal champion at each company who is empowered and whose sole goal is to make the partnership a success.&lt;/li&gt; 
 &lt;li&gt;pg 156: Form partnerships that accentuate the strengths of each partner, rather than covering their weaknesses.&lt;/li&gt; 
 &lt;li&gt;pg 158: Never use a legal document as a straw man to get the discussion rolling; discuss on the whiteboard, define a framework, then draft a document.&lt;/li&gt; 
 &lt;li&gt;pg 159: Add an &quot;out&quot; clause within some defined number of days to ensure both parties won&apos;t be trapped in an untenable predicament.&lt;/li&gt; 
 &lt;li&gt;pg 161: When schmoozing, ask questions and then shut up; follow up quickly while making it easy to get in touch; give favors, return them, and ask for the return of favors.&lt;/li&gt; 
 &lt;li&gt;pg 165: Ensure your emails have a signature, containing your name, organization, postal address, phone and fax numbers, and e-mail and web addresses.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Chapter 9: The Art of Branding&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;pg 171: Design a product that delivers basic functionality without requiring the user to refer to an instruction manual. Test it on your parents.&lt;/li&gt; 
 &lt;li&gt;pg 172: Make it easy to switch from competitors to your product, but also make it easy to switch away; making it difficult will scare potential customers away.&lt;/li&gt; 
 &lt;li&gt;pg 174: From your customers, recruit evangelists. Assign tasks, keep communication open, give them the required tools, respond to their desires, and reward them.&lt;/li&gt; 
 &lt;li&gt;pg 178: Per dollar, building a community is the cheapest way to create and maintain a brand, so don&apos;t wait for a community to form on its own.&lt;/li&gt; 
 &lt;li&gt;pg 178: To achieve humanness, try to target the young, make fun of yourself, and feature your customers. Don&apos;t be impersonal.&lt;/li&gt; 
 &lt;li&gt;pg 180: Press coverage doesn&apos;t convert readers to customers; instead, lower the barrier to entry, get customers, and then the press will write.&lt;/li&gt; 
 &lt;li&gt;pg 181: No matter what the weather, maintain good relations and contact with the press. You establish your credibility when times are bad, so don&apos;t lie.&lt;/li&gt; 
 &lt;li&gt;pg 185: If given the opportunity to give a speech, cut the sales propaganda, don&apos;t denigrate the competition, and just say something interesting.&lt;/li&gt; 
 &lt;li&gt;pg 186: When on a panel, be entertaining, never look bored, and don&apos;t look at the moderator but the audience instead.&lt;/li&gt; 
 &lt;li&gt;pg 189: You might insult an evangelist by trying to pay them; instead, make your product better, offer them information, and honor them publicly.&lt;/li&gt; 
 &lt;li&gt;pg 190: If you want to change your logo, look and feel, mantra, or tag line, consider that it may only be now that they&apos;re entering the public&apos;s mind.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Chapter 10: The Art of Rainmaking&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;pg 193: If your product succeeds in an unexpected market, find out why and adjust your business accordingly.&lt;/li&gt; 
 &lt;li&gt;pg 197: Ignore titles and find the true influencers in the middle and bottom of companies.&lt;/li&gt; 
 &lt;li&gt;pg 198: When you’ve found those to “suck down” to, don’t try to buy them, empathize with them, and never go over their head and complain about them.&lt;/li&gt; 
 &lt;li&gt;pg 200: Enable someone to do something they simply could not do before, as opposed to having to displace an entrenched product or service.&lt;/li&gt; 
 &lt;li&gt;pg 201: If your product doesn’t resonate with a sales prospect, ask why they won’t buy your product and take good notes.&lt;/li&gt; 
 &lt;li&gt;pg 203: Offer a smooth, gentle adoption curve; if your product or service really is great, this will help with the hardest step of getting in the door.&lt;/li&gt; 
 &lt;li&gt;pg 205: Don’t rely on the sales types to do all the work for you; encourage everyone to make it rain.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Chapter 11: The Art of Being a Mensch&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;pg 211: The three foundations of menschhood are helping lots of people, doing what’s right, and paying back society.&lt;/li&gt; 
 &lt;li&gt;pg 213: A mensch does the right thing, not the easy thing, the expedient thing, or the money-saving thing.&lt;/li&gt; 
 &lt;li&gt;pg 214: A mensch pays back for goodness already received, as opposed to paying it forward.&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Job search links and articles</title>
      <link>https://tedneward.github.io/Research/reading/business/job-search/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">reading/business/job-search/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://blog.nindalf.com/posts/tech-interview/&quot;&gt;&quot;Lessons From a Tech Job Search&quot;&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Business metrics</title>
      <link>https://tedneward.github.io/Research/reading/business/metrics/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">reading/business/metrics/index.html</guid>
      	<description>
	&lt;p&gt;Types of startup metrics (&lt;a href=&quot;https://media.licdn.com/dms/image/C4E22AQEoJLGjQkZDng/feedshare-shrink_2048_1536/0/1672738383273?e=1675900800&amp;amp;v=beta&amp;amp;t=6eA_lYLH1lIxZbhiBNlJh4fWfAfDN8tuWtSucmeh3_k&quot;&gt;Source&lt;/a&gt; from &lt;a href=&quot;https://www.linkedin.com/feed/update/urn:li:activity:7015973294453465088&quot;&gt;LinkedIN Alan Fecamp&lt;/a&gt;):&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Monthly Recurring Revenue (MRR), Annual Recurring Revenue (ARR): monthly or annual total of paid customer fees&lt;/li&gt; 
 &lt;li&gt;Average Revenue Per Account (ARPA): Per Account MRR/Total # of Customers&lt;/li&gt; 
 &lt;li&gt;Gross Profit: Total revenue minus cost of goods sold&lt;/li&gt; 
 &lt;li&gt;Total Contract Value (TCV): value of one-time and recurring charges&lt;/li&gt; 
 &lt;li&gt;Annual Contract Value (ACV): value of a contract over a year&lt;/li&gt; 
 &lt;li&gt;Lifetime Value (LTV): prediction of the net profit from the entire future relationship with a customer&lt;/li&gt; 
 &lt;li&gt;Deferred Revenue: amount that was received by a company in advance of earning it&lt;/li&gt; 
 &lt;li&gt;Billings: current quarter revenue + deferred revenue from previous quarter&lt;/li&gt; 
 &lt;li&gt;Customer Acquisition Cost (CAC): full cost of acquiring one user&lt;/li&gt; 
 &lt;li&gt;Concentration Risk: revenue from largest customer/total revenue&lt;/li&gt; 
 &lt;li&gt;Daily Active Users (DAU), Monthly Active Users: Users other than one-time users per day.month&lt;/li&gt; 
 &lt;li&gt;Number of logins: sign-ins per month&lt;/li&gt; 
 &lt;li&gt;Activation rate: nubmer of users taking a specific action to get value out of a product&lt;/li&gt; 
 &lt;li&gt;MoM Growth Rate: month-on-month growth: average of monthly growth rates&lt;/li&gt; 
 &lt;li&gt;Compounded Monthly Growth Rate (CMGR): (Latest Month/First Month) (1 / # of Months) - 1&lt;/li&gt; 
 &lt;li&gt;Monthly Churn Rate: lost customers this month / prior month total&lt;/li&gt; 
 &lt;li&gt;Retention Rate: % of original installed base (1st month) that are still transacting&lt;/li&gt; 
 &lt;li&gt;Gross Churn Rate: MRR lost in a given month / MRR at the beginning of the month&lt;/li&gt; 
 &lt;li&gt;Net Churn: (MRR lost - MRR from upsells) this month / MRR at the beginning of the month&lt;/li&gt; 
 &lt;li&gt;Burn Rate: Monthly cash burn rate&lt;/li&gt; 
 &lt;li&gt;Total Addressable Market (TAM): revenue opportunity for a product&lt;/li&gt; 
 &lt;li&gt;MRR Projection: projection of the current MRR into the future, annualized&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Rework</title>
      <link>https://tedneward.github.io/Research/reading/business/rework/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">reading/business/rework/index.html</guid>
      	<description>
	&lt;p&gt;&lt;em&gt;(by Jason Fried and David Heinemeier Hansson)&lt;/em&gt;&lt;/p&gt; 
&lt;p&gt;&lt;em&gt;I, &lt;a href=&quot;http://omgitsmgp.com/&quot;&gt;Michael Parker&lt;/a&gt;, own this book and took these notes to further my own learning. If you enjoy these notes, please &lt;a href=&quot;http://www.amazon.com/Rework-Jason-Fried/dp/0307463745&quot;&gt;purchase the book&lt;/a&gt;!&lt;/em&gt;&lt;/p&gt; 
&lt;h3&gt;Takedowns&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;pg 19: Make decisions right before you do something, not far in advance; long term plans are just guesses.&lt;/li&gt; 
 &lt;li&gt;pg 23: It&apos;s okay to stay small; once big, it&apos;s hard to shrink without firing people and damaging morale.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Go&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;pg 35: Build what you need, so you&apos;ll know the right answers, assess its quality directly, and love your work.&lt;/li&gt; 
 &lt;li&gt;pg 43: Have a point of view and strong opinions; otherwise everything is debatable, and decisions are hard.&lt;/li&gt; 
 &lt;li&gt;pg 50: Taking outside money relinquishes control to VCs, deprioritizes customers, and is distracting.&lt;/li&gt; 
 &lt;li&gt;pg 56: A business without a path to profit isn&apos;t a business, it&apos;s a hobby.&lt;/li&gt; 
 &lt;li&gt;pg 62: Avoid mass, like excess staff, long-term contracts, lock-ins, road maps, etc. to stay lean and agile.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Progress&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;pg 72: Prioritize working on the most important part of your business so it&apos;s the best it can be; defer the rest.&lt;/li&gt; 
 &lt;li&gt;pg 77: Make decisions, don&apos;t wait for the perfect solution; decisions build momentum and boost morale.&lt;/li&gt; 
 &lt;li&gt;pg 90: When you make something, you always make something else; sell those byproducts.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Productivity&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;pg 102: Don&apos;t throw good time after bad work; ensure that what you&apos;re working on matters.&lt;/li&gt; 
 &lt;li&gt;pg 108: Meeting suck: they convey little information, drift off-subject, require preparation, and procreate.&lt;/li&gt; 
 &lt;li&gt;pg 115: Momentum fuels motivation; build it through constant small victories that generate enthusiasm.&lt;/li&gt; 
 &lt;li&gt;pg 121: Don&apos;t forego sleep: you&apos;ll be stubborn, uncreative, inefficient, irritable, and lose motivation.&lt;/li&gt; 
 &lt;li&gt;pg 127: You&apos;ll feel guilty over long lists, then stress out; divide and conquer into small, manageable lists.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Competitors&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;pg 136: If you&apos;re a copycat, you&apos;re in a passive position where you&apos;re always behind the times.&lt;/li&gt; 
 &lt;li&gt;pg 141: If a competitor sucks, pick a fight; you&apos;ll stand out, earn followers, and ignite passions of users.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Evolution&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;pg 153: Get into the habit of saying no; saying yes is easy, but you often wind up regretting it.&lt;/li&gt; 
 &lt;li&gt;pg 157: Let customers outgrow you; focus on features that attract new customers, not please old ones.&lt;/li&gt; 
 &lt;li&gt;pg 164: Feature requests that matter you&apos;ll hear over and over, so no need to write them down.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Promotion&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;pg 174: Teach your customers; even if people don&apos;t use your product, they&apos;ll still be your fans.&lt;/li&gt; 
 &lt;li&gt;pg 188: Niche bloggers are hungry for finding the new thing; stories that start there can go mainstream.&lt;/li&gt; 
 &lt;li&gt;pg 191: Give away something for free; if your product is strong enough, people will come back for more.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Hiring&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;pg 201: Don&apos;t hire anyone until you&apos;ve tried the job yourself; then you&apos;ll know what and who to look for.&lt;/li&gt; 
 &lt;li&gt;pg 206: Hiring more people than needed leads to invented projects, which adds cost and complexity.&lt;/li&gt; 
 &lt;li&gt;pg 210: A cover letter lets you hear someone&apos;s actual voice; you can tell if it&apos;s in tune with your company.&lt;/li&gt; 
 &lt;li&gt;pg 222: Great writers are great candidates, for clear writing is clear thinking.&lt;/li&gt; 
 &lt;li&gt;pg 227: Hire potential employees for a mini-project; in a real work environment, the truth comes out.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Damage Control&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;pg 235: Responding to customers quickly with a personal response is the best customer service.&lt;/li&gt; 
 &lt;li&gt;pg 238: A good apology accepts responsibility, provides details of the problem, and a solution.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Culture&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;pg 251: Don&apos;t make up problems you don&apos;t have yet; decisions don&apos;t lost forever anyway.&lt;/li&gt; 
 &lt;li&gt;pg 262: Don&apos;t sound big and formal; communicate simply and directly, without legal or PR oversight.&lt;/li&gt; 
 &lt;li&gt;pg 268: Saying ASAP devalues any request without it; use emergency language when really needed.&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>&quot;Auctions and bidding: A guide for computer scientists&quot;</title>
      <link>https://tedneward.github.io/Research/reading/business/auctions/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">reading/business/auctions/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;http://www.sci.brooklyn.cuny.edu/~parsons/projects/mech-design/publications/bluffers-final.pdf&quot;&gt;Paper&lt;/a&gt; | &lt;a href=&quot;https://speakerdeck.com/paperswelove/daniel-doubrovkine-on-auctions-and-bidding-a-guide-for-computer-scientists&quot;&gt;Slides&lt;/a&gt; | &lt;a href=&quot;https://www.youtube.com/watch?v=v502KYHa3aE&quot;&gt;Talk video&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Reading on software licensing</title>
      <link>https://tedneward.github.io/Research/reading/business/licensing/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">reading/business/licensing/index.html</guid>
      	<description>
	&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.aliprandi.org/cc-user-guide/&quot;&gt;Creative Commons: a user guide&lt;/a&gt; - Simone Aliprandi&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://rosenlaw.com/oslbook/&quot;&gt;Open Source Licensing Software Freedom and Intellectual Property Law&lt;/a&gt; - Lawrence Rosen&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.thepublicdomain.org/download/&quot;&gt;The Public Domain: Enclosing the Commons of the Mind&lt;/a&gt; - James Boyle&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Negotiation reading</title>
      <link>https://tedneward.github.io/Research/reading/business/negotiation/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">reading/business/negotiation/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://haseebq.com/my-ten-rules-for-negotiating-a-job-offer/&quot;&gt;&quot;My 10 Rules for Negotiation a Job Offer&quot;&lt;/a&gt; and &lt;a href=&quot;https://haseebq.com/how-not-to-bomb-your-offer-negotiation/&quot;&gt;Part 2&lt;/a&gt;: &quot;The rules, in order of appearance, are:&lt;br&gt; 1. Get everything in writing&lt;br&gt; 1. Always keep the door open&lt;br&gt; 1. Information is power&lt;br&gt; 1. Always be positive&lt;br&gt; 1. Don’t be the decision maker&lt;br&gt; 1. Have alternatives&lt;br&gt; 1. Proclaim reasons for everything&lt;br&gt; 1. Be motivated by more than just money&lt;br&gt; 1. Understand what they value&lt;br&gt; 1. Be winnable&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>To Sell Is Human</title>
      <link>https://tedneward.github.io/Research/reading/business/to-sell-is-human/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">reading/business/to-sell-is-human/index.html</guid>
      	<description>
	&lt;p&gt;&lt;em&gt;(by Daniel Pink)&lt;/em&gt;&lt;/p&gt; 
&lt;h3&gt;Introduction&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;The ability to move others to exchange what they have for what we have is crucial to our survival and our happiness.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Part 1: Rebirth of a Salesman&lt;/h3&gt; 
&lt;h4&gt;Ch 1: We&apos;re All in Sales Now&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;One out of every nine American workers works in sales, and by 2020 the Bureau of Labor Statistics expects 2 million new sales jobs.&lt;/li&gt; 
 &lt;li&gt;The same holds elsewhere around the world, even after the global financial implosion and the Internet.&lt;/li&gt; 
 &lt;li&gt;Beyond producing and consuming, we now focus on moving other people to part with their resources so that we both get what we want.&lt;/li&gt; 
 &lt;li&gt;People now spend 40% of their time at work engaged in non-sales selling, and they consider this aspect crucial to their professional success.&lt;/li&gt; 
 &lt;li&gt;The older someone is, and so the more experience that person has, the more moving others occupies her days and determines her success.&lt;/li&gt; 
 &lt;li&gt;The existing data shows that 1 in 9 Americans work in sales; but the other 8 in 9 engage in non-sales selling.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Ch 2: Entrepreneurship, Elasticity, and Ed-Med&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;Very large enterprises and very small ones not only have differences in degree, but differences in kind.&lt;/li&gt; 
 &lt;li&gt;Entrepreneurs cannot specialize, they must wear many hats; and that is the first reason why more of us find ourselves in sales.&lt;/li&gt; 
 &lt;li&gt;30% of American workers now work on their own; this may grow by 65 million and become the majority of the US workforce in 2020.&lt;/li&gt; 
 &lt;li&gt;Technology was supposed to make salespeople obsolete but transformed more people into sellers -- see Etsy, Square, Kickstarter, etc.&lt;/li&gt; 
 &lt;li&gt;Elasticity, or the new breadth of skills demanded by established companies, is the second reason why we&apos;re all in sales now.&lt;/li&gt; 
 &lt;li&gt;A world of flat organizations and tumultuous business conditions punishes fixed skills and prizes elastic ones.&lt;/li&gt; 
 &lt;li&gt;As elasticity of skills becomes more common, one particular category of skill it seems always to encompass is moving others.&lt;/li&gt; 
 &lt;li&gt;Education and health services, or Ed-Med, is the largest job sector in the U.S. economy, and the fastest growing sector in the world.&lt;/li&gt; 
 &lt;li&gt;Teachers and health care professionals sell and convince others to part with time, attention, and effort, for a better future.&lt;/li&gt; 
 &lt;li&gt;Irritation is challenging people to do something you want to do; agitation is challenging them to do something they want to do.&lt;/li&gt; 
 &lt;li&gt;Non-sales selling requires influencing, persuading, and changing behavior while balancing what others want and what you can provide them.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Ch 3: From Caveat Emptor to Caveat Venditor&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;Adjectives and interjections can reveal people&apos;s attitudes, since they often contain an emotional component that nouns lack.&lt;/li&gt; 
 &lt;li&gt;Selling makes us uncomfortable and disgusted because we believe its practice revolves around duplicity, dissembling, and double-dealing.&lt;/li&gt; 
 &lt;li&gt;The presence of people who wish to pawn bad wares as good wares tends to drive out the legitimate business.&lt;/li&gt; 
 &lt;li&gt;In a world of information asymmetry, the guiding principle is caveat emptor, or buyer beware.&lt;/li&gt; 
 &lt;li&gt;If you have just as much information as the seller, and a means to talk back, the new guiding principle is caveat venditor, or seller beware.&lt;/li&gt; 
 &lt;li&gt;When buyers can know more than sellers, the sellers are not the protectors and purveyors of information, but the curators and clarifiers of it.&lt;/li&gt; 
 &lt;li&gt;Our feelings about sales derive not from the inherent nature of selling, but the information asymmetry that long defined its context.&lt;/li&gt; 
 &lt;li&gt;But as long as there are complicated products where the potential for lucre is enormous, abide by caveat emptor.&lt;/li&gt; 
 &lt;li&gt;The low road is now harder to pass and the high road has become the better, more pragmatic, long-term route.&lt;/li&gt; 
 &lt;li&gt;There are no &quot;natural&quot; salespeople, in part because we&apos;re all naturally salespeople with a selling instinct.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Part 2: How to Be&lt;/h3&gt; 
&lt;h4&gt;Ch 4: Attunement&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;Attunement is the ability to bring one&apos;s actions and outlook into harmony with other people and with the context you&apos;re in.&lt;/li&gt; 
 &lt;li&gt;Power leads individuals to anchor too heavily on their own vantage point, insufficiently adjusting to others&apos; perspective.&lt;/li&gt; 
 &lt;li&gt;Start your encounters assuming that you have less power; this will help you see other side&apos;s perspective, and in turn move them.&lt;/li&gt; 
 &lt;li&gt;Perspective-taking is a cognitive capacity, mostly about thinking; empathy is an emotional response, mostly about feeling.&lt;/li&gt; 
 &lt;li&gt;Perspective-taking is better than empathy, because you can submerge your own interests.&lt;/li&gt; 
 &lt;li&gt;People belong to groups, situations, and contexts, so pay attention to the relationships and connections of a person.&lt;/li&gt; 
 &lt;li&gt;Syncing our mannerisms and vocal patterns to someone else so that we both understand and can be understood is fundamental to attunement.&lt;/li&gt; 
 &lt;li&gt;Related to mimicry, touching someone on the upper arm or shoulder has positive results.&lt;/li&gt; 
 &lt;li&gt;The correlation between extraversion and sales in one study was only 0.07, or virtually non-existent.&lt;/li&gt; 
 &lt;li&gt;Extraverts can talk too much and listen too little, and fail to balance between asserting and holding back.&lt;/li&gt; 
 &lt;li&gt;Intraverts can be too shy to initiate and too timid to close.&lt;/li&gt; 
 &lt;li&gt;Ambiverts are the best movers because they&apos;re the most skilled attuners, knowing when to speak up and when to shut up.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;&lt;em&gt;Sample Case&lt;/em&gt;&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Jim Collins&apos; favorite opening question is &quot;Where are you from?&quot; because it opens someone up easily.&lt;/li&gt; 
 &lt;li&gt;To master strategic mimicry: watch, then wait before applying, and finally wane, or become less conscious of what you&apos;re doing.&lt;/li&gt; 
 &lt;li&gt;Jeff Bezos uses an empty chair in meetings to represent the customer; let the chair represent whom you must be attuned to.&lt;/li&gt; 
 &lt;li&gt;A discussion map of a meeting has an X next to someone&apos;s name when they talk, and has arrows for directed comments.&lt;/li&gt; 
 &lt;li&gt;Finding similarities can help you attune yourself to others and help them attune themselves to you.&lt;/li&gt; 
 &lt;li&gt;Similarity is a key form of human connection, as people are more likely to move together when they share common ground.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Ch 5: Buoyancy&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;How to stay afloat in the ocean of rejection, or buoyancy, is the second essential quality in moving others.&lt;/li&gt; 
 &lt;li&gt;Positive self-talk is better than negative self-talk, but most effective is to ask questions instead of make statements.&lt;/li&gt; 
 &lt;li&gt;The interrogative elicits answers, in which are strategies for actually carrying out the task.&lt;/li&gt; 
 &lt;li&gt;Moreover, interrogative self-talk inspires thoughts about autonomous and intrinsically motivated reasons to pursue a goal.&lt;/li&gt; 
 &lt;li&gt;Negative emotions narrow our vision and help us survive in the moment, namely fight or flight.&lt;/li&gt; 
 &lt;li&gt;Positive emotions broaden our ideas about actions, opening us to a wider range of thoughts, making us more receptive and creative.&lt;/li&gt; 
 &lt;li&gt;Believing in an offering leads to a deeper understanding of it, allowing sellers to better match what they have with what others need.&lt;/li&gt; 
 &lt;li&gt;A ratio of positive to negative emotions between 3:1 and 11:1 is ideal.&lt;/li&gt; 
 &lt;li&gt;Negative emotions offer us feedback on our performance, information on what&apos;s not working, and hints on how to do better.&lt;/li&gt; 
 &lt;li&gt;Unchecked levity makes you flighty, ungrounded, and unreal, while unchecked gravity leaves you in a heap of misery.&lt;/li&gt; 
 &lt;li&gt;Learned helplessness is a habit of people explaining negative events to themselves as permanent, pervasive, or personal.&lt;/li&gt; 
 &lt;li&gt;They believe that the negative conditions will last a long time, the causes are universal, and that they&apos;re the ones to blame.&lt;/li&gt; 
 &lt;li&gt;Optimism can stir persistence, steady us during challenges, and stoke the confidence that we can influence our surroundings.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;&lt;em&gt;Sample Case&lt;/em&gt;&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Next time you&apos;re getting ready to persuade others, ask yourself &quot;Can I move these people?&quot; Answer it, directly and in writing.&lt;/li&gt; 
 &lt;li&gt;Be more positive by displaying positive emotions of joy, gratitude, serenity, interest, hope, pride, amusement, inspiration, awe, and love.&lt;/li&gt; 
 &lt;li&gt;Explain bad events as temporary, specific, and external, and find ways to &quot;dispute&quot; and &quot;de-catastrophize&quot; negative explanations.&lt;/li&gt; 
 &lt;li&gt;Thinking through the gloom-and-doom scenarios and mentally preparing for the very worst can help some people manage their anxieties.&lt;/li&gt; 
 &lt;li&gt;Writing yourself a fake rejection letter can make consequences seem less dire, and even reveal soft spots in what you&apos;re presenting.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Ch 6: Clarity&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;Partly because our brains evolved when the future itself was perilous, we are bad at wrapping our minds around far-off events.&lt;/li&gt; 
 &lt;li&gt;Clarity is the capacity to help others see their problems in fresh and revealing ways, and to identify problems they didn&apos;t realize they had.&lt;/li&gt; 
 &lt;li&gt;The ability to move others hinges on problem finding, not solving, when one&apos;s mistaken, confused, or clueless about the true problem.&lt;/li&gt; 
 &lt;li&gt;People most disposed to creative breakthroughs tend to be problem finders, and not just problem solvers.&lt;/li&gt; 
 &lt;li&gt;Non-sales selling depends more on the problem-finding because information symmetry enables us to problem solve.&lt;/li&gt; 
 &lt;li&gt;We must now be adept at curating data, not accessing it; we must also be adept at asking questions, not answering questions.&lt;/li&gt; 
 &lt;li&gt;The contrast principle says we understand something when compared to something else than when we see it in isolation.&lt;/li&gt; 
 &lt;li&gt;The less frame: Restricting people&apos;s choices can help them see those choices more clearly instead of overwhelming them.&lt;/li&gt; 
 &lt;li&gt;The experience frame: Frame a sale as a purchase of an experience, which is more satisfying than the sale of a good.&lt;/li&gt; 
 &lt;li&gt;The label frame: Simply changing the label of an activity can favorably alter behavior.&lt;/li&gt; 
 &lt;li&gt;The blemished frame: Adding a minor negative detail in an otherwise positive description can give that description more impact.&lt;/li&gt; 
 &lt;li&gt;The blemishing effect only works if the subject is in a &quot;low effort&quot; state, and if the negative information comes last.&lt;/li&gt; 
 &lt;li&gt;The potential frame: Highlighting one&apos;s potential, not achievements, causes deeper thought into why that person is a good choice.&lt;/li&gt; 
 &lt;li&gt;Clarity on how to think without clarity on how to act can leave people unmoved, so provide a clear path of action.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;&lt;em&gt;Sample Case&lt;/em&gt;&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Irrational questions work better than rational questions when trying to motivate resistant people.&lt;/li&gt; 
 &lt;li&gt;To become an efficient curator, first seek, or gather information; then sense, or create meaning out if it; and finally share.&lt;/li&gt; 
 &lt;li&gt;To ask better questions, write down as many as you can, classify them as open-ended or closed-ended, and choose the best three.&lt;/li&gt; 
 &lt;li&gt;The Five Whys technique forces us to examine and express the underlying reasons for our behaviors and attitudes.&lt;/li&gt; 
 &lt;li&gt;Always focus on the &quot;one percent,&quot; or the essence of what you&apos;re exploring, that gives life to the other ninety-nine.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Part 3: What To Do&lt;/h3&gt; 
&lt;h4&gt;Ch 7: Pitch&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;Pitching is the ability to distill one&apos;s point to its persuasive essence.&lt;/li&gt; 
 &lt;li&gt;A pitch isn&apos;t to move others to immediately adopt your idea, but to begin a conversation, collaborate, and arrive at a mutually beneficial outcome.&lt;/li&gt; 
 &lt;li&gt;The elevator pitch is a bit threadbare, because organizations today are more democratic and because CEOs have more distractions.&lt;/li&gt; 
 &lt;li&gt;A one-word pitch reduces a point to a single word, and helps you be heard when attention spans are nearly disappearing.&lt;/li&gt; 
 &lt;li&gt;The question pitch asks a question, which compels people to respond and is more effective than statements unless the backing arguments are weak.&lt;/li&gt; 
 &lt;li&gt;The rhyming pitch relies on rhymes increasing &quot;processing fluency,&quot; and we equate this ease of processing with accuracy.&lt;/li&gt; 
 &lt;li&gt;The subject-line pitch relies on utility when one is busy and curiosity when one is bored, but not both; as well as specificity.&lt;/li&gt; 
 &lt;li&gt;The Twitter pitch values short pitches that ask questions, convey information with links, and to self-promotion.&lt;/li&gt; 
 &lt;li&gt;The Pixar pitch follows the structure &quot;One upon a time ___. Every day, ___. One day, ___. Because of that, ___. Because of that, ___. Until finally, ___.&quot;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;&lt;em&gt;Sample Case&lt;/em&gt;&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Ensure that after hearing your pitch, you can answer what someone should know, someone should feel, and someone should do.&lt;/li&gt; 
 &lt;li&gt;You can enliven question pitches, one-word pitches, rhyming pitches, and Twitter pitches with visuals.&lt;/li&gt; 
 &lt;li&gt;A pecha-kucha presentation contains exactly twenty slides, each of which appears on the screen for exactly twenty seconds.&lt;/li&gt; 
 &lt;li&gt;When pitching, go first if you&apos;re the incumbent and last if you&apos;re the challenger; avoid the middle.&lt;/li&gt; 
 &lt;li&gt;In a pitch, granular numbers are more credible than coarse ones.&lt;/li&gt; 
 &lt;li&gt;Ask people to describe in three words what your organization, your product, and you are about, and then look for patterns.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Ch 8: Improvise&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;Sales scripts perform nicely in an environment where buyers have minimal choices and sellers have maximal information.&lt;/li&gt; 
 &lt;li&gt;The stable, simple, and certain conditions that favored scripts have given way to the dynamic, complex, and unpredictable conditions that favor improvisation.&lt;/li&gt; 
 &lt;li&gt;To move others, follow the three essential rules of improv: hear others, say &quot;Yes and,&quot; and make your partner look good.&lt;/li&gt; 
 &lt;li&gt;Listening without some degree of intimacy isn&apos;t really listening; it&apos;s passive and transactional, not active and engaged.&lt;/li&gt; 
 &lt;li&gt;Don&apos;t listen &lt;em&gt;for&lt;/em&gt; anything; instead, take in anything and everything someone says as an offer you can do something with.&lt;/li&gt; 
 &lt;li&gt;While &quot;Yes, but&quot; spirals down into frustration, &quot;Yes, and&quot; spirals up toward positivity.&lt;/li&gt; 
 &lt;li&gt;Under conditions of information asymmetry, results are often win-lose; but with information parity, we cannot push for win-lose.&lt;/li&gt; 
 &lt;li&gt;Making your partner look good calls for, and enables, clarity, the capacity to develop solutions that nobody previously imagined.&lt;/li&gt; 
 &lt;li&gt;Ask questions, because when both sides view an encounter as an opportunity to learn, the desire to defeat the other side wanes.&lt;/li&gt; 
 &lt;li&gt;Never argue, for to win an argument is to lose a sale.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;&lt;em&gt;Sample Case&lt;/em&gt;&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;If your conversation partner isn&apos;t finishing his sentence, or can&apos;t speak without you interrupting, then you need to slow down.&lt;/li&gt; 
 &lt;li&gt;Ask questions, but don&apos;t ask yes-no questions, don&apos;t ask questions that are veiled opinions.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Ch 9: Serve&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;For service to cause people to achieve something greater and more enduring than an exchange of resources, make it personal and purposeful.&lt;/li&gt; 
 &lt;li&gt;In circumstances in which we move others, we not adopt a stance that is abstract and distant, but concrete and personal.&lt;/li&gt; 
 &lt;li&gt;This lets you recognize the person you&apos;re trying to serve, and also puts you personally behind whatever you&apos;re trying to sell.&lt;/li&gt; 
 &lt;li&gt;Many of us like to say &quot;I&apos;m accountable,&quot; but few of us are so deeply committed to serving other that we&apos;ll say, &quot;Call my cell.&quot;&lt;/li&gt; 
 &lt;li&gt;We assume everyone is driven by self-interest, but we all do things for &quot;prosocial&quot; or &quot;self-transcending&quot; reasons.&lt;/li&gt; 
 &lt;li&gt;We should also be tapping others&apos; innate desire to serve by making it purposeful, not just personal.&lt;/li&gt; 
 &lt;li&gt;A servant-leader begins with the natural feeling that one wants to serve; then conscious choice brings one to aspire to lead.&lt;/li&gt; 
 &lt;li&gt;The best test of this philosophy is whether those who are served grow as persons, and in turn more likely themselves to become servants.&lt;/li&gt; 
 &lt;li&gt;Servant selling asks if the person you&apos;re selling to agrees to buy, will his or her life, and the state of the world, improve?&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;&lt;em&gt;Sample Case&lt;/em&gt;&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Upserving means doing more than the other person expects or you initially intended, transforming a mundane interaction into a memorable experience.&lt;/li&gt; 
 &lt;li&gt;Really good salespeople want to solve problems and serve customers, becoming part of something larger than themselves.&lt;/li&gt; 
 &lt;li&gt;Emotionally intelligent signage either expresses empathy with the person viewing it, or tries to trigger empathy in that person.&lt;/li&gt; 
 &lt;li&gt;To make an encounter personal and encourage you to genuinely serve, imagine that the person you&apos;re dealing with is you grandmother.&lt;/li&gt; 
 &lt;li&gt;If the buyer isn&apos;t improving her life, or the world isn&apos;t a better place after the interaction, you&apos;re doing something wrong.&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Competing on Analytics</title>
      <link>https://tedneward.github.io/Research/reading/business/competing-on-analytics/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">reading/business/competing-on-analytics/index.html</guid>
      	<description>
	&lt;p&gt;&lt;em&gt;(by Thomas H Davenport, from &quot;HBR&apos;s 10 Must Reads: The Essentials&quot;)&lt;/em&gt;&lt;/p&gt; 
&lt;p&gt;TBD&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Marketing Myopia</title>
      <link>https://tedneward.github.io/Research/reading/business/marketing-myopia/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">reading/business/marketing-myopia/index.html</guid>
      	<description>
	&lt;p&gt;&lt;em&gt;(by Theodore Levitt, from &quot;HBR&apos;s 10 Must Reads: The Essentials&quot;)&lt;/em&gt;&lt;/p&gt; 
&lt;p&gt;What business are you really in? A seemingly obvious question--but one we should all ask before demand for our competitors&apos; products or services dwindles.&lt;/p&gt; 
&lt;p&gt;The railorads failed to ask this same question--and stopped growing. Why? Not because people no longer needed transportation. And not because other innovations (cars, airplanes) filled transportation needs. Rather, railroads stopped growing because railroads didn&apos;t move to fill those needs. Their executives incorrectly thought that they were in the railroad business, not the transportation business. They viewed themselves as providing a product instead of serving customers. Too many other industries make the same mistake--putting themselves at risk of obsolescence.&lt;/p&gt; 
&lt;p&gt;How to ensure continued growth for your company? Concentrate on meeting customers&apos; needs rather thna selling products. Chemical powerhouse DuPont kept a close eye on its customers&apos; most pressing concerns--and deployed its technical know-how to create an ever-expanding array of products that appealed to customers and continuously enlarged its market. If DuPont had merely found more uses for its flagship innovation (nylon), it might not be around today.&lt;/p&gt; 
&lt;p&gt;We put our businesses at risk of obsolescence when we accept any of the following myths:&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Myth 1: An ever-expanding and more affluent population will ensure our growth.&lt;/strong&gt; When markets are expanding, we often assume we don&apos;t have to think imaginatively about our businesses. Instead, we seek to outdo rivals simply by improving on what we&apos;re already doing. The consequence: We incrase the efficiency of &lt;em&gt;making&lt;/em&gt; our products, rather than boosting the value those products deliver to customers.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Myth 2: There is no competitive substitute for our industry&apos;s major product.&lt;/strong&gt; Believing that our products have no rivals makes our companies vulnerable to dramatic innovations from outside our industries--often by smaller, newer companies that are focusing on customer needs rather than the products themselves.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Myth 3: We can protect ourselves through mass production.&lt;/strong&gt; Few of us can resist the prospect of the incresaed profits that come with steeply declining unit costs. But focusing on mass production emphasizes our &lt;em&gt;company&lt;/em&gt;&apos;s needs--when we should be emphasizing our &lt;em&gt;customers&lt;/em&gt;&apos;.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Myth 4: Technical research and development will ensure our growth.&lt;/strong&gt; When R&amp;amp;D produces breakthrough products, we may be tempted to organize our companies around the technology rather than the consumer. Instead, we should remain focused on satisfying customer needs.&lt;/p&gt; 
&lt;p&gt;(Examples: petroleum, automobiles, electronics industries.)&lt;/p&gt; 
&lt;p&gt;No organization can achieve greatness without a vigorous leader who is driven onward by a pulsating &lt;em&gt;will to succeed&lt;/em&gt;. A leader has to have a vision of grandeur, a vision that cna produce eager followers in vast numbers. In business, the followers are the customers.&lt;/p&gt; 
&lt;p&gt;In order to produce these customers, the entire corporation must be viewed as a customer-creating and customer-satisfying organism. Management must think of itself not as producing products but as providing customer-creating value satisfactions. It must push this idea (and everything it means and requires) into every nook and cranny of the organization. It has to do this continuously and with the kind of flair that excites and stimulates the people in it. Otherwise, the company will be merely a series of pigeonholed parts, with no consolidating sense of purpose or direction.&lt;/p&gt; 
&lt;p&gt;In short, the organization must learn to think of itself not as producing goods or services, but as &lt;em&gt;buying customers&lt;/em&gt;, as doing the things that will make people &lt;em&gt;want&lt;/em&gt; to do business with it. And the chief executive has the inescapable responsibility for creating this environment, this viewpoint, this attitude, this aspiration. The chief executive must set the company&apos;s style, its direction, and its goals. This means knowing precisely where he/she wants to go and making sure the whole organization is enthusiasically aware of where that is. This is a first requisite of leadership, for &lt;em&gt;unless a leader knows where he/she is going, any road will take him/her there.&lt;/em&gt; (And if any road is OK, the chief executive may as well go fishing--if the organization does not know or care where it is going, it does not need to advertise that fact with a ceremonial figurehead, for everybody will notice it soon enough.)&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Platform Revolution</title>
      <link>https://tedneward.github.io/Research/reading/business/platform-revolutions/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">reading/business/platform-revolutions/index.html</guid>
      	<description>
	&lt;p&gt;&lt;em&gt;(by Geoffrey G Parker, Marshall W Van Alstyne, and Sangeet Paul Choudary)&lt;/em&gt;&lt;/p&gt; 
&lt;h1&gt;1. Today&lt;/h1&gt; 
&lt;p&gt;&lt;em&gt;Welcome to the Platform Revolution&lt;/em&gt;&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Platform&lt;/em&gt;&lt;/strong&gt;: &quot;A business based on enabling value-creating interactions between external producers and consumers. Platform provides open, participative infrastructure for these interactions and sets governance conditions for them. Purpose: to consummate matches among users and facilitate the exchange of goods, services, or social currency, thereby enabling value creation for all participants.&quot;&lt;/p&gt; 
&lt;p&gt;Traditional system: pipeline/linear value chain (single-track, assembly line)&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Platforms beat pipelines because platforms scale more efficiently by eliminating gatekeepers.&lt;/em&gt;&lt;/strong&gt; Until recently, most business were built around products--designed/made at one end of the pipeline and delivered to consumers at the other end. Pipelines rely on inefficient gatekeepers to manage the flow of value from the producer to the consumer; the elimination of gatekeepers allow consumers greater freedom to select products that fit their needs.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Platforms beat pipelines because platforms unlock new sources of value creation and supply.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Platforms beat pipelines by using data-based tools to create community feedback loops.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Platforms invert the firm.&lt;/em&gt;&lt;/strong&gt; Strategy has moved from controlling the unique resources and erecting competitive barriers to orchestrating external resources and engaging vibrant communities.&lt;/p&gt; 
&lt;h1&gt;2. Network Effects&lt;/h1&gt; 
&lt;p&gt;&lt;em&gt;The Power of the Platform&lt;/em&gt;&lt;/p&gt; 
&lt;p&gt;(Uber as a &quot;matching&quot;--matching ride-providers to ride-seekers--service)&lt;/p&gt; 
&lt;p&gt;Network effects: the impact the number of users of a platform has on the value created for each user.&lt;/p&gt; 
&lt;p&gt;Positive network effects: the ability of a large, well-managed platform community to produce significant value for each user of the platform&lt;/p&gt; 
&lt;p&gt;Negative network effects: the ability to reduce value for each user&lt;/p&gt; 
&lt;p&gt;Uber&apos;s &quot;virtuous circle&quot; (flowing clockwise)&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;Lower prices  ---&amp;gt; More demand \
  ^    ^                        \
  |     \                   More drivers
  |     Faster pickups          /
  |              ^             /
  |               \           /
  |                 ----  More geographic
  |               /       coverage/saturation
  |              v
Less driver downtime

(More demand -&amp;gt; More drivers -&amp;gt; More geographic coverage/satuation -&amp;gt; Faster pickups and Less driver downtime -&amp;gt; Lower prices -&amp;gt; More demand....)
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Demand economies of scale&lt;/em&gt;&lt;/strong&gt;&lt;br&gt; 20th-century monopolies were created based on supply-side economies of scale, driven by production efficiencies, which reduce unit cost of good/service delivered. 21st-century driven by demand economies of scale, which take advantage of technology improvements on the demand side--efficiencies in social networks, demand aggregation, app development, and other phenomena that make bigger networks more valuable to users. (Metcalfe&apos;s Law: The value of a telephone network.)&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Two-sided network effects&lt;/em&gt;&lt;/strong&gt;&lt;br&gt; (The cycle--both sides of the market are engaged.)&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Network effects vs other growth-building tools&lt;/em&gt;&lt;/strong&gt;&lt;br&gt; Price effects are evanescent: they disappear the moment the discounts end or another firm offers a better price. Typically only 1-2% convert.&lt;br&gt; Brand effects are stickier, but difficult to sustain.&lt;br&gt; Virality effects attract, but network effects keep people there.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Scaling network effects: Frictionless entry (and other tools)&lt;/em&gt;&lt;/strong&gt;&lt;br&gt; Effective platforms are able to expand in size quickly and easily, thereby scaling the value that derives from network effects. Netorks that permit frictionless entry are able to grow organically without limits.&lt;br&gt; Sideswitching: when users of one side of the platform can join the opposite side.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Negative network effects&lt;/em&gt;&lt;/strong&gt;&lt;br&gt; Growth adds to difficulty of finding matches; offset by curation.&lt;br&gt; Data-driven network effects&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Four kinds of network effects&lt;/em&gt;&lt;/strong&gt;&lt;br&gt; Two-by-two grid of &quot;same-side/cross-side&quot; and &quot;positive/negative&quot; network effects:&lt;br&gt; Same-side positive network effects&lt;br&gt; Same-side negative network effects&lt;br&gt; Cross-side positive network effects&lt;br&gt; Cross-side negative network effects&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Structural change: Network effects turn firms inside out&lt;/em&gt;&lt;/strong&gt;&lt;br&gt; Four broad categories of companies:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Asset builders&lt;/li&gt; 
 &lt;li&gt;Service providers&lt;/li&gt; 
 &lt;li&gt;Technology creators (develop/sell intellectural property)&lt;/li&gt; 
 &lt;li&gt;Network orchestrators (develop networks)&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;In the world of network effects, ecosystems of users are the new source of competitive advantage/market dominance.&lt;/p&gt; 
&lt;h1&gt;3. Architecture&lt;/h1&gt; 
&lt;p&gt;&lt;em&gt;Principles for Designing a Successful Platform&lt;/em&gt;&lt;/p&gt; 
&lt;p&gt;A platform connects producers w/consumers and allows them to exchange value, one of 3 things:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Information&lt;/li&gt; 
 &lt;li&gt;Goods/services&lt;/li&gt; 
 &lt;li&gt;Currency&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;&lt;strong&gt;&lt;em&gt;The core interaction: The Way of Platform Design&lt;/em&gt;&lt;/strong&gt;&lt;br&gt; 3 key components:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Particpants: Producer creates value, consumer consumes it&lt;/li&gt; 
 &lt;li&gt;Value unit: users are provided w/basis for deciding whether they want to proceed to further exchange&lt;/li&gt; 
 &lt;li&gt;Filter: Software-based tool used by the platform to enable the exchange of appropriate value units between users&lt;/li&gt; 
&lt;/ul&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;When designing a platform, your first and most important job is to decide what your core interaction will be, then define the participants, the value units, and the filters to make sure such core interaction is possible.&lt;/p&gt; 
 &lt;p&gt;Platforms don&apos;t create value units--they are created by the producers in the platform; thus the platforms are &quot;information factories&quot; that have no control over inventory. They create the &apos;factory floor&apos;; they can foster a culture of quality control, and they develop filters that are designed to deliver valuable units while blocking others, but they have no control over the production process itself.&lt;/p&gt; 
&lt;/blockquote&gt; 
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Pull, facilitate, match: The How of Platform Design&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Pull producers/consumers to the paltform&lt;/li&gt; 
 &lt;li&gt;Facilitate their interactions by providing tools/rules that make it easy for them to connect &amp;amp; enhance&lt;/li&gt; 
 &lt;li&gt;Match producers and consumers effectively by using info about each to connect them in ways they will find mutually rewarding&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;Pull challenges:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;attracting users&lt;/li&gt; 
 &lt;li&gt;keeping the interest of users&lt;/li&gt; 
 &lt;li&gt;tool: feedback loop(s): single-user and multi-user&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Behind the core interaction&lt;/em&gt;&lt;/strong&gt;&lt;br&gt; Successful platforms tend to scale by layering new inteactions on top of the core interaction&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;by changing the value unit exchanged between existing users&lt;/li&gt; 
 &lt;li&gt;by introducing a new category of users as either producers or consumers&lt;/li&gt; 
 &lt;li&gt;by allowing users to exchange new kinds of value units&lt;/li&gt; 
 &lt;li&gt;by curating membrs of an existing user group to create a new category of users&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Applying the end-to-end principle to platform design&lt;/em&gt;&lt;/strong&gt;&lt;br&gt; End-to-End Principle: in a general-purpose network, application-specific functions out to reside in the end hosts of a network rather than in intermediary nodes. Only the highest-volume, highest-value features that cut across apps should become part of the core platform.&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;When specific new features are incorporated into the core platform, apps that don&apos;t use them appear slow/inefficient; when app-specific features are run by an app itself, UX is cleaner&lt;/li&gt; 
 &lt;li&gt;Platform ecosystem can evolve faster when the core platform is a clean, simple system; stable core restricting variety, but underneath an evolving layer that enables variety&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Tower of Modularity&lt;/em&gt;&lt;/strong&gt;&lt;br&gt; Successful platform must have a modular approach; &quot;designers achieve modularity by partitioning information into visible design rules and hidden design parameters; modularity is beneficial only if the partition is precide, unambiguous, and complete.&quot; ... &quot;Fundamental architecture behind all systems is ... the system is partitioned into a set of &apos;core&apos; components w/low variety and a complementary set of &apos;peripheral&apos; components w/high variety. The low-variety components consititute the platform. They are the long-lived elements of the system and thus implicitly/explicitly establish the system&apos;s interfaces and the rules governing interactions among the parts.&quot;&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Re-architecting the platform&lt;/em&gt;&lt;/strong&gt;&lt;br&gt; First step: analyze the degree of modularity already achieved.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Iterative improvement: The Anti-Design principle&lt;/em&gt;&lt;/strong&gt;&lt;br&gt; Platforms cannot be entirely planned--they also emerge; platforms characterized by activity controlled by the users, not bythe owners/managers. Platform designers should always leave room for serendipitous discoveries, as suers often lead the way to where design should evolve. Close monitoring of user behavior reveals unexpected patterns, some of which may suggest fruitful new ideas for value creation. Best platforms allow for user quirks &amp;amp; are open enough to gradually incorporate such quirks.&lt;/p&gt; 
&lt;h1&gt;4. Disruption&lt;/h1&gt; 
&lt;p&gt;&lt;em&gt;How Platforms Conquer and Transform Traditional Industries&lt;/em&gt;&lt;/p&gt; 
&lt;p&gt;Platform concept is not new--farmer&apos;s markets, stock markets, etc. What&apos;s new is digital technology enabling reach.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Capsule history of digitial disruption&lt;/em&gt;&lt;/strong&gt;&lt;br&gt; Stage 1: Efficient pipelines are inefficient pipelines&lt;br&gt; Stage 2: Platforms eat pipelines&lt;br&gt; In the world of platforms, the internet no longer acts merely as a distribution channel; it also acts as a creation infrstructure &amp;amp; coordination mechanism&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Impacts of platform distribution on value creation, value consumption, and quality control&lt;/em&gt;&lt;/strong&gt;&lt;br&gt; Reconfiguring value creation to tape new supply sources&lt;br&gt; Reconfiguring value consumption by enabling new forms of consumer behavior&lt;br&gt; Reconfiguring quality control through community-driven curation&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Structural impacts of platform disruption&lt;/em&gt;&lt;/strong&gt;&lt;br&gt; De-linking assets from value&lt;br&gt; Re-intermediation&lt;br&gt; Market aggregation&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;&lt;em&gt;The incumbents fight back: Pipelines becoming platforms&lt;/em&gt;&lt;/strong&gt;&lt;br&gt; They&apos;ll need to ask questions:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Which processes that we curently manage in-house can be delegated to outside partners, whether suppliers or consumers?&lt;/li&gt; 
 &lt;li&gt;How can we empower outside partners to create products/services that will generate new forms of value for our existing customers?&lt;/li&gt; 
 &lt;li&gt;Are there way swe can network w/current competitors to produce valuable new services for customers?&lt;/li&gt; 
 &lt;li&gt;How can the value of the goods &amp;amp; services we currently provide be enhanced through new data streams, interpersonal connection, and curation tools?&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h1&gt;5. Launch: Chicken or Egg?&lt;/h1&gt; 
&lt;p&gt;&lt;em&gt;Eight Ways to Launch a Successful Platform&lt;/em&gt;&lt;/p&gt; 
&lt;h4&gt;The heart of platform marketing: Designing for growth&lt;/h4&gt; 
&lt;p&gt;Pull strategies are most effective/important over push; goods/services must be designed to be so attractive they naturally pull customers into their orbit&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;&lt;em&gt;The incumbents&apos; advantage: Reality or illusion?&lt;/em&gt;&lt;/strong&gt;&lt;br&gt; Large enterprises have advantages, which can lead to complacency&lt;/p&gt; 
&lt;h4&gt;Platform launch strategies&lt;/h4&gt; 
&lt;ol&gt; 
 &lt;li&gt;&lt;strong&gt;&lt;em&gt;The Follow-the-Rabbit Strategy.&lt;/em&gt;&lt;/strong&gt; Use a non-platform demonstration project to model success, probably attracting both users and producers to a new platform erected on your project&apos;s proven infrastructure. How to overcome the chicken/egg problem: 
  &lt;ul&gt; 
   &lt;li&gt;Staging value creation: The platform managers arrange for the creation of value units that will attract one or more sets of users and demonstrate the potential benefits of participating in the platform.&lt;/li&gt; 
   &lt;li&gt;Designing the paltform to attract one set of users: platform is designed to provide tools, products, services, or other benefits that will attract one set of users--consumers or producers. The existence of a critical mass of users on one side of a marketplace attracts users on the other side, leading to a positive feedback loop.&lt;/li&gt; 
   &lt;li&gt;Simultanous on-boarding: platform creates conditions such that value units can be created that are relevant to users even when the network size is too small. It then strives to stimulate a burst of activity that will simultanously attract both consumers and producers in sufficient numbers to create larger numbers of value units and value-producing interactions so that network effects begin to kick in.&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;&lt;em&gt;The Piggyback Strategy.&lt;/em&gt;&lt;/strong&gt; Connect with an existing user base from a different platform and stage the creation of value units in order to recruit those users to participate.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;&lt;em&gt;The Seeding Strategy.&lt;/em&gt;&lt;/strong&gt; Create value units that will be relevant to at least one set of potential users. When those users are attracted to the platform, other sets of users who want to engage in interactions with them will follow. In many cases, the platform company takes the task of value creation upon itself by acting as the first producer. In addition to jump-starting the platform, the platform owner can define kind and quality of value units they want to see.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;&lt;em&gt;The Marquee Strategy.&lt;/em&gt;&lt;/strong&gt; Provide incentives to attract members of a key user set onto your platform. A variation of this is to choose to purchase a marquee participant in order to obtain exclusive access to the seeds it produces.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;&lt;em&gt;The Single-Side Strategy.&lt;/em&gt;&lt;/strong&gt; Create a business around products or services that benefit a single set of users; later, convert the business into a platform business by attracting a second set of users who want to engage in interactions with the first set.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;&lt;em&gt;The Producer Evangelism Strategy.&lt;/em&gt;&lt;/strong&gt; Design your platform to attract producers, who can induce their customers to become users of the platform. Platforms that provide businesses w/tools for customer relationship management can often solve the chicken/egg problem by attracting one set of users (producers) who then take on the task of bringing along the other set (consumers) from their own customer base. The platform helps the producers cater to their existing set of consumers, and over time, the producers benefit from data-driven cross-pollination as other consumers on the network become interested.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;&lt;em&gt;The Big-Bang Adoption Strategy.&lt;/em&gt;&lt;/strong&gt; Use one or more traditional push marketing strategies to attract a high volume of interest and attention to your platofrm. This triggers a simultaneous on-boarding effect.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;&lt;em&gt;The Micromarket Strategy.&lt;/em&gt;&lt;/strong&gt; Start by targeting a tiny market that comprises members who are already engaging in interactions. This enables the platform to provide the effective matchmaking characteristic of a large market even in the earliest stages of growth.&lt;/li&gt; 
&lt;/ol&gt; 
&lt;h4&gt;Viral growth: The user-to-user launch mechanism&lt;/h4&gt; 
&lt;p&gt;Four key elements:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;The sender: getting senders to spread value untis is not the same as word-of-mouth; word of mouth happens when users like your platform so much, they can&apos;t stop talking about it. When users become senders and spread value units, they aren&apos;t talking about your platform--they are spreading their own creations, and indirectly generating awareness of/interest in your platform. Users do this to get social feedback (fun, fame, fulfillment, fortune, etc); avoid discouraging the spread of value units&lt;/li&gt; 
 &lt;li&gt;The value unit: The fundamental unit of virality, but not all value units are spreadable. Design value units to be spreadable as a crucial step.&lt;/li&gt; 
 &lt;li&gt;The recipient: Platform managers have no control over them.&lt;/li&gt; 
 &lt;li&gt;The external network: External networks often impose restrictions.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h1&gt;6. Monetization&lt;/h1&gt; 
&lt;p&gt;&lt;em&gt;Capturing the Value Created by Network Effects&lt;/em&gt;&lt;/p&gt; 
&lt;h1&gt;7. Openness&lt;/h1&gt; 
&lt;p&gt;&lt;em&gt;Defining What Platform Users and Partners Can and Cannot Do&lt;/em&gt;&lt;/p&gt; 
&lt;h1&gt;8. Governance&lt;/h1&gt; 
&lt;p&gt;&lt;em&gt;Policies to Increase Value and Enhance Growth&lt;/em&gt;&lt;/p&gt; 
&lt;h1&gt;9. Metrics&lt;/h1&gt; 
&lt;p&gt;&lt;em&gt;How Platform Managers Can Measure What Really Matters&lt;/em&gt;&lt;/p&gt; 
&lt;h1&gt;10. Strategy&lt;/h1&gt; 
&lt;p&gt;&lt;em&gt;How Platforms Change Competition&lt;/em&gt;&lt;/p&gt; 
&lt;h1&gt;11. Policy&lt;/h1&gt; 
&lt;p&gt;&lt;em&gt;How Platforms Should (and Should Not) Be Regulated&lt;/em&gt;&lt;/p&gt; 
&lt;h1&gt;12. Tomorrow&lt;/h1&gt; 
&lt;p&gt;&lt;em&gt;The Future of the Platform Revolution&lt;/em&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Steve Yegge Rants</title>
      <link>https://tedneward.github.io/Research/reading/business/yegge/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">reading/business/yegge/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://gist.github.com/chitchcock/1281611&quot;&gt;Stevey&apos;s Google Platforms Rant&lt;/a&gt;: &lt;em&gt;(This is too good not to capture a copy so I make sure I always have it on-hand. For personal use only--go link to the original.)&lt;/em&gt;&lt;/p&gt; 
&lt;h1&gt;Stevey&apos;s Google Platforms Rant (2011)&lt;/h1&gt; 
&lt;p&gt;I was at Amazon for about six and a half years, and now I&apos;ve been at Google for that long. One thing that struck me immediately about the two companies -- an impression that has been reinforced almost daily -- is that Amazon does everything wrong, and Google does everything right. Sure, it&apos;s a sweeping generalization, but a surprisingly accurate one. It&apos;s pretty crazy. There are probably a hundred or even two hundred different ways you can compare the two companies, and Google is superior in all but three of them, if I recall correctly. I actually did a spreadsheet at one point but Legal wouldn&apos;t let me show it to anyone, even though recruiting loved it.&lt;/p&gt; 
&lt;p&gt;I mean, just to give you a very brief taste: Amazon&apos;s recruiting process is fundamentally flawed by having teams hire for themselves, so their hiring bar is incredibly inconsistent across teams, despite various efforts they&apos;ve made to level it out. And their operations are a mess; they don&apos;t really have SREs and they make engineers pretty much do everything, which leaves almost no time for coding - though again this varies by group, so it&apos;s luck of the draw. They don&apos;t give a single shit about charity or helping the needy or community contributions or anything like that. Never comes up there, except maybe to laugh about it. Their facilities are dirt-smeared cube farms without a dime spent on decor or common meeting areas. Their pay and benefits suck, although much less so lately due to local competition from Google and Facebook. But they don&apos;t have any of our perks or extras -- they just try to match the offer-letter numbers, and that&apos;s the end of it. Their code base is a disaster, with no engineering standards whatsoever except what individual teams choose to put in place.&lt;/p&gt; 
&lt;p&gt;To be fair, they do have a nice versioned-library system that we really ought to emulate, and a nice publish-subscribe system that we also have no equivalent for. But for the most part they just have a bunch of crappy tools that read and write state machine information into relational databases. We wouldn&apos;t take most of it even if it were free.&lt;/p&gt; 
&lt;p&gt;I think the pubsub system and their library-shelf system were two out of the grand total of three things Amazon does better than google.&lt;/p&gt; 
&lt;p&gt;I guess you could make an argument that their bias for launching early and iterating like mad is also something they do well, but you can argue it either way. They prioritize launching early over everything else, including retention and engineering discipline and a bunch of other stuff that turns out to matter in the long run. So even though it&apos;s given them some competitive advantages in the marketplace, it&apos;s created enough other problems to make it something less than a slam-dunk.&lt;/p&gt; 
&lt;p&gt;But there&apos;s one thing they do really really well that pretty much makes up for ALL of their political, philosophical and technical screw-ups.&lt;/p&gt; 
&lt;p&gt;Jeff Bezos is an infamous micro-manager. He micro-manages every single pixel of Amazon&apos;s retail site. He hired Larry Tesler, Apple&apos;s Chief Scientist and probably the very most famous and respected human-computer interaction expert in the entire world, and then ignored every goddamn thing Larry said for three years until Larry finally -- wisely -- left the company. Larry would do these big usability studies and demonstrate beyond any shred of doubt that nobody can understand that frigging website, but Bezos just couldn&apos;t let go of those pixels, all those millions of semantics-packed pixels on the landing page. They were like millions of his own precious children. So they&apos;re all still there, and Larry is not.&lt;/p&gt; 
&lt;p&gt;Micro-managing isn&apos;t that third thing that Amazon does better than us, by the way. I mean, yeah, they micro-manage really well, but I wouldn&apos;t list it as a strength or anything. I&apos;m just trying to set the context here, to help you understand what happened. We&apos;re talking about a guy who in all seriousness has said on many public occasions that people should be paying him to work at Amazon. He hands out little yellow stickies with his name on them, reminding people &quot;who runs the company&quot; when they disagree with him. The guy is a regular... well, Steve Jobs, I guess. Except without the fashion or design sense. Bezos is super smart; don&apos;t get me wrong. He just makes ordinary control freaks look like stoned hippies.&lt;/p&gt; 
&lt;p&gt;So one day Jeff Bezos issued a mandate. He&apos;s doing that all the time, of course, and people scramble like ants being pounded with a rubber mallet whenever it happens. But on one occasion -- back around 2002 I think, plus or minus a year -- he issued a mandate that was so out there, so huge and eye-bulgingly ponderous, that it made all of his other mandates look like unsolicited peer bonuses.&lt;/p&gt; 
&lt;p&gt;His Big Mandate went something along these lines:&lt;/p&gt; 
&lt;p&gt;1) All teams will henceforth expose their data and functionality through service interfaces.&lt;/p&gt; 
&lt;p&gt;2) Teams must communicate with each other through these interfaces.&lt;/p&gt; 
&lt;p&gt;3) There will be no other form of interprocess communication allowed: no direct linking, no direct reads of another team&apos;s data store, no shared-memory model, no back-doors whatsoever. The only communication allowed is via service interface calls over the network.&lt;/p&gt; 
&lt;p&gt;4) It doesn&apos;t matter what technology they use. HTTP, Corba, Pubsub, custom protocols -- doesn&apos;t matter. Bezos doesn&apos;t care.&lt;/p&gt; 
&lt;p&gt;5) All service interfaces, without exception, must be designed from the ground up to be externalizable. That is to say, the team must plan and design to be able to expose the interface to developers in the outside world. No exceptions.&lt;/p&gt; 
&lt;p&gt;6) Anyone who doesn&apos;t do this will be fired.&lt;/p&gt; 
&lt;p&gt;7) Thank you; have a nice day!&lt;/p&gt; 
&lt;p&gt;Ha, ha! You 150-odd ex-Amazon folks here will of course realize immediately that #7 was a little joke I threw in, because Bezos most definitely does not give a shit about your day.&lt;/p&gt; 
&lt;p&gt;#6, however, was quite real, so people went to work. Bezos assigned a couple of Chief Bulldogs to oversee the effort and ensure forward progress, headed up by Uber-Chief Bear Bulldog Rick Dalzell. Rick is an ex-Armgy Ranger, West Point Academy graduate, ex-boxer, ex-Chief Torturer slash CIO at Wal*Mart, and is a big genial scary man who used the word &quot;hardened interface&quot; a lot. Rick was a walking, talking hardened interface himself, so needless to say, everyone made LOTS of forward progress and made sure Rick knew about it.&lt;/p&gt; 
&lt;p&gt;Over the next couple of years, Amazon transformed internally into a service-oriented architecture. They learned a tremendous amount while effecting this transformation. There was lots of existing documentation and lore about SOAs, but at Amazon&apos;s vast scale it was about as useful as telling Indiana Jones to look both ways before crossing the street. Amazon&apos;s dev staff made a lot of discoveries along the way. A teeny tiny sampling of these discoveries included:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt; &lt;p&gt;pager escalation gets way harder, because a ticket might bounce through 20 service calls before the real owner is identified. If each bounce goes through a team with a 15-minute response time, it can be hours before the right team finally finds out, unless you build a lot of scaffolding and metrics and reporting.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;every single one of your peer teams suddenly becomes a potential DOS attacker. Nobody can make any real forward progress until very serious quotas and throttling are put in place in every single service.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;monitoring and QA are the same thing. You&apos;d never think so until you try doing a big SOA. But when your service says &quot;oh yes, I&apos;m fine&quot;, it may well be the case that the only thing still functioning in the server is the little component that knows how to say &quot;I&apos;m fine, roger roger, over and out&quot; in a cheery droid voice. In order to tell whether the service is actually responding, you have to make individual calls. The problem continues recursively until your monitoring is doing comprehensive semantics checking of your entire range of services and data, at which point it&apos;s indistinguishable from automated QA. So they&apos;re a continuum.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;if you have hundreds of services, and your code MUST communicate with other groups&apos; code via these services, then you won&apos;t be able to find any of them without a service-discovery mechanism. And you can&apos;t have that without a service registration mechanism, which itself is another service. So Amazon has a universal service registry where you can find out reflectively (programmatically) about every service, what its APIs are, and also whether it is currently up, and where.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;debugging problems with someone else&apos;s code gets a LOT harder, and is basically impossible unless there is a universal standard way to run every service in a debuggable sandbox.&lt;/p&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;That&apos;s just a very small sample. There are dozens, maybe hundreds of individual learnings like these that Amazon had to discover organically. There were a lot of wacky ones around externalizing services, but not as many as you might think. Organizing into services taught teams not to trust each other in most of the same ways they&apos;re not supposed to trust external developers.&lt;/p&gt; 
&lt;p&gt;This effort was still underway when I left to join Google in mid-2005, but it was pretty far advanced. From the time Bezos issued his edict through the time I left, Amazon had transformed culturally into a company that thinks about everything in a services-first fashion. It is now fundamental to how they approach all designs, including internal designs for stuff that might never see the light of day externally.&lt;/p&gt; 
&lt;p&gt;At this point they don&apos;t even do it out of fear of being fired. I mean, they&apos;re still afraid of that; it&apos;s pretty much part of daily life there, working for the Dread Pirate Bezos and all. But they do services because they&apos;ve come to understand that it&apos;s the Right Thing. There are without question pros and cons to the SOA approach, and some of the cons are pretty long. But overall it&apos;s the right thing because SOA-driven design enables Platforms.&lt;/p&gt; 
&lt;p&gt;That&apos;s what Bezos was up to with his edict, of course. He didn&apos;t (and doesn&apos;t) care even a tiny bit about the well-being of the teams, nor about what technologies they use, nor in fact any detail whatsoever about how they go about their business unless they happen to be screwing up. But Bezos realized long before the vast majority of Amazonians that Amazon needs to be a platform.&lt;/p&gt; 
&lt;p&gt;You wouldn&apos;t really think that an online bookstore needs to be an extensible, programmable platform. Would you?&lt;/p&gt; 
&lt;p&gt;Well, the first big thing Bezos realized is that the infrastructure they&apos;d built for selling and shipping books and sundry could be transformed an excellent repurposable computing platform. So now they have the Amazon Elastic Compute Cloud, and the Amazon Elastic MapReduce, and the Amazon Relational Database Service, and a whole passel&apos; o&apos; other services browsable at aws.amazon.com. These services host the backends for some pretty successful companies, reddit being my personal favorite of the bunch.&lt;/p&gt; 
&lt;p&gt;The other big realization he had was that he can&apos;t always build the right thing. I think Larry Tesler might have struck some kind of chord in Bezos when he said his mom couldn&apos;t use the goddamn website. It&apos;s not even super clear whose mom he was talking about, and doesn&apos;t really matter, because nobody&apos;s mom can use the goddamn website. In fact I myself find the website disturbingly daunting, and I worked there for over half a decade. I&apos;ve just learned to kinda defocus my eyes and concentrate on the million or so pixels near the center of the page above the fold.&lt;/p&gt; 
&lt;p&gt;I&apos;m not really sure how Bezos came to this realization -- the insight that he can&apos;t build one product and have it be right for everyone. But it doesn&apos;t matter, because he gets it. There&apos;s actually a formal name for this phenomenon. It&apos;s called Accessibility, and it&apos;s the most important thing in the computing world.&lt;/p&gt; 
&lt;p&gt;The. Most. Important. Thing.&lt;/p&gt; 
&lt;p&gt;If you&apos;re sorta thinking, &quot;huh? You mean like, blind and deaf people Accessibility?&quot; then you&apos;re not alone, because I&apos;ve come to understand that there are lots and LOTS of people just like you: people for whom this idea does not have the right Accessibility, so it hasn&apos;t been able to get through to you yet. It&apos;s not your fault for not understanding, any more than it would be your fault for being blind or deaf or motion-restricted or living with any other disability. When software -- or idea-ware for that matter -- fails to be accessible to anyone for any reason, it is the fault of the software or of the messaging of the idea. It is an Accessibility failure.&lt;/p&gt; 
&lt;p&gt;Like anything else big and important in life, Accessibility has an evil twin who, jilted by the unbalanced affection displayed by their parents in their youth, has grown into an equally powerful Arch-Nemesis (yes, there&apos;s more than one nemesis to accessibility) named Security. And boy howdy are the two ever at odds.&lt;/p&gt; 
&lt;p&gt;But I&apos;ll argue that Accessibility is actually more important than Security because dialing Accessibility to zero means you have no product at all, whereas dialing Security to zero can still get you a reasonably successful product such as the Playstation Network.&lt;/p&gt; 
&lt;p&gt;So yeah. In case you hadn&apos;t noticed, I could actually write a book on this topic. A fat one, filled with amusing anecdotes about ants and rubber mallets at companies I&apos;ve worked at. But I will never get this little rant published, and you&apos;ll never get it read, unless I start to wrap up.&lt;/p&gt; 
&lt;p&gt;That one last thing that Google doesn&apos;t do well is Platforms. We don&apos;t understand platforms. We don&apos;t &quot;get&quot; platforms. Some of you do, but you are the minority. This has become painfully clear to me over the past six years. I was kind of hoping that competitive pressure from Microsoft and Amazon and more recently Facebook would make us wake up collectively and start doing universal services. Not in some sort of ad-hoc, half-assed way, but in more or less the same way Amazon did it: all at once, for real, no cheating, and treating it as our top priority from now on.&lt;/p&gt; 
&lt;p&gt;But no. No, it&apos;s like our tenth or eleventh priority. Or fifteenth, I don&apos;t know. It&apos;s pretty low. There are a few teams who treat the idea very seriously, but most teams either don&apos;t think about it all, ever, or only a small percentage of them think about it in a very small way.&lt;/p&gt; 
&lt;p&gt;It&apos;s a big stretch even to get most teams to offer a stubby service to get programmatic access to their data and computations. Most of them think they&apos;re building products. And a stubby service is a pretty pathetic service. Go back and look at that partial list of learnings from Amazon, and tell me which ones Stubby gives you out of the box. As far as I&apos;m concerned, it&apos;s none of them. Stubby&apos;s great, but it&apos;s like parts when you need a car.&lt;/p&gt; 
&lt;p&gt;A product is useless without a platform, or more precisely and accurately, a platform-less product will always be replaced by an equivalent platform-ized product.&lt;/p&gt; 
&lt;p&gt;Google+ is a prime example of our complete failure to understand platforms from the very highest levels of executive leadership (hi Larry, Sergey, Eric, Vic, howdy howdy) down to the very lowest leaf workers (hey yo). We all don&apos;t get it. The Golden Rule of platforms is that you Eat Your Own Dogfood. The Google+ platform is a pathetic afterthought. We had no API at all at launch, and last I checked, we had one measly API call. One of the team members marched in and told me about it when they launched, and I asked: &quot;So is it the Stalker API?&quot; She got all glum and said &quot;Yeah.&quot; I mean, I was joking, but no... the only API call we offer is to get someone&apos;s stream. So I guess the joke was on me.&lt;/p&gt; 
&lt;p&gt;Microsoft has known about the Dogfood rule for at least twenty years. It&apos;s been part of their culture for a whole generation now. You don&apos;t eat People Food and give your developers Dog Food. Doing that is simply robbing your long-term platform value for short-term successes. Platforms are all about long-term thinking.&lt;/p&gt; 
&lt;p&gt;Google+ is a knee-jerk reaction, a study in short-term thinking, predicated on the incorrect notion that Facebook is successful because they built a great product. But that&apos;s not why they are successful. Facebook is successful because they built an entire constellation of products by allowing other people to do the work. So Facebook is different for everyone. Some people spend all their time on Mafia Wars. Some spend all their time on Farmville. There are hundreds or maybe thousands of different high-quality time sinks available, so there&apos;s something there for everyone.&lt;/p&gt; 
&lt;p&gt;Our Google+ team took a look at the aftermarket and said: &quot;Gosh, it looks like we need some games. Let&apos;s go contract someone to, um, write some games for us.&quot; Do you begin to see how incredibly wrong that thinking is now? The problem is that we are trying to predict what people want and deliver it for them.&lt;/p&gt; 
&lt;p&gt;You can&apos;t do that. Not really. Not reliably. There have been precious few people in the world, over the entire history of computing, who have been able to do it reliably. Steve Jobs was one of them. We don&apos;t have a Steve Jobs here. I&apos;m sorry, but we don&apos;t.&lt;/p&gt; 
&lt;p&gt;Larry Tesler may have convinced Bezos that he was no Steve Jobs, but Bezos realized that he didn&apos;t need to be a Steve Jobs in order to provide everyone with the right products: interfaces and workflows that they liked and felt at ease with. He just needed to enable third-party developers to do it, and it would happen automatically.&lt;/p&gt; 
&lt;p&gt;I apologize to those (many) of you for whom all this stuff I&apos;m saying is incredibly obvious, because yeah. It&apos;s incredibly frigging obvious. Except we&apos;re not doing it. We don&apos;t get Platforms, and we don&apos;t get Accessibility. The two are basically the same thing, because platforms solve accessibility. A platform is accessibility.&lt;/p&gt; 
&lt;p&gt;So yeah, Microsoft gets it. And you know as well as I do how surprising that is, because they don&apos;t &quot;get&quot; much of anything, really. But they understand platforms as a purely accidental outgrowth of having started life in the business of providing platforms. So they have thirty-plus years of learning in this space. And if you go to msdn.com, and spend some time browsing, and you&apos;ve never seen it before, prepare to be amazed. Because it&apos;s staggeringly huge. They have thousands, and thousands, and THOUSANDS of API calls. They have a HUGE platform. Too big in fact, because they can&apos;t design for squat, but at least they&apos;re doing it.&lt;/p&gt; 
&lt;p&gt;Amazon gets it. Amazon&apos;s AWS (aws.amazon.com) is incredible. Just go look at it. Click around. It&apos;s embarrassing. We don&apos;t have any of that stuff.&lt;/p&gt; 
&lt;p&gt;Apple gets it, obviously. They&apos;ve made some fundamentally non-open choices, particularly around their mobile platform. But they understand accessibility and they understand the power of third-party development and they eat their dogfood. And you know what? They make pretty good dogfood. Their APIs are a hell of a lot cleaner than Microsoft&apos;s, and have been since time immemorial.&lt;/p&gt; 
&lt;p&gt;Facebook gets it. That&apos;s what really worries me. That&apos;s what got me off my lazy butt to write this thing. I hate blogging. I hate... plussing, or whatever it&apos;s called when you do a massive rant in Google+ even though it&apos;s a terrible venue for it but you do it anyway because in the end you really do want Google to be successful. And I do! I mean, Facebook wants me there, and it&apos;d be pretty easy to just go. But Google is home, so I&apos;m insisting that we have this little family intervention, uncomfortable as it might be.&lt;/p&gt; 
&lt;p&gt;After you&apos;ve marveled at the platform offerings of Microsoft and Amazon, and Facebook I guess (I didn&apos;t look because I didn&apos;t want to get too depressed), head over to developers.google.com and browse a little. Pretty big difference, eh? It&apos;s like what your fifth-grade nephew might mock up if he were doing an assignment to demonstrate what a big powerful platform company might be building if all they had, resource-wise, was one fifth grader.&lt;/p&gt; 
&lt;p&gt;Please don&apos;t get me wrong here -- I know for a fact that the dev-rel team has had to FIGHT to get even this much available externally. They&apos;re kicking ass as far as I&apos;m concerned, because they DO get platforms, and they are struggling heroically to try to create one in an environment that is at best platform-apathetic, and at worst often openly hostile to the idea.&lt;/p&gt; 
&lt;p&gt;I&apos;m just frankly describing what developers.google.com looks like to an outsider. It looks childish. Where&apos;s the Maps APIs in there for Christ&apos;s sake? Some of the things in there are labs projects. And the APIs for everything I clicked were... they were paltry. They were obviously dog food. Not even good organic stuff. Compared to our internal APIs it&apos;s all snouts and horse hooves.&lt;/p&gt; 
&lt;p&gt;And also don&apos;t get me wrong about Google+. They&apos;re far from the only offenders. This is a cultural thing. What we have going on internally is basically a war, with the underdog minority Platformers fighting a more or less losing battle against the Mighty Funded Confident Producters.&lt;/p&gt; 
&lt;p&gt;Any teams that have successfully internalized the notion that they should be externally programmable platforms from the ground up are underdogs -- Maps and Docs come to mind, and I know GMail is making overtures in that direction. But it&apos;s hard for them to get funding for it because it&apos;s not part of our culture. Maestro&apos;s funding is a feeble thing compared to the gargantuan Microsoft Office programming platform: it&apos;s a fluffy rabbit versus a T-Rex. The Docs team knows they&apos;ll never be competitive with Office until they can match its scripting facilities, but they&apos;re not getting any resource love. I mean, I assume they&apos;re not, given that Apps Script only works in Spreadsheet right now, and it doesn&apos;t even have keyboard shortcuts as part of its API. That team looks pretty unloved to me.&lt;/p&gt; 
&lt;p&gt;Ironically enough, Wave was a great platform, may they rest in peace. But making something a platform is not going to make you an instant success. A platform needs a killer app. Facebook -- that is, the stock service they offer with walls and friends and such -- is the killer app for the Facebook Platform. And it is a very serious mistake to conclude that the Facebook App could have been anywhere near as successful without the Facebook Platform.&lt;/p&gt; 
&lt;p&gt;You know how people are always saying Google is arrogant? I&apos;m a Googler, so I get as irritated as you do when people say that. We&apos;re not arrogant, by and large. We&apos;re, like, 99% Arrogance-Free. I did start this post -- if you&apos;ll reach back into distant memory -- by describing Google as &quot;doing everything right&quot;. We do mean well, and for the most part when people say we&apos;re arrogant it&apos;s because we didn&apos;t hire them, or they&apos;re unhappy with our policies, or something along those lines. They&apos;re inferring arrogance because it makes them feel better.&lt;/p&gt; 
&lt;p&gt;But when we take the stance that we know how to design the perfect product for everyone, and believe you me, I hear that a lot, then we&apos;re being fools. You can attribute it to arrogance, or naivete, or whatever -- it doesn&apos;t matter in the end, because it&apos;s foolishness. There IS no perfect product for everyone.&lt;/p&gt; 
&lt;p&gt;And so we wind up with a browser that doesn&apos;t let you set the default font size. Talk about an affront to Accessibility. I mean, as I get older I&apos;m actually going blind. For real. I&apos;ve been nearsighted all my life, and once you hit 40 years old you stop being able to see things up close. So font selection becomes this life-or-death thing: it can lock you out of the product completely. But the Chrome team is flat-out arrogant here: they want to build a zero-configuration product, and they&apos;re quite brazen about it, and Fuck You if you&apos;re blind or deaf or whatever. Hit Ctrl-+ on every single page visit for the rest of your life.&lt;/p&gt; 
&lt;p&gt;It&apos;s not just them. It&apos;s everyone. The problem is that we&apos;re a Product Company through and through. We built a successful product with broad appeal -- our search, that is -- and that wild success has biased us.&lt;/p&gt; 
&lt;p&gt;Amazon was a product company too, so it took an out-of-band force to make Bezos understand the need for a platform. That force was their evaporating margins; he was cornered and had to think of a way out. But all he had was a bunch of engineers and all these computers... if only they could be monetized somehow... you can see how he arrived at AWS, in hindsight.&lt;/p&gt; 
&lt;p&gt;Microsoft started out as a platform, so they&apos;ve just had lots of practice at it.&lt;/p&gt; 
&lt;p&gt;Facebook, though: they worry me. I&apos;m no expert, but I&apos;m pretty sure they started off as a Product and they rode that success pretty far. So I&apos;m not sure exactly how they made the transition to a platform. It was a relatively long time ago, since they had to be a platform before (now very old) things like Mafia Wars could come along.&lt;/p&gt; 
&lt;p&gt;Maybe they just looked at us and asked: &quot;How can we beat Google? What are they missing?&quot;&lt;/p&gt; 
&lt;p&gt;The problem we face is pretty huge, because it will take a dramatic cultural change in order for us to start catching up. We don&apos;t do internal service-oriented platforms, and we just as equally don&apos;t do external ones. This means that the &quot;not getting it&quot; is endemic across the company: the PMs don&apos;t get it, the engineers don&apos;t get it, the product teams don&apos;t get it, nobody gets it. Even if individuals do, even if YOU do, it doesn&apos;t matter one bit unless we&apos;re treating it as an all-hands-on-deck emergency. We can&apos;t keep launching products and pretending we&apos;ll turn them into magical beautiful extensible platforms later. We&apos;ve tried that and it&apos;s not working.&lt;/p&gt; 
&lt;p&gt;The Golden Rule of Platforms, &quot;Eat Your Own Dogfood&quot;, can be rephrased as &quot;Start with a Platform, and Then Use it for Everything.&quot; You can&apos;t just bolt it on later. Certainly not easily at any rate -- ask anyone who worked on platformizing MS Office. Or anyone who worked on platformizing Amazon. If you delay it, it&apos;ll be ten times as much work as just doing it correctly up front. You can&apos;t cheat. You can&apos;t have secret back doors for internal apps to get special priority access, not for ANY reason. You need to solve the hard problems up front.&lt;/p&gt; 
&lt;p&gt;I&apos;m not saying it&apos;s too late for us, but the longer we wait, the closer we get to being Too Late.&lt;/p&gt; 
&lt;p&gt;I honestly don&apos;t know how to wrap this up. I&apos;ve said pretty much everything I came here to say today. This post has been six years in the making. I&apos;m sorry if I wasn&apos;t gentle enough, or if I misrepresented some product or team or person, or if we&apos;re actually doing LOTS of platform stuff and it just so happens that I and everyone I ever talk to has just never heard about it. I&apos;m sorry.&lt;/p&gt; 
&lt;p&gt;But we&apos;ve gotta start doing this right.&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://plus.google.com/110981030061712822816/posts/WugKtXSp7We&quot;&gt;Original URL&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://plus.google.com/110981030061712822816/posts/bwJ7kAELRnf&quot;&gt;Follow-up URL&lt;/a&gt;&lt;/p&gt; 
&lt;hr&gt;
	</description>
    </item>
    <item>
      <title>Lit</title>
      <link>https://tedneward.github.io/Research/presentation/webcomponents/lit/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/webcomponents/lit/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://lit.dev/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/lit/lit/&quot;&gt;Source&lt;/a&gt; | &lt;a href=&quot;https://lit.dev/tutorial/&quot;&gt;Tutorial&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Builds on top of Web Components.&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-ts&quot;&gt;import {html, css, LitElement} from &apos;lit&apos;;
import {customElement, property} from &apos;lit/decorators.js&apos;;

@customElement(&apos;simple-greeting&apos;)  // (1)
export class SimpleGreeting extends LitElement {
  static styles = css`p { color: blue }`;  // (2)

  @property()       // (3)
  name = &apos;Somebody&apos;;

  render() {
    return html`&amp;lt;p&amp;gt;Hello, ${this.name}!&amp;lt;/p&amp;gt;`;  // (4)
  }
}
&lt;/code&gt;&lt;/pre&gt; 
&lt;ol&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Custom Elements&lt;/strong&gt; Lit components are standard custom elements, so the browser treats them exactly like built-in elements. Use them in hand-written HTML or framework code, output them from your CMS or static site builder, even create instances in JavaScript — they just work!&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Scoped styles&lt;/strong&gt; Lit scopes your styles by default, using Shadow DOM. This keeps your CSS selectors simple and ensures that your component’s styles don&apos;t affect — and aren&apos;t affected by — any other styles on the page.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Reactive properties&lt;/strong&gt; Declare reactive properties to model your component’s API and internal state. A Lit component efficiently re-renders whenever a reactive property (or corresponding HTML attribute) changes.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Declarative templates&lt;/strong&gt; Lit templates, based on tagged template literals, are simple, expressive and fast, featuring HTML markup with native JavaScript expressions inline. No custom syntax to learn, no compilation required.&lt;/p&gt; &lt;/li&gt; 
&lt;/ol&gt; 
&lt;pre&gt;&lt;code&gt;&amp;lt;simple-greeting name=&quot;World&quot;&amp;gt;&amp;lt;/simple-greeting&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
	</description>
    </item>
    <item>
      <title>WebGui</title>
      <link>https://tedneward.github.io/Research/presentation/webgui/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/webgui/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://jnmaloney.github.io/WebGui/imgui.html&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/jnmaloney/WebGui&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Wiggle-UI</title>
      <link>https://tedneward.github.io/Research/presentation/wiggle-ui/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/wiggle-ui/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://wigggle-ui.vercel.app/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/wigggle-ui/ui&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>WinUI</title>
      <link>https://tedneward.github.io/Research/presentation/winui/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/winui/index.html</guid>
      	<description>
	&lt;p&gt;&quot;By incorporating the Fluent Design System into all experiences, controls, and styles, WinUI provides consistent, intuitive, and accessible experiences using the latest user interface (UI) patterns. With support for both desktop and UWP apps, you can build with WinUI from the ground up, or gradually migrate your existing MFC, WinForms, or WPF apps using familiar languages such as C++, C#, Visual Basic, and Javascript (via React Native for Windows).&quot;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://microsoft.github.io/microsoft-ui-xaml/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://docs.microsoft.com/en-us/windows/apps/winui/&quot;&gt;Docs&lt;/a&gt; | &lt;a href=&quot;https://github.com/microsoft/microsoft-ui-xaml&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;hr&gt; 
&lt;p&gt;&lt;a href=&quot;https://dotmorten.github.io/WinUIEx/&quot;&gt;WinUIEx&lt;/a&gt;: A set of extension methods and classes to fill some gaps in WinUI 3, mostly around windowing and unit testing.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>XForms</title>
      <link>https://tedneward.github.io/Research/presentation/xforms/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/xforms/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/XForms&quot;&gt;Wikipedia&lt;/a&gt; | &lt;a href=&quot;http://www.w3.org/TR/xforms/&quot;&gt;XForms 1.1&lt;/a&gt; | &lt;a href=&quot;https://www.w3.org/community/xformsusers/wiki/XForms_2.0&quot;&gt;XForms 2.0 draft&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Zotonic</title>
      <link>https://tedneward.github.io/Research/presentation/zotonic/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/zotonic/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;http://zotonic.com/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/zotonic/zotonic&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Polymer (Project)</title>
      <link>https://tedneward.github.io/Research/presentation/webcomponents/polymer/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/webcomponents/polymer/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.polymer-project.org/&quot;&gt;Website&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Webix</title>
      <link>https://tedneward.github.io/Research/presentation/webix/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/webix/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://webix.com/&quot;&gt;Website&lt;/a&gt; | Commercial&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Wiki.js</title>
      <link>https://tedneward.github.io/Research/presentation/wikijs/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/wikijs/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://js.wiki/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/Requarks/wiki&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Wired Elements</title>
      <link>https://tedneward.github.io/Research/presentation/wiredjs/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/wiredjs/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://wiredjs.com/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/rough-stuff/wired-elements&quot;&gt;Source&lt;/a&gt; | &lt;a href=&quot;https://wiredjs.com/showcase&quot;&gt;Component Showcase&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Sandbox:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://codesandbox.io/s/react-wrapper-for-wired-elements-vid1j&quot;&gt;React&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://codesandbox.io/s/wired-elements-svelte-4hfkb&quot;&gt;Svelte&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://codesandbox.io/s/wired-elements-vanilla-4bpny&quot;&gt;Vanilla&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://codesandbox.io/s/vj389y9375&quot;&gt;Vue&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>XMLUI</title>
      <link>https://tedneward.github.io/Research/presentation/xmlui/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/xmlui/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.xmlui.org/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/xmlui-org/xmlui&quot;&gt;Source&lt;/a&gt; | &lt;a href=&quot;https://demo.xmlui.org/&quot;&gt;Demos&lt;/a&gt; | &lt;a href=&quot;https://docs.xmlui.org/&quot;&gt;Docs&lt;/a&gt;&lt;/p&gt; 
&lt;h2&gt;Reading&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://blog.jonudell.net/2025/07/18/introducing-xmlui/&quot;&gt;Introducing XMLUI&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://blog.xmlui.org/blog/improving-the-xmlui-mcp-server&quot;&gt;Improving the XMLUI MCP Server&lt;/a&gt; - &lt;a href=&quot;https://github.com/xmlui-org/xmlui-mcp&quot;&gt;Source&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Example&lt;/h2&gt; 
&lt;h3&gt;Getting Started&lt;/h3&gt; 
&lt;p&gt;The XMLUI engine is a single JS file. Here is the minimal XMLUI setup.&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;&amp;lt;your app folder&amp;gt;
index.html
Main.xmlui
xmlui
0.9.90.js
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;index.html&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;&amp;lt;!doctype html&amp;gt;
&amp;lt;html lang=&quot;en&quot;&amp;gt;
  &amp;lt;head&amp;gt;
    &amp;lt;meta charset=&quot;UTF-8&quot; /&amp;gt;
    &amp;lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot; /&amp;gt;
    &amp;lt;script src=&quot;xmlui/0.9.90.js&quot;&amp;gt;&amp;lt;/script&amp;gt;
  &amp;lt;/head&amp;gt;
  &amp;lt;body&amp;gt;
  &amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Main.xmlui&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;&amp;lt;App name=&quot;XMLUI Hello World&quot;&amp;gt;Hello World&amp;lt;/App&amp;gt;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Automatic reactivity&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;&amp;lt;App&amp;gt;
  &amp;lt;Select id=&quot;lines&quot; initialValue=&quot;bakerloo&quot;&amp;gt;
    &amp;lt;Items data=&quot;https://api.tfl.gov.uk/line/mode/tube/status&quot;&amp;gt;
        &amp;lt;Option value=&quot;{$item.id}&quot; label=&quot;{$item.name}&quot; /&amp;gt;
    &amp;lt;/Items&amp;gt;
  &amp;lt;/Select&amp;gt;
  &amp;lt;DataSource
    id=&quot;tubeStations&quot;
    url=&quot;https://api.tfl.gov.uk/Line/{lines.value}/Route/Sequence/inbound&quot;
    resultSelector=&quot;stations&quot;/&amp;gt;
  &amp;lt;Table data=&quot;{tubeStations}&quot; height=&quot;280px&quot;&amp;gt;
    &amp;lt;Column bindTo=&quot;name&quot; /&amp;gt;
    &amp;lt;Column bindTo=&quot;modes&quot; /&amp;gt;
  &amp;lt;/Table&amp;gt;
&amp;lt;/App&amp;gt;
&lt;/code&gt;&lt;/pre&gt; 
&lt;h2&gt;Components&lt;/h2&gt; 
&lt;p&gt;APICall, App, AppHeader, AppState, AutoComplete, Avatar, Backdrop, Badge, BarChart, Bookmark, Breakout, Button, CHStack, CVStack, Card, ChangeListener, Checkbox, ColorPicker, Column, ContentSeparator, DataSource, DatePicker, DonutChart, DropdownMenu, EmojiSelector, FileInput, FileUploadDropZone, FlowLayout, Footer, Form, FormItem, FormSection, Fragment, H1, H2, H3, H4, H5, H6, HSplitter, HStack, Heading, Icon, Image, Items, LabelList, Legend, LineChart, Link, List, Logo, Markdown, MenuItem, MenuSeparator, ModalDialog, NavGroup, NavLink, NavPanel, NoResult, NumberBox, Option, Page, PageMetaTitle, Pages, PasswordInput, PieChart, ProgressBar, Queue, RadioGroup, RealTimeAdapter, Redirect, Select, Slider, SpaceFiller, Spinner, Splitter, Stack, StickyBox, SubMenuItem, Switch, TabItem, Table, TableOfContents, Tabs, Text, TextArea, TextBox, Theme, ToneChangerButton, VSplitter, VStack&lt;/p&gt; 
&lt;p&gt;See the &lt;a href=&quot;https://docs.xmlui.org/components/_overview&quot;&gt;whole catalog&lt;/a&gt;.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Shoelace</title>
      <link>https://tedneward.github.io/Research/presentation/webcomponents/shoelace/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/webcomponents/shoelace/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://shoelace.style/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/shoelace-style/shoelace&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Builds on top of &lt;a href=&quot;/presentation/webcomponents&quot;&gt;Web Components&lt;/a&gt;.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>WebSharper</title>
      <link>https://tedneward.github.io/Research/presentation/websharper/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/websharper/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://websharper.com/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/dotnet-websharper&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;h3&gt;From the Documentation/Basics:&lt;/h3&gt; 
&lt;h4&gt;Hello World!&lt;/h4&gt; 
&lt;p&gt;With WebSharper you can develop pure JS/HTML, and single- and multi-page web applications with an optional server side, all in F#. Unless you are looking for low-level control, we recommend that you start by creating a sitelet.&lt;/p&gt; 
&lt;p&gt;The simplest sitelet serves text on a single endpoint at the root of the application:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;module YourApp

open WebSharper
open WebSharper.Sitelets

[&amp;lt;Website&amp;gt;]
let Main = Application.Text (fun ctx -&amp;gt; &quot;Hello World!&quot;)
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;&lt;img src=&quot;http://i.imgur.com/fZgqeKjm.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt; 
&lt;h4&gt;Single Page Applications&lt;/h4&gt; 
&lt;p&gt;While serving text is fun and often useful, going beyond isn’t any complicated. For instance, you can easily construct single-page applications:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;module YourApp

open WebSharper
open WebSharper.Sitelets
open WebSharper.UI.Html
open WebSharper.UI.Server

[&amp;lt;Website&amp;gt;]
let Main =
    Application.SinglePage (fun ctx -&amp;gt;
        Content.Page(
            h1 [] [text &quot;Hello World!&quot;]
        )
    )
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;This code creates an empty HTML document and inserts a header node.&lt;/p&gt; 
&lt;p&gt;&lt;img src=&quot;http://i.imgur.com/xYITvCqm.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt; 
&lt;h4&gt;HTML responses&lt;/h4&gt; 
&lt;p&gt;Pages are a special type of content responses, and you can easily finetune them by specifying where you want content to be added, by using an optional Title, Head, Body, and Doctype.&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;    ...
    Application.SinglePage (fun ctx -&amp;gt;
        Content.Page(
            Title = &quot;My Hello World app&quot;,
            Body = [
                h1 [text &quot;Hello World!&quot;]
            ],
            ...
        )
    )
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;You can construct HTML via the (soon legacy) WebSharper 3.x markup combinators in WebSharper.Html.Server and WebSharper.Html.Client (for client-side markup, see the section below), or using the next generation reactive HTML language from WebSharper UI (as above and in the examples on this page; formerly called UI.Next).&lt;/p&gt; 
&lt;h4&gt;Custom responses&lt;/h4&gt; 
&lt;p&gt;Content responses are asynchronous. Next to full HTML pages, you can return:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Plain text with &lt;code&gt;Content.Text&lt;/code&gt;:&lt;/li&gt; 
&lt;/ul&gt; 
&lt;pre&gt;&lt;code&gt;Content.Text &quot;Hello World!&quot;
&lt;/code&gt;&lt;/pre&gt; 
&lt;ul&gt; 
 &lt;li&gt;JSON values with &lt;code&gt;Content.Json&lt;/code&gt; (visit JSON documentation or JSON cheatsheet for more info):&lt;/li&gt; 
&lt;/ul&gt; 
&lt;pre&gt;&lt;code&gt;type Person = { First: string; Last: string; Age: int}

Content.Json { First=&quot;John&quot;; Last=&quot;Smith&quot;; Age=30 }
&lt;/code&gt;&lt;/pre&gt; 
&lt;ul&gt; 
 &lt;li&gt;Files with &lt;code&gt;Content.File&lt;/code&gt;:&lt;/li&gt; 
&lt;/ul&gt; 
&lt;pre&gt;&lt;code&gt;Content.File(&quot;Main.fs&quot;, ContentType=&quot;text/plain&quot;)
&lt;/code&gt;&lt;/pre&gt; 
&lt;ul&gt; 
 &lt;li&gt;Various error codes:&lt;/li&gt; 
&lt;/ul&gt; 
&lt;pre&gt;&lt;code&gt;Content.Unauthorized (401)
Content.Forbidden (403)
Content.NotFound (404)
Content.MethodNotAllowed (405)
Content.ServerError (500)
&lt;/code&gt;&lt;/pre&gt; 
&lt;ul&gt; 
 &lt;li&gt;You can also create your own custom error code response:&lt;/li&gt; 
&lt;/ul&gt; 
&lt;pre&gt;&lt;code&gt;Content.Custom(Status=Http.Status.Custom 402 (Some &quot;Payment Required&quot;))
&lt;/code&gt;&lt;/pre&gt; 
&lt;ul&gt; 
 &lt;li&gt;Any other custom content with &lt;code&gt;Content.Custom&lt;/code&gt;.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Multi-page applications&lt;/h4&gt; 
&lt;p&gt;Multi-page applications have multiple endpoints: pairs of HTTP verbs and paths, and are represented as an annotated union type we typically call Endpoints (or Action in previous terminology). The endpoints, as defined by this union type - given the various annotations on each union case - are mapped to content to be served using Application.MultiPage. Links to endpoints in your site can be calculated from the serving context, so you will never have invalid URLs.&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;module YourApp

open WebSharper
open WebSharper.Sitelets
open WebSharper.UI
open WebSharper.UI.Html
open WebSharper.UI.Server

type Endpoints =
    | [&amp;lt;EndPoint &quot;GET /&quot;&amp;gt;] Home
    | [&amp;lt;EndPoint &quot;GET /about&quot;&amp;gt;] About

[&amp;lt;Website&amp;gt;]
let Main =
    Application.MultiPage (fun ctx endpoint -&amp;gt;
        let (=&amp;gt;) label endpoint = a [attr.href (ctx.Link endpoint)] [text label]
        match endpoint with
        | Endpoints.Home -&amp;gt;
            Content.Page(
                Body = [
                    h1 [] [text &quot;Hello world!&quot;]
                    &quot;About&quot; =&amp;gt; Endpoints.About
                ]
            )
        | Endpoints.About -&amp;gt;
            Content.Page(
                Body = [
                    p [] [text &quot;This is a simple app&quot;]
                    &quot;Home&quot; =&amp;gt; Endpoints.Home
                ]
            )
    )
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;&lt;img src=&quot;http://i.imgur.com/WMnmzIPm.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt; 
&lt;h4&gt;Adding client-side functionality&lt;/h4&gt; 
&lt;p&gt;WebSharper applications can easily incorporate client-side content, expressed in F#, giving an absolute edge over any web development library. Just mark your client-side functions or modules with [&lt;javascript&gt;
  ] and embed them into server side markup using client. Server-side RPC functions are annotated with [
  &lt;rpc&gt;
   ].
  &lt;/rpc&gt;
 &lt;/javascript&gt;&lt;/p&gt; 
&lt;p&gt;The example below is reimplemented from the blog entry Deploying WebSharper apps to Azure via GitHub, also available in the main WebSharper templates, and although it omits the more advanced templating in that approach (which is straightforward to add to this implementation), it should give you an recipe for adding client-side functionality to your sitelets easily.&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;module YourApp

open WebSharper
open WebSharper.Sitelets
open WebSharper.UI
open WebSharper.UI.Html
open WebSharper.UI.Client

module Server =
    [&amp;lt;Rpc&amp;gt;]
    let DoWork (s: string) = 
        async {
            return System.String(List.ofSeq s |&amp;gt; List.rev |&amp;gt; Array.ofList)
        }

[&amp;lt;JavaScript&amp;gt;]
module Client =
    open WebSharper.JavaScript

    let Main () =
        let input = input [attr.value &quot;&quot;] []
        let output = h1 [] []
        div [
            input
            button [
                on.click (fun _ _ -&amp;gt;
                    async {
                        let! data = Server.DoWork input.Value
                        output.Text &amp;lt;- data
                    }
                    |&amp;gt; Async.Start
                )
            ] [text &quot;Send&quot;]
            hr [] []
            h4A [attr.``class`` &quot;text-muted&quot;] [text &quot;The server responded:&quot;]
            div [attr.``class`` &quot;jumbotron&quot;] [output]
        ]

open WebSharper.UI.Server

[&amp;lt;Website&amp;gt;]
let MySite =
    Application.SinglePage (fun ctx -&amp;gt;
        Content.Page(
            Body = [
                h1 [] [text &quot;Say Hi to the server&quot;]
                div [] [client &amp;lt;@ Client.Main() @&amp;gt;]
            ]
        )
    )
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;&lt;img src=&quot;http://i.imgur.com/9sPa4lzm.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt; 
&lt;h4&gt;Using JavaScript libraries&lt;/h4&gt; 
&lt;p&gt;WebSharper extensions bring JavaScript libraries to WebSharper. You can download extensions or develop your own using WIG, among others. Below is an example using WebSharper.Charting and chart.js underneath.&lt;/p&gt; 
&lt;p&gt;Note that these and any other dependencies you may be using will be automatically injected into a Content.Page or other sitelet HTML response, and you will never have to deal with them manually.&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;module YourApp

open WebSharper
open WebSharper.Sitelets
open WebSharper.UI
open WebSharper.UI.Html

[&amp;lt;JavaScript&amp;gt;]
module Client =
    open WebSharper.JavaScript
    open WebSharper.UI.Client
    open WebSharper.Charting

    let RadarChart () =
        let labels =    
            [| &quot;Eating&quot;; &quot;Drinking&quot;; &quot;Sleeping&quot;;
               &quot;Designing&quot;; &quot;Coding&quot;; &quot;Cycling&quot;; &quot;Running&quot; |]
        let data1 = [|28.0; 48.0; 40.0; 19.0; 96.0; 27.0; 100.0|]
        let data2 = [|65.0; 59.0; 90.0; 81.0; 56.0; 55.0; 40.0|]

        let ch =
            Chart.Combine [
                Chart.Radar(Seq.zip labels data1)
                    .WithFillColor(Color.Rgba(151, 187, 205, 0.2))
                    .WithStrokeColor(Color.Rgba(151, 187, 205, 1.))
                    .WithPointColor(Color.Rgba(151, 187, 205, 1.))

                Chart.Radar(Seq.zip labels data2)
                    .WithFillColor(Color.Rgba(220, 220, 220, 0.2))
                    .WithStrokeColor(Color.Rgba(220, 220, 220, 1.))
                    .WithPointColor(Color.Rgba(220, 220, 220, 1.))
            ]
        Renderers.ChartJs.Render(ch, Size = Size(400, 400))

open WebSharper.UI.Server

[&amp;lt;Website&amp;gt;]
let MySite =
    Application.SinglePage (fun ctx -&amp;gt;
        Content.Page(
            Body = [
                h1 [] [text &quot;Charts are easy with WebSharper Warp!&quot;]
                div [] [client &amp;lt;@ Client.RadarChart() @&amp;gt;]
            ])
    )
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;&lt;img src=&quot;http://i.imgur.com/9o7x2b1m.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Wikmd</title>
      <link>https://tedneward.github.io/Research/presentation/wikmd/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/wikmd/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://linbreux.github.io/wikmd/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/Linbreux/wikmd&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;h2&gt;Installation&lt;/h2&gt; 
&lt;h3&gt;Docker-Compose&lt;/h3&gt; 
&lt;pre&gt;&lt;code&gt;---
version: &quot;2.1&quot;
services:
  wikmd:
    image: linbreux/wikmd:latest
    container_name: wikmd
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=Europe/Paris
    volumes:
      - /path/to/wiki:/wiki
    ports:
      - 5000:5000
    restart: unless-stopped

&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;Docker (CLI)&lt;/h3&gt; 
&lt;pre&gt;&lt;code&gt;docker run -d \
  --name wikmd \
  -e TZ=Europe/Paris \
  -e PUID=1000 \
  -e PGID=1000 \
  -e WIKMD_LOGGING=1 `#optional` \
  -p 5000:5000 \
  -v /path/to/wiki:/wiki \
  --restart unless-stopped \
  linbreux/wikmd:latest

&lt;/code&gt;&lt;/pre&gt;
	</description>
    </item>
    <item>
      <title>wxWidgets</title>
      <link>https://tedneward.github.io/Research/presentation/wxwidgets/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/wxwidgets/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.wxwidgets.org/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/wxWidgets/wxWidgets&quot;&gt;Source&lt;/a&gt;: &quot;When installing wxWidgets on Windows or macOS, we always recommend building the library from source yourself, and only provide the source package for most platforms. On some platforms, we have provided a few pre-built binaries for convenience, but wxWidgets supports so many compilers on so many platforms, that we can’t provide binaries for all of them. On Linux, we recommend using the official wxGTK packages provided by each distribution, but newer packages are available.&quot;&lt;/p&gt; 
&lt;p&gt;It has popular language bindings for Python, Perl, Ruby and many other languages,&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Yet Another Multicolumn Layout (YAML)</title>
      <link>https://tedneward.github.io/Research/presentation/yaml/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/yaml/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;http://www.yaml.de/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/yamlcss/yaml&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>KickstandUI</title>
      <link>https://tedneward.github.io/Research/presentation/webcomponents/kickstand/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/webcomponents/kickstand/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://kickstand-ui.com/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/break-stuff/kickstand-ui&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Stencil</title>
      <link>https://tedneward.github.io/Research/presentation/webcomponents/stencil/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/webcomponents/stencil/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://stenciljs.com/docs/introduction&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/ionic-team/stencil&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Stencil uses TypeScript, JSX, and CSS to create standards-based Web Components that can be used to craft high quality component libraries, design systems, and applications.&lt;/p&gt; 
&lt;p&gt;Stencil generates standards-compliant Web Components that can work with popular frameworks right out of the box. In addition, Stencil can be used to generate framework native components that can be used just like any other components in your framework of choice. Stencil accomplishes this by wrapping your Web Components via Stencil&apos;s Output Target feature.&lt;/p&gt; 
&lt;p&gt;Example:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;import { Component, Prop, h } from &apos;@stencil/core&apos;;

@Component({
  tag: &apos;my-first-component&apos;,
})
export class MyComponent {

  // Indicate that name should be a public property on the component
  @Prop() name: string;

  render() {
    return (
      &amp;lt;p&amp;gt;
        My name is {this.name}
      &amp;lt;/p&amp;gt;
    );
  }
}
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Once compiled, this component can be used in HTML just like any other tag.&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;&amp;lt;my-first-component name=&quot;Max&quot;&amp;gt;&amp;lt;/my-first-component&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
	</description>
    </item>
    <item>
      <title>Apache Wicket</title>
      <link>https://tedneward.github.io/Research/presentation/wicket/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/wicket/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://wicket.apache.org/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;http://www.apache.org/dyn/closer.cgi/wicket/9.7.0&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;http://wicket.apache.org/learn/#guide&quot;&gt;Official Free Online Guide for Apache Wicket framework&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>WASM WinForms</title>
      <link>https://tedneward.github.io/Research/presentation/winformswasm/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/winformswasm/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/roozbehid/WasmWinforms&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Xamarin</title>
      <link>https://tedneward.github.io/Research/presentation/xamarin/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/xamarin/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://dotnet.microsoft.com/en-us/apps/xamarin&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://docs.microsoft.com/en-us/xamarin/&quot;&gt;Docs&lt;/a&gt; | &lt;a href=&quot;https://www.github.com/xamarin&quot;&gt;GitHub&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Xamarin has both native bindings to the underlying ecosystem (Xamarin.iOS for iOS and Xamarin.Android for Android) as well as a portable layer that abstracts away the underlying platform (Xamarin.Forms).&lt;/p&gt; 
&lt;h2&gt;Reading&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://developer.xamarin.com/guides/xamarin-forms/creating-mobile-apps-xamarin-forms/&quot;&gt;Creating Mobile Apps with Xamarin.Forms C#&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.packtpub.com/free-ebook/mastering-xamarin-ui-development-second-edition/9781788995511&quot;&gt;Mastering Xamarin UI Development, Second Edition&lt;/a&gt; (account required)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.syncfusion.com/ebooks/xamarin-forms-succinctly&quot;&gt;Xamarin.Forms Succinctly&lt;/a&gt;, &lt;a href=&quot;https://www.syncfusion.com/ebooks/xamarin_forms_for_mac_os_succinctly&quot;&gt;Xamarin.Forms for macOS Succinctly&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Xamarin iOS&lt;/h2&gt; 
&lt;h2&gt;Xamarin Android&lt;/h2&gt; 
&lt;h2&gt;Xamarin Forms&lt;/h2&gt;
	</description>
    </item>
    <item>
      <title>Yoga</title>
      <link>https://tedneward.github.io/Research/presentation/yoga/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/yoga/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.yogalayout.dev/&quot;&gt;Website&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Yoga is an embeddable layout system used in popular UI frameworks like React Native. Yoga itself is not a UI framework, and does not do any drawing itself. Yoga&apos;s only responsibility is determining the size and position of boxes.&lt;/p&gt; 
&lt;p&gt;Yoga supports a familiar subset of CSS, mostly focused on Flexbox. This gives users a familiar model, and enables sharing code between native platforms and the browser.&lt;/p&gt; 
&lt;p&gt;Yoga is written in C++, with a public C API. This allows Yoga to be used by a wide variety of languages, via both official and unofficial bindings.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Kivy</title>
      <link>https://tedneward.github.io/Research/presentation/python/kivy/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/python/kivy/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://kivy.org/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/kivy&quot;&gt;Source&lt;/a&gt; | &lt;a href=&quot;https://kivy.org/doc/stable/&quot;&gt;Docs&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Uses a &quot;design language&quot; (&lt;a href=&quot;https://kivy.org/doc/stable/guide/lang.html&quot;&gt;Kv Design Language&lt;/a&gt;) to separate code from layout:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;#:kivy 1.0

&amp;lt;Controller&amp;gt;:
    label_wid: my_custom_label

    BoxLayout:
        orientation: &apos;vertical&apos;
        padding: 20

        Button:
            text: &apos;My controller info is: &apos; + root.info
            on_press: root.do_action()

        Label:
            id: my_custom_label
            text: &apos;My label before button press&apos;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;... matched up with code...&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;import kivy
kivy.require(&apos;1.0.5&apos;)

from kivy.uix.floatlayout import FloatLayout
from kivy.app import App
from kivy.properties import ObjectProperty, StringProperty


class Controller(FloatLayout):
    &apos;&apos;&apos;Create a controller that receives a custom widget from the kv lang file.

    Add an action to be called from the kv lang file.
    &apos;&apos;&apos;
    label_wid = ObjectProperty()
    info = StringProperty()

    def do_action(self):
        self.label_wid.text = &apos;My label after button press&apos;
        self.info = &apos;New info text&apos;


class ControllerApp(App):

    def build(self):
        return Controller(info=&apos;Hello world&apos;)


if __name__ == &apos;__main__&apos;:
    ControllerApp().run()
&lt;/code&gt;&lt;/pre&gt;
	</description>
    </item>
    <item>
      <title>Qt</title>
      <link>https://tedneward.github.io/Research/presentation/qt/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/qt/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.qt.io/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://www.qt.io/download-open-source&quot;&gt;Open Source Website&lt;/a&gt; | &lt;a href=&quot;https://wiki.qt.io/Building_Qt_5_from_Git#Getting_the_source_code&quot;&gt;Source&lt;/a&gt; | &lt;a href=&quot;https://www.qt.io/download-qt-installer&quot;&gt;Qt Installer&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Railo</title>
      <link>https://tedneward.github.io/Research/presentation/railo/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/railo/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/getrailo/railo&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Appears to be abandoned--no new development since 2013 or so.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>React</title>
      <link>https://tedneward.github.io/Research/presentation/react/index/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/react/index/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://reactjs.org/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://reactjs.org/docs/getting-started.html&quot;&gt;Docs&lt;/a&gt; | &lt;a href=&quot;https://github.com/facebook/react/&quot;&gt;Source&lt;/a&gt; | &lt;a href=&quot;https://github.com/facebook/react/tree/main/compiler&quot;&gt;Compiler&lt;/a&gt;&lt;/p&gt; 
&lt;h3&gt;Reading&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://airbnb.io/javascript/react/&quot;&gt;Airbnb React/JSX Style Guide&lt;/a&gt; - Airbnb&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.hackingwithreact.com&quot;&gt;Hacking with React&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.digitalocean.com/community/books/how-to-code-in-react-js-ebook&quot;&gt;How To Code in React.js&lt;/a&gt; - Joe Morgan&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://code.tutsplus.com/tutorials/intro-to-the-react-framework--net-35660&quot;&gt;Intro to the React Framework&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://scotch.io/tutorials/learning-react-getting-started-and-concepts&quot;&gt;Learning React.js: Getting Started and Concepts&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/vasanthk/react-bits&quot;&gt;React-Bits&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/softchris/react-book/&quot;&gt;React Book, your beginner guide to React&lt;/a&gt; - Chris Noring&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.reactenlightenment.com&quot;&gt;React Enlightenment&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://developmentarc.gitbooks.io/react-indepth/content/&quot;&gt;React In-depth: An exploration of UI development&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://krasimir.gitbooks.io/react-in-patterns/content&quot;&gt;React in patterns&lt;/a&gt; - Krasimir Tsonev&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://goalkicker.com/ReactJSBook/&quot;&gt;React JS Notes for Professionals&lt;/a&gt; - Compiled from StackOverflow Documentation (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/mikechau/react-primer-draft&quot;&gt;React Primer Draft&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.syncfusion.com/ebooks/react-succinctly&quot;&gt;React Succinctly&lt;/a&gt; - Samer Buna&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://reactjs.org/tutorial/tutorial.html&quot;&gt;React Tutorial&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;React Tutorial by Josh Finnie&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.joshfinnie.com/blog/reactjs-tutorial-part-1/&quot;&gt;Part 1&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.joshfinnie.com/blog/reactjs-tutorial-part-2/&quot;&gt;Part 2&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.joshfinnie.com/blog/reactjs-tutorial-part-3/&quot;&gt;Part 3&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://reactjs.net/getting-started/aspnetcore.html&quot;&gt;React with ASP.NET Core Tutorial&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://codegeekz.com/react-js-tutorial/&quot;&gt;React.js Tutorial: Now is Your Time to Try It, Right in Your Browser&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://survivejs.com&quot;&gt;SurviveJS - Webpack and React&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://flaviocopes.com/page/react-handbook/&quot;&gt;The React Beginner&apos;s Handbook&lt;/a&gt; - Flavio Copes (PDF, EPUB, Kindle) &lt;em&gt;(email address requested)&lt;/em&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Supplementals&lt;/h2&gt; 
&lt;p&gt;&lt;a href=&quot;https://mobx.js.org/README.html&quot;&gt;MobX.js&lt;/a&gt;: Simple, scalable state management.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>ReactiveUI</title>
      <link>https://tedneward.github.io/Research/presentation/reactiveui/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/reactiveui/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.reactiveui.net/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/reactiveui&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;An advanced, composable, functional reactive model-view-viewmodel framework for all .NET platforms that is inspired by functional reactive programming. ReactiveUI allows you to abstract mutable state away from your user interfaces, express the idea around a feature in one readable place and improve the testability of your application.&lt;/p&gt; 
&lt;/blockquote&gt; 
&lt;p&gt;Includes the &lt;a href=&quot;../storage/akavache&quot;&gt;Akavache&lt;/a&gt; project&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://github.com/reactiveui/refit&quot;&gt;Refit&lt;/a&gt;: The automatic type-safe REST library for .NET Core, Xamarin and .NET. Heavily inspired by Square&apos;s Retrofit library, Refit turns your REST API into a live interface.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Rete.js</title>
      <link>https://tedneward.github.io/Research/presentation/retejs/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/retejs/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://retejs.org/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/retejs/rete&quot;&gt;Source&lt;/a&gt; | &lt;a href=&quot;https://retejs.org/docs/development/rete-kit&quot;&gt;Docs&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Sciter</title>
      <link>https://tedneward.github.io/Research/presentation/sciter/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/sciter/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://sciter.com/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/c-smile/sciter-sdk&quot;&gt;Github&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;C-based API. &lt;a href=&quot;https://sciter.com/hello-cpp-tutorial/&quot;&gt;C++ Tutorial&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Used to be built with &lt;a href=&quot;/languaes/tiscript&quot;&gt;TIScript&lt;/a&gt;&lt;/p&gt; 
&lt;h2&gt;Apps built with Sciter&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://notes.sciter.com/&quot;&gt;Sciter Notes&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Sequential Workflow Designer</title>
      <link>https://tedneward.github.io/Research/presentation/sequential-workflow-designer/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/sequential-workflow-designer/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://nocode-js.com/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/nocode-js/sequential-workflow-designer&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Works with &lt;a href=&quot;https://github.com/nocode-js/sequential-workflow-machine&quot;&gt;Sequential Workflow Machine&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>SiteJS</title>
      <link>https://tedneward.github.io/Research/presentation/sitejs/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/sitejs/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://sitejs.org/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/small-tech/site.js&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;The Small Web is for people (not startups, enterprises, or governments). One person. One server. One site. Develop, test, sync, and deploy (using a single tool that comes in a single binary). Comes bundled with &lt;a href=&quot;../hugo&quot;&gt;Hugo&lt;/a&gt;. Dynamic sites use DotJS (&quot;PHP-like simplicity in JavaScript using .js files&quot;), and includes WebSockets support as well. Comes bundled with &lt;a href=&quot;../../storage/jsdb&quot;&gt;JavaScript Database (JSDB)&lt;/a&gt; built into it.&lt;/p&gt; 
&lt;/blockquote&gt;
	</description>
    </item>
    <item>
      <title>SolidJS</title>
      <link>https://tedneward.github.io/Research/presentation/solidjs/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/solidjs/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.solidjs.com/&quot;&gt;Website&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>StillJs</title>
      <link>https://tedneward.github.io/Research/presentation/stilljs/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/stilljs/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://stilljs.dev/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/still-js&quot;&gt;Source&lt;/a&gt; | &lt;a href=&quot;https://github.com/still-js/samples&quot;&gt;Samples&lt;/a&gt;&lt;/p&gt; 
&lt;h2&gt;Reading&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://thenewstack.io/tired-of-javascript-framework-complexity-meet-still-js/&quot;&gt;https://thenewstack.io/tired-of-javascript-framework-complexity-meet-still-js/&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Taipy</title>
      <link>https://tedneward.github.io/Research/presentation/taipy/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/taipy/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://taipy.io/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/Avaiga/taipy&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://taipy.io/enterprise&quot;&gt;Taipy Designer&lt;/a&gt; (Commercial)&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Tiddlywiki</title>
      <link>https://tedneward.github.io/Research/presentation/tiddlywiki/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/tiddlywiki/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://tiddlywiki.com/&quot;&gt;Website/Demo&lt;/a&gt; | &lt;a href=&quot;https://github.com/TiddlyWiki/TiddlyWiki5&quot;&gt;Source&lt;/a&gt; | &lt;a href=&quot;https://tiddlywiki.com/#TiddlyDesktop&quot;&gt;Desktop&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;TiddlyWiki is a complete interactive wiki in JavaScript. It can be used as a single HTML file in the browser or as a powerful Node.js application. It is highly customisable: the entire user interface is itself implemented in hackable WikiText.&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://kookma.github.io/TW-Scripts/&quot;&gt;Scripts in TiddlyWiki&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;It can be run client-server mode in nodejs:&lt;/p&gt; 
&lt;h1&gt;&lt;a href=&quot;https://github.com/TiddlyWiki/TiddlyWiki5?tab=readme-ov-file#installing-tiddlywiki-on-nodejs&quot;&gt;Installing TiddlyWiki on Node.js&lt;/a&gt;&lt;/h1&gt; 
&lt;p&gt;TiddlyWiki is a &lt;a href=&quot;https://tiddlywiki.com/static/SingleFileApplication.html&quot;&gt;SingleFileApplication&lt;/a&gt;, which is easy to use. For advanced users and developers there is a possibility to use a Node.js client / server configuration. This configuration is also used to build the TiddlyWiki &lt;a href=&quot;https://tiddlywiki.com/static/SinglePageApplication.html&quot;&gt;SinglePageApplication&lt;/a&gt;&lt;/p&gt; 
&lt;ol&gt; 
 &lt;li&gt;Install &lt;a href=&quot;https://tiddlywiki.com/static/Node.js.html&quot;&gt;Node.js&lt;/a&gt; 
  &lt;ul&gt; 
   &lt;li&gt;Linux: 
    &lt;blockquote&gt; 
     &lt;p&gt;&lt;em&gt;Debian/Ubuntu&lt;/em&gt;:&lt;br&gt; &lt;code&gt;apt install nodejs&lt;/code&gt;&lt;br&gt; May need to be followed up by:&lt;br&gt; &lt;code&gt;apt install npm&lt;/code&gt;&lt;/p&gt; 
     &lt;p&gt;&lt;em&gt;Arch Linux&lt;/em&gt;&lt;br&gt; &lt;code&gt;yay -S tiddlywiki&lt;/code&gt;&lt;br&gt; (installs node and tiddlywiki)&lt;/p&gt; 
    &lt;/blockquote&gt; &lt;/li&gt; 
   &lt;li&gt;Mac 
    &lt;blockquote&gt; 
     &lt;p&gt;&lt;code&gt;brew install node&lt;/code&gt;&lt;/p&gt; 
    &lt;/blockquote&gt; &lt;/li&gt; 
   &lt;li&gt;Android 
    &lt;blockquote&gt; 
     &lt;p&gt;&lt;a href=&quot;https://tiddlywiki.com/static/Serving%2520TW5%2520from%2520Android.html&quot;&gt;Termux for Android&lt;/a&gt;&lt;/p&gt; 
    &lt;/blockquote&gt; &lt;/li&gt; 
   &lt;li&gt;Other 
    &lt;blockquote&gt; 
     &lt;p&gt;See &lt;a href=&quot;http://nodejs.org/&quot;&gt;http://nodejs.org&lt;/a&gt;&lt;/p&gt; 
    &lt;/blockquote&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Open a command line terminal and type: 
  &lt;blockquote&gt; 
   &lt;p&gt;&lt;code&gt;npm install -g tiddlywiki&lt;/code&gt;&lt;/p&gt; 
   &lt;p&gt;If it fails with an error you may need to re-run the command as an administrator:&lt;/p&gt; 
   &lt;p&gt;&lt;code&gt;sudo npm install -g tiddlywiki&lt;/code&gt; (Mac/Linux)&lt;/p&gt; 
  &lt;/blockquote&gt; &lt;/li&gt; 
 &lt;li&gt;Ensure TiddlyWiki is installed by typing: 
  &lt;blockquote&gt; 
   &lt;p&gt;&lt;code&gt;tiddlywiki --version&lt;/code&gt;&lt;/p&gt; 
  &lt;/blockquote&gt; 
  &lt;ul&gt; 
   &lt;li&gt;In response, you should see &lt;a href=&quot;https://tiddlywiki.com/static/TiddlyWiki.html&quot;&gt;TiddlyWiki&lt;/a&gt; report its current version (eg &quot;5.3.8&quot;. You may also see other debugging information reported.)&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;Try it out: 
  &lt;ol&gt; 
   &lt;li&gt;&lt;code&gt;tiddlywiki mynewwiki --init server&lt;/code&gt; to create a folder for a new wiki that includes server-related components&lt;/li&gt; 
   &lt;li&gt;&lt;code&gt;tiddlywiki mynewwiki --listen&lt;/code&gt; to start &lt;a href=&quot;https://tiddlywiki.com/static/TiddlyWiki.html&quot;&gt;TiddlyWiki&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;Visit &lt;a href=&quot;http://127.0.0.1:8080/&quot;&gt;http://127.0.0.1:8080/&lt;/a&gt; in your browser&lt;/li&gt; 
   &lt;li&gt;Try editing and creating tiddlers&lt;/li&gt; 
  &lt;/ol&gt; &lt;/li&gt; 
 &lt;li&gt;Optionally, make an offline copy: 
  &lt;ul&gt; 
   &lt;li&gt;click the &lt;strong&gt;save changes&lt;/strong&gt; button in the sidebar, &lt;strong&gt;OR&lt;/strong&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;code&gt;tiddlywiki mynewwiki --build index&lt;/code&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ol&gt; 
&lt;p&gt;The &lt;code&gt;-g&lt;/code&gt; flag causes &lt;a href=&quot;https://tiddlywiki.com/static/TiddlyWiki.html&quot;&gt;TiddlyWiki&lt;/a&gt; to be installed globally. Without it, &lt;a href=&quot;https://tiddlywiki.com/static/TiddlyWiki.html&quot;&gt;TiddlyWiki&lt;/a&gt; will only be available in the directory where you installed it.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Warning&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;If you are using Debian or Debian-based Linux and you are receiving a &lt;code&gt;node: command not found&lt;/code&gt; error though node.js package is installed, you may need to create a symbolic link between &lt;code&gt;nodejs&lt;/code&gt; and &lt;code&gt;node&lt;/code&gt;. Consult your distro&apos;s manual and &lt;code&gt;whereis&lt;/code&gt; to correctly create a link. See github &lt;a href=&quot;http://github.com/TiddlyWiki/TiddlyWiki5/issues/1434&quot;&gt;issue 1434&lt;/a&gt;.&lt;/p&gt; 
&lt;p&gt;Example Debian v8.0: &lt;code&gt;sudo ln -s /usr/bin/nodejs /usr/bin/node&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Tip&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;You can also install prior versions like this:&lt;br&gt; &lt;code&gt;npm install -g tiddlywiki@5.1.13&lt;/code&gt;&lt;/p&gt; 
&lt;hr&gt; 
&lt;h2&gt;&lt;a href=&quot;https://tiddlywiki.com/#Community&quot;&gt;Community Resources&lt;/a&gt;&lt;/h2&gt; 
&lt;h3&gt;&lt;a href=&quot;https://tiddlywiki.com/#Saving%20to%20a%20Git%20service&quot;&gt;Saving to a Git service&lt;/a&gt;&lt;/h3&gt; 
&lt;p&gt;Saving to a Git service is configured in the $:/ControlPanel in the Git Service Saver tab under the Saving tab. The following settings are supported:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Type - (mandatory) the type of the service (e.g. GitHub, GitLab)&lt;/li&gt; 
 &lt;li&gt;Username - (mandatory) the username for the Git service account used for saving changes&lt;/li&gt; 
 &lt;li&gt;Password - (mandatory) the OAUTH token or personal access token for the specified account. Note that GitHub deprecated password authentication, permitted authentication methods are shown in the API documentation.&lt;/li&gt; 
 &lt;li&gt;Repository - (mandatory) the name of the Git repository. Both the owner name and the repository name must be specified. For example Jermolene/TiddlyWiki5&lt;/li&gt; 
 &lt;li&gt;Branch - (optional) the name of the branch to be used within the Git repository. Defaults to main (GitHub) or master (GitLab)&quot;&lt;/li&gt; 
 &lt;li&gt;Path - (optional) the path to the target file. Defaults to /&lt;/li&gt; 
 &lt;li&gt;Filename - (mandatory) the filename of the target file&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;&lt;a href=&quot;https://tiddlywiki.com/#GitHub%20Saver%20Tutorial%20by%20Mohammad&quot;&gt;GitHub Saver Tutorial by Mohammad&lt;/a&gt;&lt;/h3&gt; 
&lt;p&gt;GitHub Saver is a step by step tutorial that shows how to integrate Tiddlywiki 5 and GitHub Pages to create websites hosted on &lt;a href=&quot;https://github.com/&quot;&gt;https://github.com/&lt;/a&gt;.&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://kookma.github.io/TW5-GitHub-Saver/&quot;&gt;https://kookma.github.io/TW5-GitHub-Saver/&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;This instruction is based on Tiddlywiki single html file model, while it can use subfolder for extra materials like images, audios, videos, pdfs,... in separate folders.&lt;/p&gt; 
&lt;p&gt;Other tutorials&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt; &lt;p&gt;Tiddlywiki, Travis-CI and GitHub Pages&lt;/p&gt; &lt;p&gt;&lt;a href=&quot;https://kookma.github.io/Tiddlywiki-Travis-CI/&quot;&gt;https://kookma.github.io/Tiddlywiki-Travis-CI/&lt;/a&gt;&lt;/p&gt; &lt;p&gt;This wiki shows how to set up websites hosted on GitHub Pages using Travis-CI and Tiddlywiki 5 on Node.js.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Tiddlywiki and GitHub Pages&lt;/p&gt; &lt;p&gt;&lt;a href=&quot;https://kookma.github.io/Tiddlywiki-and-GitHub-Pages/&quot;&gt;https://kookma.github.io/Tiddlywiki-and-GitHub-Pages/&lt;/a&gt;&lt;/p&gt; &lt;p&gt;This instruction is based on local edit, save and push to GitHub. It does NOT use the new GitHub Saver mechanism (requires TW 5.1.20+) which lets edit and save directly from Tiddlywiki!&lt;/p&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;&lt;a href=&quot;https://tiddly.packett.cool/&quot;&gt;TiddlyPWA&lt;/a&gt;&lt;/h3&gt; 
&lt;p&gt;&lt;a href=&quot;https://codeberg.org/valpackett/tiddlypwa&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Runs TW as a progressive web app. Secure offline storage and cross-device synchronization solution for TiddlyWiki 5.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>TogetherJS</title>
      <link>https://tedneward.github.io/Research/presentation/togetherjs/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/togetherjs/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://togetherjs.com/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/mozilla/togetherjs&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Some built=in features:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Audio chat: TogetherJS uses Web RTC technology to enhance communication for your users.&lt;/li&gt; 
 &lt;li&gt;User focus: Your users see each other&apos;s mouse cursors and clicks.&lt;/li&gt; 
 &lt;li&gt;User presence: TogetherJS enables your users to see each other in real time.&lt;/li&gt; 
 &lt;li&gt;Text chat: Your users can chat with each other with familiar instant messaging.&lt;/li&gt; 
 &lt;li&gt;Co-browsing: Your users can follow each other to different pages on the same domain.&lt;/li&gt; 
 &lt;li&gt;Real time content sync: Your users can see content on a site or app dynamically change together.&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Ultralight</title>
      <link>https://tedneward.github.io/Research/presentation/ultralight/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/ultralight/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://ultralig.ht/&quot;&gt;Website&lt;/a&gt; | Commercial/closed-source&lt;/p&gt; 
&lt;p&gt;Pros: battle tested / production ready, html/css/js, good documentation and multiple samples, supports both application and game scenarios (render to texture)&lt;br&gt; Cons: non-platform theme (expected with css), usual overhead of js &amp;lt;-&amp;gt; c++ integration&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Vanilla</title>
      <link>https://tedneward.github.io/Research/presentation/vanilla/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/vanilla/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://vanillaforums.com/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/vanilla/vanilla&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Vue</title>
      <link>https://tedneward.github.io/Research/presentation/vue/index/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/vue/index/index.html</guid>
      	<description>
	&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.newline.co/30-days-of-vue&quot;&gt;30 Days Of Vue&lt;/a&gt; - Hassan Djirdeh (HTML; &lt;em&gt;email required for PDF&lt;/em&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://riptutorial.com/Download/vue-js.pdf&quot;&gt;Learning Vue.js&lt;/a&gt; (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://flaviocopes.nyc3.digitaloceanspaces.com/vue-handbook/vue-handbook.pdf&quot;&gt;The Vue.js Handbook&lt;/a&gt; - Flavio Copes (PDF)&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>NiceGUI</title>
      <link>https://tedneward.github.io/Research/presentation/python/nicegui/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/python/nicegui/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://nicegui.io/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/zauberzeug/nicegui&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Create web-based user interfaces with Python. &quot;The nice way.&quot;&lt;/p&gt; 
&lt;p&gt;NiceGUI is an easy-to-use, Python-based UI framework, which shows up in your web browser. You can create buttons, dialogs, Markdown, 3D scenes, plots and much more.&lt;/p&gt; 
&lt;p&gt;It is great for micro web apps, dashboards, robotics projects, smart home solutions and similar use cases. You can also use it in development, for example when tweaking/configuring a machine learning algorithm or tuning motor controllers.&lt;/p&gt; 
&lt;h4&gt;Installation&lt;/h4&gt; 
&lt;p&gt;&lt;code&gt;python3 -m pip install nicegui&lt;/code&gt;&lt;/p&gt; 
&lt;h4&gt;Usage&lt;/h4&gt; 
&lt;p&gt;Write your nice GUI in a file main.py:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;from nicegui import ui

ui.label(&apos;Hello NiceGUI!&apos;)
ui.button(&apos;BUTTON&apos;, on_click=lambda: ui.notify(&apos;button was pressed&apos;))

ui.run()
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Launch it with:&lt;/p&gt; 
&lt;p&gt;&lt;code&gt;python3 main.py&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;The GUI is now available through &lt;a href=&quot;http://localhost:8080/&quot;&gt;http://localhost:8080/&lt;/a&gt; in your browser. Note: NiceGUI will automatically reload the page when you modify the code.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Quarto</title>
      <link>https://tedneward.github.io/Research/presentation/quarto/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/quarto/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://quarto.org/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://quarto.org/docs/get-started/&quot;&gt;Getting Started&lt;/a&gt;&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Author using Jupyter notebooks or with plain text markdown in your favorite editor.&lt;/li&gt; 
 &lt;li&gt;Create dynamic content with Python, R, Julia, and Observable.&lt;/li&gt; 
 &lt;li&gt;Publish reproducible, production quality articles, presentations, dashboards, websites, blogs, and books in HTML, PDF, MS Word, ePub, and more.&lt;/li&gt; 
 &lt;li&gt;Share knowledge and insights organization-wide by publishing to Posit Connect, Confluence, or other publishing systems.&lt;/li&gt; 
 &lt;li&gt;Write using Pandoc markdown, including equations, citations, crossrefs, figure panels, callouts, advanced layout, and more.&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Ratchet</title>
      <link>https://tedneward.github.io/Research/presentation/ratchet/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/ratchet/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;http://goratchet.com/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/twbs/ratchet&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Built by Twitter?&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>React Native</title>
      <link>https://tedneward.github.io/Research/presentation/react/native/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/react/native/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://reactnative.dev/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/facebook/react-native&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;h3&gt;Reading&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://leanpub.com/programming-react-native&quot;&gt;Programming React Native&lt;/a&gt; &lt;em&gt;(Leanpub account or valid email requested)&lt;/em&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://browniefed.com/react-native-animation-book/&quot;&gt;React Native Animation Book&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.reactnativeexpress.com&quot;&gt;React Native Express&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://goalkicker.com/ReactNativeBook&quot;&gt;React Native Notes for Professionals&lt;/a&gt; - Compiled from StackOverflow documentation (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.gitbook.com/book/unbug/react-native-training/details&quot;&gt;React Native Training&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Refactoring to HTML</title>
      <link>https://tedneward.github.io/Research/presentation/refactoring-to-html/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/refactoring-to-html/index.html</guid>
      	<description>
	&lt;p&gt;&lt;em&gt;(by Elliott Rusty Harold (Addison-Wesley, 2008, ISBN-13 978-0-321-50363-3))&lt;/em&gt;&lt;/p&gt; 
&lt;h1&gt;Well-Formedness&lt;/h1&gt; 
&lt;ul&gt; 
 &lt;li&gt;Change Name to Lowercase (69)&lt;/li&gt; 
 &lt;li&gt;Quote Attribute Value (73)&lt;/li&gt; 
 &lt;li&gt;Fill In Omitted Attribute Value (76)&lt;/li&gt; 
 &lt;li&gt;Replace Empty Tag with Empty-Element Tag (78)&lt;/li&gt; 
 &lt;li&gt;Add End-tag (82)&lt;/li&gt; 
 &lt;li&gt;Remove Overlap (86)&lt;/li&gt; 
 &lt;li&gt;Convert Text to UTF-8 (89)&lt;/li&gt; 
 &lt;li&gt;Escape Less-Than Sign (91)&lt;/li&gt; 
 &lt;li&gt;Escape Ampersand (93)&lt;/li&gt; 
 &lt;li&gt;Escape Quotation Marks in Attribute Values (96)&lt;/li&gt; 
 &lt;li&gt;Introduce an XHTML DOCTYPE Declaration (98)&lt;/li&gt; 
 &lt;li&gt;Terminate Each Entity Reference (101)&lt;/li&gt; 
 &lt;li&gt;Replace Imaginary Entity References (102)&lt;/li&gt; 
 &lt;li&gt;Introduce a Root Element (103)&lt;/li&gt; 
 &lt;li&gt;Introduce the XHTML Namespace (104)&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h1&gt;Validity&lt;/h1&gt; 
&lt;ul&gt; 
 &lt;li&gt;Introduce a Transitional DOCTYPE Declaration&lt;/li&gt; 
 &lt;li&gt;Remove all Nonexistent Tags&lt;/li&gt; 
 &lt;li&gt;Add an alt Attribute&lt;/li&gt; 
 &lt;li&gt;Replace embed with object&lt;/li&gt; 
 &lt;li&gt;Introduce a Strict DOCTYPE Declaration&lt;/li&gt; 
 &lt;li&gt;Replace center with CSS&lt;/li&gt; 
 &lt;li&gt;Replace font with CSS&lt;/li&gt; 
 &lt;li&gt;Replace i with em or CSS&lt;/li&gt; 
 &lt;li&gt;Replace b with strong or CSS&lt;/li&gt; 
 &lt;li&gt;Replace the color Attribute with CSS&lt;/li&gt; 
 &lt;li&gt;Convert img Attributes to CSS&lt;/li&gt; 
 &lt;li&gt;Replace applet with object&lt;/li&gt; 
 &lt;li&gt;Replace Presentational Elements with CSS&lt;/li&gt; 
 &lt;li&gt;Nest Inline Elements inside Block Elements&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h1&gt;Layout&lt;/h1&gt; 
&lt;ul&gt; 
 &lt;li&gt;Replace Table Layouts&lt;/li&gt; 
 &lt;li&gt;Replace Frames with CSS Positions&lt;/li&gt; 
 &lt;li&gt;Move Content to the Front&lt;/li&gt; 
 &lt;li&gt;Mark up Lists as Lists&lt;/li&gt; 
 &lt;li&gt;Replace blockquote/ul Indentation with CSS&lt;/li&gt; 
 &lt;li&gt;Replace Spacer GIFs&lt;/li&gt; 
 &lt;li&gt;Add an ID Attribute&lt;/li&gt; 
 &lt;li&gt;Add Width and Height to an Image&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h1&gt;Accessibility&lt;/h1&gt; 
&lt;ul&gt; 
 &lt;li&gt;Convert Images to Text&lt;/li&gt; 
 &lt;li&gt;Add Labels to Form Input&lt;/li&gt; 
 &lt;li&gt;Introduce Standard Field Names&lt;/li&gt; 
 &lt;li&gt;Turn on Autocomplete&lt;/li&gt; 
 &lt;li&gt;Add Tab Indexes to Forms&lt;/li&gt; 
 &lt;li&gt;Introduce Skip Navigation&lt;/li&gt; 
 &lt;li&gt;Add Internal Headings&lt;/li&gt; 
 &lt;li&gt;Move Unique Content to the Front of Links and Headlines&lt;/li&gt; 
 &lt;li&gt;Make the Input Field Bigger&lt;/li&gt; 
 &lt;li&gt;Introduce Table Descriptions&lt;/li&gt; 
 &lt;li&gt;Introduce Acronym Elements&lt;/li&gt; 
 &lt;li&gt;Introduce lang Attributes&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h1&gt;Web Applications&lt;/h1&gt; 
&lt;ul&gt; 
 &lt;li&gt;Replace Unsafe GET with POST&lt;/li&gt; 
 &lt;li&gt;Replace Safe POST with GET&lt;/li&gt; 
 &lt;li&gt;Redirect POST to GET&lt;/li&gt; 
 &lt;li&gt;Enable Caching&lt;/li&gt; 
 &lt;li&gt;Prevent Caching&lt;/li&gt; 
 &lt;li&gt;Introduce ETag&lt;/li&gt; 
 &lt;li&gt;Replace Flash with HTML&lt;/li&gt; 
 &lt;li&gt;Add Web Forms 2.0 Types&lt;/li&gt; 
 &lt;li&gt;Replace Contact Forms with mailto Links&lt;/li&gt; 
 &lt;li&gt;Block Robots&lt;/li&gt; 
 &lt;li&gt;Escape User Input&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h1&gt;Content&lt;/h1&gt; 
&lt;ul&gt; 
 &lt;li&gt;Correct Spelling&lt;/li&gt; 
 &lt;li&gt;Repair Broken Links&lt;/li&gt; 
 &lt;li&gt;Remove the Entry Page&lt;/li&gt; 
 &lt;li&gt;Hide E-mail Addresses&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>RevealJS</title>
      <link>https://tedneward.github.io/Research/presentation/revealjs/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/revealjs/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://revealjs.com/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/hakimel/reveal.js&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Scratch</title>
      <link>https://tedneward.github.io/Research/presentation/scratch/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/scratch/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://scratch.mit.edu/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/LLK/scratch-blocks&quot;&gt;Source&lt;/a&gt; | &lt;a href=&quot;https://github.com/LLK/scratch-www&quot;&gt;Scratch-WWW&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://scratch.mit.edu/developers&quot;&gt;Scratch for developers&lt;/a&gt;&lt;/p&gt; 
&lt;h2&gt;Learning Principles&lt;/h2&gt; 
&lt;h3&gt;Projects&lt;/h3&gt; 
&lt;p&gt;People learn best when they are actively working on projects — generating new ideas, designing prototypes, making improvements and creating final products.&lt;/p&gt; 
&lt;h3&gt;Passion&lt;/h3&gt; 
&lt;p&gt;When people focus on things they care about, they work longer and harder, persist in the face of challenges, and learn more in the process.&lt;/p&gt; 
&lt;h3&gt;Peers&lt;/h3&gt; 
&lt;p&gt;Learning flourishes as a social activity, with people sharing ideas, collaborating on projects, and building on one another&apos;s work.&lt;/p&gt; 
&lt;h3&gt;Play&lt;/h3&gt; 
&lt;p&gt;Learning involves playful experimentation — trying new things, tinkering with materials, testing boundaries, taking risks, iterating again and again.&lt;/p&gt; 
&lt;h2&gt;Design Principles&lt;/h2&gt; 
&lt;h3&gt;Low Floor &amp;amp; Wide Walls&lt;/h3&gt; 
&lt;p&gt;In order to encourage a varied and diverse set of interactions, we explicitly include elements and features that are easy for kids to understand (low floor), but general enough to support diverse uses (wide walls).&lt;/p&gt; 
&lt;h3&gt;Make it as Simple as Possible — And Maybe Even Simpler&lt;/h3&gt; 
&lt;p&gt;Despite the common drive to add more features to software products, we have found that reducing the number of features often improves the user experience. What initially seems like a constraint or limitation can foster new forms of creativity.&lt;/p&gt; 
&lt;h3&gt;Many Paths, Many Styles&lt;/h3&gt; 
&lt;p&gt;Many math and science activities have traditionally been biased towards specific populations. By paying special attention to creating accessible and appealing technologies, we are working to close the gap.&lt;/p&gt; 
&lt;h3&gt;Design for Tinkerability&lt;/h3&gt; 
&lt;p&gt;We believe that the learning process is inherently iterative. Tinkerers start by exploring and experimenting, then revising and refining their goals and creations. To support this style of interaction, we design our interfaces to encourage quick experimentation and rapid cycles of iteration.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Server-Driven UI (SDUI)</title>
      <link>https://tedneward.github.io/Research/presentation/server-driven-ui/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/server-driven-ui/index.html</guid>
      	<description>
	&lt;h2&gt;Implementations&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/csmets/Server-Driven-UI&quot;&gt;https://github.com/csmets/Server-Driven-UI&lt;/a&gt;: A framework example for Server Driven UI (SDUI) that teaches you the best practices to scale. &lt;a href=&quot;https://github.com/csmets/Server-Driven-UI/blob/master/docs/README.md&quot;&gt;Docs&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Reading&lt;/h2&gt; 
&lt;h3&gt;Articles&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.apollographql.com/docs/graphos/schema-design/guides/sdui/basics&quot;&gt;Server-Driven UI Basics&lt;/a&gt;: From a GraphQL vendor.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://engineeringblog.yelp.com/2024/03/chaos-yelps-unified-framework-for-server-driven-ui.html&quot;&gt;CHAOS: Yelp&apos;s Unified Framework for Server-Driven UI&lt;/a&gt;: &quot;In late 2021, we began building a unified SDUI framework called CHAOS or “Content Hosting Architecture with Optimization Strategies”.&quot;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://getstream.io/blog/server-driven-compose-firebase/&quot;&gt;Design Server-Driven UI with Jetpack Compose and Firebase&lt;/a&gt; &lt;a href=&quot;https://github.com/skydoves/server-driven-compose&quot;&gt;Source&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Skeleton</title>
      <link>https://tedneward.github.io/Research/presentation/skeleton/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/skeleton/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;http://getskeleton.com/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/dhg/Skeleton&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Spice</title>
      <link>https://tedneward.github.io/Research/presentation/spice/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/spice/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/jonathanpeppers/spice&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>SuperCollider</title>
      <link>https://tedneward.github.io/Research/presentation/supercollider/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/supercollider/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://supercollider.github.io/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/supercollider/supercollider&quot;&gt;Source&lt;/a&gt; | &lt;a href=&quot;https://docs.supercollider.online/Tutorials/Getting-Started/01-Introductory-Remarks.html&quot;&gt;sclang Tutorial&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;SuperCollider is actually three programs:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;The text editor you are looking at (also referred to as the IDE or Integrated Development Environment),&lt;/li&gt; 
 &lt;li&gt;the language (sclang or the &quot;client&quot; app),&lt;/li&gt; 
 &lt;li&gt;and the server, which does the actual synthesis and calculation of audio.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;The sclang part is a sophisticated programming language with nice features for building GUIs (Graphical User Interfaces); and the server part is a lean, mean, efficient UNIX command line application (meaning it runs without any GUI representation).&lt;/p&gt; 
&lt;p&gt;They communicate by a protocol called OSC (Open Sound Control), over either UDP (User Datagram Protocol) or TCP (Transmission Control Protocol), which are network protocols also used on the internet. Because the client and server communicate this way, more advanced projects might run them on separate computers for performance reasons. In fact, it&apos;s even possible that they could be running in different parts of the world! However, just because these two applications communicate using common internet protocols does not mean they must be connected to the internet or on different computers. Most of the time they will be running on the same computer, and the &quot;networking&quot; aspect of things will be relatively transparent for you. Especially while you&apos;re still getting started.&lt;/p&gt; 
&lt;p&gt;You can only communicate with the server using OSC messages over the network, but luckily the language app has lots of powerful objects which represent things on the server and allow you to control them easily and elegantly.&lt;/p&gt; 
&lt;h2&gt;Examples&lt;/h2&gt; 
&lt;p&gt;Hello, world&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;&quot;Hello World!&quot;.postln;
&lt;/code&gt;&lt;/pre&gt;
	</description>
    </item>
    <item>
      <title>Tauri</title>
      <link>https://tedneward.github.io/Research/presentation/tauri/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/tauri/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://tauri.studio/en/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/tauri-apps/tauri&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Looks to be a competitor to Electron but aiming to be pluggable in a number of places (which I&apos;m not sure is a win).&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>TinyWiki</title>
      <link>https://tedneward.github.io/Research/presentation/tinywiki/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/tinywiki/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/Kartones/tiny-wiki&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Renders markdown documents provided by items.json, with a list of all documents at the left, and a list of the headings (levels 2+) at the right. No frameworks, just a bit of Javascript, HTML 5 and CSS.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Twilio</title>
      <link>https://tedneward.github.io/Research/presentation/twilio/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/twilio/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.twilio.com/&quot;&gt;Website&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Uno</title>
      <link>https://tedneward.github.io/Research/presentation/uno/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/uno/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://platform.uno/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/nventive/Uno&quot;&gt;Source&lt;/a&gt; | &lt;a href=&quot;https://gallery.platform.uno/&quot;&gt;Gallery&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;C# and XAML&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>VanillaJS (aka No Web Framework)</title>
      <link>https://tedneward.github.io/Research/presentation/vanillajs/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/vanillajs/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;http://vanilla-js.com/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://vanillajstoolkit.com/&quot;&gt;VanillaJS Toolkit&lt;/a&gt; (ignore the homepage, look at the menu at the top) | &lt;a href=&quot;https://github.com/vanillawc/&quot;&gt;VanillaJS Components&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://youtu.be/VvOsegaN9Wk&quot;&gt;&quot;A Framework Author&apos;s Case Against Frameworks&quot;&lt;/a&gt;: Adrian Holovaty, dotJS 2017&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://javarome.medium.com/design-noframework-bbc00a02d9b3&quot;&gt;&quot;Design: #noFramework&quot;&lt;/a&gt;:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;speaks principally to Web frameworks, but I&apos;d argue that this can be true of any framework (thinking Java server-side Web frameworks, C++ GUI frameworks, server-side transaction processing frameworks, ...).* 
  &lt;ul&gt; 
   &lt;li&gt; &lt;p&gt;brings to mind Vlissides&apos; pattern of &lt;a href=&quot;/reading/patterns/evolving-frameworks&quot;&gt;evolving frameworks&lt;/a&gt;*&lt;/p&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;Also brings to mind the Windows++ story: build your own to understand what&apos;s going on underneath--not quite the same point as this author, but certainly a viable line of thought/approach.*&lt;/p&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;Drawbacks of frameworks:&lt;/p&gt; 
    &lt;ul&gt; 
     &lt;li&gt; &lt;p&gt;The Framework Tax: frameworks require you to:&lt;/p&gt; 
      &lt;ul&gt; 
       &lt;li&gt; &lt;p&gt;&lt;strong&gt;comply&lt;/strong&gt; with their API so that they can provide your their services. This is just the way a framework works: your code will have to adhere to some rules, including more or less boilerplate code. So it’s the framework way, or the highway. Your daily challenges will be less about “how to do this” than “how to make the framework (not) do this”. Dodge those constraints at your own risks: if you bypass a framework by directly calling low-level APIs, don’t expect it to understand what you’re trying to do, don’t expect it to stay consistent. So it’s a false promise frameworks make that you’ll be “focusing on your business”: in reality you have to care on the framework too, and a lot.&lt;/p&gt; &lt;/li&gt; 
       &lt;li&gt; &lt;p&gt;upgrades are effectively forced if you:&lt;br&gt; 1) want a new feature (even if you didn’t wanted all those of the next release, you need to upgrade the whole thing) or&lt;br&gt; 2) want a bugfix, or&lt;br&gt; 3) want to avoid loosing support (as new versions are shipped, the one on which you have based your app will get deprecated).&lt;br&gt; Upgrades can also be lacking and let you frustrated (and possibly with a project at risk) with an identified bug but no planned date for a fix. Third-party framework-specific libraries (such as widgets) or plugins are no exception to that rule and will be less and less compatible with your app if you keep using old versions. Maintaining backward compatibility has became such a hassle for frameworks maintainers that they now find more profitable to work on tools that automate upgrades of your code as much as possible (Angular’s ng-update, React native Upgrade helper, Facebook’s jscodeshift, etc.).&lt;/p&gt; &lt;/li&gt; 
       &lt;li&gt; &lt;p&gt;&lt;strong&gt;train&lt;/strong&gt; to learn how they work (what they can/cannot do, what are their concepts, APIs, ecosystem, tools), including changes that may occur in new versions. Should you pick the most popular framework of the day, this might be easier, but it’s unlikely that you’ll ever know about every aspects of a given framework. Also, hype comes and goes: should you decide to use another framework for a new app (or even worse, to migrate from one to another), the cost of investing in such proprietary knowledge will be lost. This explains a lot of inertia in enterprise projects, even if each project is different than the previous one. “Compatibility means deliberately repeating other people’s mistakes,” said the late David Wheeler.&lt;/p&gt; &lt;/li&gt; 
       &lt;li&gt; &lt;p&gt;&lt;strong&gt;compromise&lt;/strong&gt; with the drawbacks implied by delegating control: you may not be able to do whatever you want (or to prevent the framework from doing things you do not want) or you may not achieve the performance you want (because of additional layering, too-generic code, bigger code size or backward compatibility requirements).&lt;/p&gt; &lt;/li&gt; 
       &lt;li&gt; &lt;p&gt;&lt;strong&gt;lose&lt;/strong&gt; skills. A number of developers either don’t know much about the lower-level APIs (because they always used the framework layer instead) or live in the past (i.e. are stick on an outdated knowledge of it, not being aware of the latest improvements and new capabilities). The &lt;a href=&quot;https://en.wikipedia.org/wiki/Law_of_the_instrument&quot;&gt;law of the instrument&lt;/a&gt; then leads too often to build overkill solutions to simple problems, and loose (if even once acquired) knowledge to build simpler ones. Being guided by blueprints and recipes, they loose (or not gain) a culture of good software design (principles, patterns) and barely build a significant engineering experience. Just like users of CSS frameworks (Bootstrap, Tailwind, etc.) lack CSS skills, users of web frameworks are doomed to lack experience in both modern web APIs and software design in general.&lt;/p&gt; &lt;/li&gt; 
      &lt;/ul&gt; &lt;/li&gt; 
     &lt;li&gt; &lt;p&gt;The Framework Silo: Aside the “tax” that you have to pay to get their benefits, frameworks can also induce an additional major issue when they are not standard. As they enforce rules — but each one of them is different — this implies binding your app with a proprietary ecosystem. That means locking your app code with a proprietary API (and its upgrade process). That’s a risky bet for your project.&lt;/p&gt; &lt;/li&gt; 
     &lt;li&gt; &lt;p&gt;Are languages (CoffeeScript, TypeScript, Dart, etc) subject to the same problems as frameworks? Yup.&lt;/p&gt; &lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;Frameworks are a good thing if they:&lt;/p&gt; 
    &lt;ul&gt; 
     &lt;li&gt;are app-specific: any app ends up designing its own “business” framework.&lt;/li&gt; 
     &lt;li&gt;are standard or end up with a standard. For instance the web platform is a standard web framework, and Web Components frameworks (lit, stencil, skatejs, etc.) end up building components that comply with the standard.&lt;/li&gt; 
     &lt;li&gt;add some unique value that you’re missing in all other alternatives (including other frameworks). In such a case you have almost no choice, as the unique added value justifies the implied cost of locking with it. For instance, an OS-specific framework makes sense since it enforce OS standards and there is no other other way to provide an app or extension for it.&lt;/li&gt; 
     &lt;li&gt;are used to build non-critical apps (short lived, with lower quality expectations) where tax and silo effect are acceptable. For instance it makes sense to use Bootstrap to build some prototype, MVP or internal tool.&lt;/li&gt; 
    &lt;/ul&gt; &lt;p&gt;So, in a nutshell, avoiding a framework to build an app aims to:&lt;/p&gt; 
    &lt;ul&gt; 
     &lt;li&gt;maximize flexibility by avoiding “one size fits all” constraints from frameworks. Also, not having blueprints avoids the law of the instrument to increase the creativity for ambitious applications. Most web apps using Bootstrap can be recognized as such, because they’re having a hard time getting out of the predefined components and styles. In the end, they’ll have a hard time thinking another way.&lt;/li&gt; 
     &lt;li&gt;minimize dependency to any of the currently hyped frameworks. Not being locked with a framework avoids issues with portability and interoperability.&lt;/li&gt; 
     &lt;li&gt;maximize performance by allowing the most fine-grained operations only when required (no framework-dependent refresh cycle for instance) and reducing dependencies to a selection of precise, required-only, set of lightweight libraries.&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;Building an app without a framework:&lt;/p&gt; 
    &lt;ul&gt; 
     &lt;li&gt; &lt;p&gt;Goals and mindset: We must clarify the anti-goal: “building an app without a framework” is NOT to be confused with “replacing the framework”. This is not the challenge at stake: a framework is a general purpose technical solution to host virtually any app, so it is less about your app than all apps. On the opposite, going vanilla is an opportunity to focus on your app’s needs only.&lt;/p&gt; &lt;p&gt;This is an important scope narrowing to make to assess the (non-)difficulty of building your app without a framework: it is not as hard as building a framework, because you do NOT aim to build:&lt;/p&gt; 
      &lt;ul&gt; 
       &lt;li&gt;a proprietary component model (a container implementing a specific components lifecycle)&lt;/li&gt; 
       &lt;li&gt;a proprietary plugins/extension system :&lt;/li&gt; 
       &lt;li&gt;a fancy template syntax (JSX, Angular HTML, etc.)&lt;/li&gt; 
       &lt;li&gt;optimizations that make sense for general-purpose (change detection, virtual DOM)&lt;/li&gt; 
       &lt;li&gt;framework-specific tools (debugging extensions, UI builders, version migration tools)&lt;/li&gt; 
      &lt;/ul&gt; &lt;p&gt;So building a vanilla app is not an enormous task of “reinventing the wheel” as often caricatured, because the major part of this “wheel” is actually about the APIs/contracts, their implementations, the general-purpose engine and associated optimizations, the debugging capabilities, etc.. Leaving the general-purpose goal and focusing on your app’s goals means that you can rid of most of it. Ironically, this is the real “focus on your app” approach.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;change your state of mind&lt;/strong&gt;: don’t look for the framework-specific services mentioned above. As a vanilla app, you will probably don’t need it. Don’t think change detection, just update the DOM, etc.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;use technical alternatives&lt;/strong&gt; for the common tasks you performed with frameworks (updating the DOM — including reactively — , loading lazily, etc.)&lt;/p&gt; &lt;/li&gt; 
     &lt;li&gt; &lt;p&gt;Standards: standards APIs are among the “good frameworks” as they:&lt;/p&gt; 
      &lt;ul&gt; 
       &lt;li&gt;allow portability: they are expected to be available everywhere. When not yet available, they can be polyfilled.&lt;/li&gt; 
       &lt;li&gt;allow interoperability: they can interact with other standards and be used by proprietary code.&lt;/li&gt; 
       &lt;li&gt;are long lived: as devised by multiple industry actors rather than only one, they are well designed and here to stay once released. So investing in them is less risky.&lt;/li&gt; 
       &lt;li&gt;are immediately available in the browser most of the time, which avoids downloading them. In some case you may have to download polyfills instead but, contrary to proprietary frameworks (which are doomed to be less and less trendy), their fate is to be more and more available (thus reducing download probability).&lt;/li&gt; 
      &lt;/ul&gt; &lt;/li&gt; 
     &lt;li&gt; &lt;p&gt;What about the use of libraries? As for the “rewrite a framework” false assumption, it is often considered that vanilla JS apps are NOT supposed to use libraries. This is utterly false. Once again, “reinventing the wheel”, i.e. rewriting everything from scratch cannot be a sensible goal. The vanilla goal of removing constraints implied by frameworks and not libraries, must not be confused with a “write everything by yourself” dogma.&lt;/p&gt; &lt;p&gt;&lt;em&gt;(This raises an interesting question not answered by the author: What is the difference between a framework and a library?)&lt;/em&gt;&lt;/p&gt; &lt;p&gt;&lt;em&gt;(THis is a fascinating throwaway line at the end of this section:)&lt;/em&gt; don’t be fooled by frameworks documentation or articles that would claim that they are not a framework (because they would be “unopinionated”, or not defining a “complete application“, etc.): as soon as they imply a contract, they are. &lt;em&gt;(Can libraries be opinionated?)&lt;/em&gt; &lt;em&gt;(NOTE: author also has another post about the &lt;a href=&quot;https://javarome.medium.com/framework-or-library-6711f998d978&quot;&gt;differences between libraries and frameworks&lt;/a&gt; in which he summarizes the two as &quot;frameworks provide you application blueprints with built-in services but enforces predefined contracts to call your code and thus imply a strong dependency; libraries won’t help you design your application, but can be called only when you need them. You can devise a design that limits dependency to them.&quot;)&lt;/em&gt;&lt;/p&gt; &lt;/li&gt; 
     &lt;li&gt; &lt;p&gt;Patterns. Just use of patterns is not enough, but it helps allow people coming to your app consume it more quickly (lighter cognitive burden).&lt;/p&gt; &lt;/li&gt; 
     &lt;li&gt; &lt;p&gt;Concerns:&lt;/p&gt; 
      &lt;ul&gt; 
       &lt;li&gt; &lt;p&gt;Updating: When interviewing developers about what would be their primary concerns when trying to build a vanilla application, most of them reply that it would be complicated to implement model change detection and subsequent updates in the relevant “views” of the app. This is a typical law of the instrument effect, which makes you think in a framework way, whereas not being a framework actually implies much more simple needs:&lt;/p&gt; 
        &lt;ul&gt; 
         &lt;li&gt;The “views” are just DOM elements. You can abstract them of course (and you should) but in the end they are just that.&lt;/li&gt; 
         &lt;li&gt;Updating them is just a matter of viewElement.replaceChild(newContent). That’s it. No unnecessary update of a larger DOM scope, no unwanted redraw or scrolling. There are several ways to update the DOM, from inserting text to manipulating real DOM objects. Just pick the one that fits your need.&lt;/li&gt; 
         &lt;li&gt;“Detecting” when updating is required is usually not necessary in a vanilla app, since most often you just know what is to be updated following an event as you can just do it imperatively. You grab your DOM target and update it, period. In some cases of course you might want to do a more generic update by reversing the dependency and notifying observers (see below) that will update themselves.&lt;/li&gt; 
        &lt;/ul&gt; &lt;/li&gt; 
       &lt;li&gt; &lt;p&gt;Templates: Another feature that developers fear to miss is the ability to write HTML snippets with dynamics parts, even listeners, etc.&lt;/p&gt; &lt;p&gt;First of all the DOM API (document.createElement(&quot;button&quot;), etc.) is not that hard, and actually more powerful than any template language since this allows you full access to the API. It can be tedious to build long HTML fragments but, hey, if they are that long, it’s probably that you need to split it in more fine grained components.&lt;/p&gt; &lt;p&gt;It is true, however, that viewing those elements as a template improves readability. So how to have them? There are actually multiple ways:&lt;/p&gt; 
        &lt;ul&gt; 
         &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/Web_Components/Using_templates_and_slots&quot;&gt;HTML Templates&lt;/a&gt; are now available in browsers (since 2017 at worse). They provide the ability to build a reusable, off-screen, HTML
           &lt;template&gt;
             snippet. This is this actually a part of Web Components and yes, they can support transclusion through &lt;slot&gt;
             .
            &lt;/slot&gt;
           &lt;/template&gt;&lt;/p&gt; &lt;/li&gt; 
         &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals&quot;&gt;Template literals&lt;/a&gt; are available in JavaScript since ES6 (2015). They allow you to easily embed values inside a string. That be enough to embed primitives (numbers, strings, including other HTML code, etc.) but not more sophisticated elements like DOM elements on which you registered listeners for instance.&lt;/p&gt; &lt;/li&gt; 
         &lt;li&gt; &lt;p&gt;A &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals&quot;&gt;tagged template literal&lt;/a&gt; function can help embedding complex values like DOM Nodes into such a template that would result in a Node itself. ObservableHQ has devised a pretty handy one that allows you to write things like html&lt;code&gt;&amp;lt;header&amp;gt;${stringOrNode}&amp;lt;/header&amp;gt; or to do more complex templating like html&lt;/code&gt;&lt;/p&gt;
          &lt;ul&gt;
           ${items.map(item =&amp;gt; `
           &lt;li&gt;${item.title}&lt;/li&gt;}
          &lt;/ul&gt; .&lt;p&gt;&lt;/p&gt; &lt;/li&gt; 
        &lt;/ul&gt; &lt;/li&gt; 
      &lt;/ul&gt; &lt;p&gt;What about conditionals or loops in a template? Aside the fact that this might have never been a good idea (UIs should be dumb and not contain logic), you can (and should) just do it JS, then insert the result in your template, using one of the techniques above.&lt;/p&gt; 
      &lt;ul&gt; 
       &lt;li&gt; &lt;p&gt;Events: how to bind events to DOM Nodes inside them? There are also several alternatives:&lt;/p&gt; 
        &lt;ul&gt; 
         &lt;li&gt;HTML event handlers (&amp;lt;button onclick=&quot;myClickHandler(event)“&amp;gt;) can be inserted in any HTML source, but they not very practicable, since they require the specified handlers to be available on the specified scope.&lt;/li&gt; 
         &lt;li&gt;Event handlers API (button.addEventListener(&quot;click&quot;, myClickHandler)) can be used on any node created through the DOM API or an HTML tagged template literal function.&lt;/li&gt; 
        &lt;/ul&gt; &lt;p&gt;Now what about custom/business events? What if I need to react to some event triggered by a component of my app. There are also multiple options for that:&lt;/p&gt; 
        &lt;ul&gt; 
         &lt;li&gt;Custom events: You can create you own events classes extending EventTarget and dispatch or listen to them, just like any “standard” event.&lt;/li&gt; 
         &lt;li&gt;EventEmitter is theoretically an option (exists in Node and as libs in the browser), but is rarely used.&lt;/li&gt; 
         &lt;li&gt;Observer pattern: You can build your own but RxJs is the de facto-standard for doing such reactive programming: build a Subject then notify all subscribers of a new value so they can react to it.&lt;/li&gt; 
        &lt;/ul&gt; &lt;/li&gt; 
       &lt;li&gt; &lt;p&gt;Components: it is still a good idea design software items as reusable (i.e. context-independent) if they can occur multiple times in your system. Whatever the technology you use, well-grained abstractions remain useful, whether they are business or technical: it’s always a good idea to group data and rules pertaining to the same business concept into a reusable object or to build a widget that can be instantiated in multiple places in your app.&lt;/p&gt; &lt;p&gt;Aside &lt;em&gt;[from]&lt;/em&gt; standard widget components (which would typically be implemented as standard Web Components), any component should typically be able to &lt;em&gt;(standard component things: methods, state, events)&lt;/em&gt;:&lt;/p&gt; 
        &lt;ul&gt; 
         &lt;li&gt;split its logic and its view (through a MVC typically). Mixing the two usually makes the code less maintainable, and less flexible (for instance, should you want to display a record in both detailed or tabular form, your RecordComponent would just need to use either a DetailRecordView or a RowRecordView).&lt;/li&gt; 
         &lt;li&gt;read inputs to parameterize its behavior or its view.&lt;/li&gt; 
         &lt;li&gt;trigger events to notify parties that something occurred in the component (following a user interaction typically).&lt;/li&gt; 
         &lt;li&gt;synchronize: your component should be able to redraw if some event occurs. This can be achieved quite easily using reactive libraries such as RxJS.&lt;/li&gt; 
        &lt;/ul&gt; &lt;p&gt;In any case, whatever the design strategy you choose, you component (or more specifically its associated “view”) must be able to provide some HTML rendering result. A string containing HTML code could be used, but an actual HTMLElement (or just Element) is usually a better choice (easier to read/update rather than parsing, allowing to bind event handlers on it) and a more performant one (no parsing required).&lt;/p&gt; &lt;p&gt;Also, you might want to use external components from third-party libraries. For sure, proprietary frameworks, because of their popularity, benefit from a larger number of libraries and components developed by their community. Although most of them are actually not so different from what they would be if they’d had been implemented in pure Javascript (like this was the case at JQuery times) they do suffer from lack of interoperability, and you find yourself looking for either vanilla or Web components.&lt;/p&gt; &lt;p&gt;Hopefully such libraries exist, such as the Vanilla JS Toolkit, even if less common. Regarding standards ones, WebComponents.org list 2000+ elements. There’s even vanilla web components, but the vanilla aspect is less relevant here (more about implementation lightweightness than interoperability).&lt;/p&gt; &lt;/li&gt; 
       &lt;li&gt; &lt;p&gt;Routing: Managing routes in a SPA today requires using the web &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/History_API&quot;&gt;History API&lt;/a&gt;. Whereas this is &lt;a href=&quot;https://krasimirtsonev.com/blog/article/A-modern-JavaScript-router-in-100-lines-history-api-pushState-hash-url&quot;&gt;less complex that you imagine&lt;/a&gt;, you might want to delegate this to a simple router library such as &lt;a href=&quot;https://github.com/krasimir/navigo&quot;&gt;Navigo&lt;/a&gt;. All you have to do, then, is to replace an DOM element by another (using replaceChildren() or replaceWith()) when a route is reached.&lt;/p&gt; &lt;/li&gt; 
       &lt;li&gt; &lt;p&gt;Lazy loading: ES6 (2015) can load modules dynamically. This works in Node, but in browsers too: &lt;code&gt;{WelcomeModule} = await import(&quot;./welcome/ModuleImpl&quot;); module = new WelcomeModule()&lt;/code&gt; Bundlers like Webpack can insulate modules in dedicated files. Beware that you should only use constants in the import path, though: otherwise, the bundler cannot guess what you will load and will package the whole set of possible files in a single chunk. For instance &lt;code&gt;await import(&lt;/code&gt;./welcome/${moduleName}&lt;code&gt;)&lt;/code&gt; will bundle everything in the specified directory, given that your bundler doesn’t know what the &lt;code&gt;moduleName&lt;/code&gt; variable will hold at runtime.&lt;/p&gt; &lt;/li&gt; 
       &lt;li&gt; &lt;p&gt;Native apps: &lt;em&gt;(as opposed to using framework derivatives like React Native)&lt;/em&gt;&lt;/p&gt; &lt;/li&gt; 
       &lt;li&gt; &lt;p&gt;Server-side rendering (SSR): &lt;em&gt;(I find it hilarious and sad that we talk about using client-side Javascript fameworks to do server-side rendering with a straight face)&lt;/em&gt;&lt;/p&gt; &lt;/li&gt; 
       &lt;li&gt; &lt;p&gt;Internationalization: Internationalization have been handled by libraries for many years now (and finally integrated within frameworks). You can easily integrate one of those libs but this could also be a good candidate for an in-house implementation, which would allow more simple and efficient messages types than a general-purpose lib can.&lt;/p&gt; &lt;pre&gt;&lt;code&gt;    ```
    interface WelcomeMessages {
        title: string
        greetings(user: string, unreadCount: number): string
    }
    class WelcomeMessage_en implements WelcomeMessage {
        title = &quot;Welcome !&quot;,
        greetings = (user, unreadCount) =&amp;gt; `Welcome ${user}, you have ${unreadCount} unread messages.`
    }
    class WelcomeMessage_fr implements WelcomeMessage {
        title = &quot;Bienvenue !&quot;,
        greetings = (user, unreadCount) =&amp;gt; `Bienvenue ${user}, vous avez ${unreadCount} nouveaux messages.`
    }
    ```
&lt;/code&gt;&lt;/pre&gt; &lt;p&gt;Note that this provides you:&lt;/p&gt; 
        &lt;ul&gt; 
         &lt;li&gt; &lt;p&gt;type checking: every message has a static type (and several implementations/translations), so your IDE can check if you’re using a valid message property or not, and provide you auto-completion.&lt;/p&gt; &lt;/li&gt; 
         &lt;li&gt; &lt;p&gt;translation exhaustivity check: you can’t compile until all interface keys are implemented in all languages.&lt;/p&gt; &lt;/li&gt; 
        &lt;/ul&gt; &lt;p&gt;All you have is to (load and) instantiate the message class that is relevant to you user’s locale. General purpose libs can’t provide such business-specific types.&lt;/p&gt; &lt;p&gt;&lt;em&gt;(I think he&apos;s oversimplifying the case, but at the same time, I think a lot of frameworks over-complexify the case so let&apos;s assume this is the simplest thing, and get more complicated from there as need be.)&lt;/em&gt;&lt;/p&gt; &lt;/li&gt; 
       &lt;li&gt; &lt;p&gt;Tools: If you want to free yourself from dependency on a too constraining software stack, it is likely that you’d want to do the same with your tools: you don’t want to depend on them (their limitations, their performance, their bugs, their versions) to be able to move forward. You don’t want tot get stuck with a build problem that you cannot solve (or need hours or days to solve) because you do not own it (especially when using trendy but recent build tools which are not fully battle-tested yet). That said, you will hardy avoid those tools. Most often your production code will have to be bundled in a clever way, involving minification, obfuscation, code splitting, tree shaking, lazy loading, style inclusion, etc. and there is little doubt that existing packagers such as Webpack, Parcel, ESBuild or Vite will do it better that you could. All you can do about it is:&lt;/p&gt; 
        &lt;ul&gt; 
         &lt;li&gt;Use less transformations as possible. For instance, using TypeScript might a good thing but implies an additional level of complexity that has to be handled by your tooling chain. Maybe your CSS also, especially with the latest modern versions, is not worth using preprocessors like Sass.&lt;/li&gt; 
         &lt;li&gt;Use less tools as possible. The more you add, the more one can fail / not support your needs.&lt;/li&gt; 
         &lt;li&gt;When using one, use the most popular tool so what you need is more likely to be supported by such a battle-tested software (and so you won’t be stuck in a position of “change need or change tool”). Moving to the latest hyped bundler too early might save you a few build seconds that might be compensated by the time devoted understanding the new beta documentation, handling bugs or lack of support.&lt;/li&gt; 
        &lt;/ul&gt; &lt;p&gt;&lt;em&gt;(I&apos;m really not sure I agree with his take on this; he has some good points, but this feels like it encourages a very &quot;build it all yourself&quot; approach--which, to be fair, is a known concern that he&apos;s addressed repeatedly all over the place. Still, I think the better takeaway here is, &quot;Use tools sparingly but deliberately.&quot; Know what the tool does, be able to live one layer deeper than what the tool gives you, and so on.)&lt;/em&gt;&lt;/p&gt; &lt;/li&gt; 
      &lt;/ul&gt; &lt;/li&gt; 
     &lt;li&gt; &lt;p&gt;Challenges: (from others)&lt;/p&gt; 
      &lt;ul&gt; 
       &lt;li&gt;“you’re going to write your own framework”: no, you’re going to write an app instead of a framework.&lt;/li&gt; 
       &lt;li&gt;“you’re going to write more code”: maybe, maybe not so much (depending on your use of libraries) as this has to be compared with the boilerplate code required by frameworks. In any case, the overall loaded code size will be smaller,&lt;/li&gt; 
       &lt;li&gt;“you’re going to reinvent the wheel constantly”: of course not: not using a framework is just choosing to not comply with its predefined rules (configuration, lifecycle, refresh mechanism, etc.) but it’s not forgetting DRY principles and, as stated above, you can still (and should) use battle-tested third-party libraries.&lt;/li&gt; 
       &lt;li&gt;“you will write more code for every feature”: no, you’ll just use your own rules instead of the framework boilerplate.&lt;/li&gt; 
       &lt;li&gt;“there will be no documentation”: no documentation about the framework for sure (since there’s isn’t any) but, as for any software development, you are still expected to document your app. Notably, the use of patterns will help to auto-document your software design. Your app’s code documentation is the one you care about ; having an additional framework’s documentation is just the consequence of having a framework.&lt;/li&gt; 
       &lt;li&gt;“there will be no constraints or patterns to guide the developer”: no, nothing prevents you to enforce constraints if you need it (you just have to define contracts). The difference is that they will be the constraints of your choice, tailored for your app.&lt;/li&gt; 
       &lt;li&gt;“you will miss performance improvements” such as the once-hyped Virtual Dom (which is today challenged, including by subsequent frameworks like Svelte or Aurelia): no, as those “performance improvements” are actually more need by the general-purpose nature of frameworks, not by custom apps. On the opposite, general purpose framework will more likely miss a number of performance improvements that a custom code can implement.&lt;/li&gt; 
       &lt;li&gt;“You get this problem because you didn’t use a framework” Every difficulty (bug, delay, recruitment, etc) will be blamed on that unorthodox choice. Because most developers’ experience is that everything that has worked was using a framework, not using them will be assumed risky by default. This assumption will be considered as confirmed as soon as a problem will arise, whether it is related to not using a framework or not. They will forget all the similar issues they had when using framework.&lt;/li&gt; 
       &lt;li&gt;“We can’t find developers”: You’ll be told that it’s difficult to find developers who can develop vanilla code. That’s both true and false. True because a lot of developers (not speaking about managers) will find themselves more comfortable using known recipes such as frameworks. Candidates might feel a bit scared about building a webapp from scratch if they never did it once, or if they don’t know the basic web APIs well. False because, if you want to build quality apps, you should not look for this kind of developers. For sure it is currently easier to find any React developer, but what you need is not a React developer, but a good developer.&lt;/li&gt; 
       &lt;li&gt;“You won’t get the code quality of frameworks”. For sure frameworks or libraries are usually written by major industry players or experienced developers. However, as we saw above, the code of frameworks is mostly related to framework-specific activities (components lifecycle, general-purpose refresh and optimizations, tooling, etc.), not your app. Furthermore, you can still make bad design choices and write poor code using frameworks. The quality of your application always depends more on the quality of your team, than the lack of blueprints.&lt;/li&gt; 
       &lt;li&gt;“You won’t get same performance as frameworks”: No, we’ll get better performance. The marketed argument that framework include sophisticated technologies that can “improve performance” such as the “virtual DOM” (which allowed to bufferize DOM changes in order to limit their changes on it) is off-topic, as it relates to solving the performance drawbacks of a general-purpose solution. When the developer updates the DOM by him/herself, (s)he can get the best performance because (s)he will now if it’s worth bufferizing/caching it or if it’s pure overhead.&lt;/li&gt; 
      &lt;/ul&gt; &lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>W3M</title>
      <link>https://tedneward.github.io/Research/presentation/w3m/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/w3m/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;http://w3m.rocks/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;http://w3m.sourceforge.net/&quot;&gt;Source&lt;/a&gt; | &lt;a href=&quot;http://w3m.sourceforge.net/MANUAL&quot;&gt;Manual&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Python UI frameworks/libraries</title>
      <link>https://tedneward.github.io/Research/presentation/python/index/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/python/index/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://realpython.com/tutorials/gui/&quot;&gt;&quot;Python GUI Tutorials&quot;&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://blog.tooljet.ai/python-gui-framework/#&quot;&gt;&quot;Choosing Right Python GUI Framework: A Complete Guide&quot;&lt;/a&gt;&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Tkinter&lt;/li&gt; 
 &lt;li&gt;PyQt5&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;/presentation/python/kivy&quot;&gt;Kivy&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;wxPython&lt;/li&gt; 
 &lt;li&gt;Libavg&lt;/li&gt; 
 &lt;li&gt;PySimpleGUI&lt;/li&gt; 
 &lt;li&gt;PyForms&lt;/li&gt; 
 &lt;li&gt;Wax&lt;/li&gt; 
 &lt;li&gt;PySide2&lt;/li&gt; 
 &lt;li&gt;PyGUI&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;Related&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/python-eel/Eel&quot;&gt;Eel&lt;/a&gt;: A little Python library for making simple Electron-like HTML/JS GUI apps (Discontinued development in June 2025)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/cztomczak/cefpython&quot;&gt;CEFPython&lt;/a&gt;: an open source project founded by Czarek Tomczak in 2012 to provide Python bindings for the Chromium Embedded Framework (CEF).&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Streamlit</title>
      <link>https://tedneward.github.io/Research/presentation/python/streamlit/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/python/streamlit/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://streamlit.io/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/streamlit/streamlit&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Install: &lt;code&gt;pip install streamlit&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;Start an app: &lt;code&gt;streamlit hello&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;Streamlit builds upon three simple principles:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Embrace scripting: Build an app in a few lines of code with our magically simple API. Then see it automatically update as you iteratively save the source file.&lt;/li&gt; 
 &lt;li&gt;Weave in interaction: Adding a widget is the same as declaring a variable. No need to write a backend, define routes, handle HTTP requests, connect a frontend, write HTML, CSS, JavaScript, ...&lt;/li&gt; 
 &lt;li&gt;Deploy instantly: Effortlessly share, manage and deploy your apps, directly from Streamlit. All for free!&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Quasar</title>
      <link>https://tedneward.github.io/Research/presentation/quasar/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/quasar/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://quasar.dev/&quot;&gt;Website&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Quasar is an open-source Vue.js based framework, which allows you as a web developer to quickly create responsive++ websites/apps in many flavours:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;SPAs (Single Page App)&lt;/li&gt; 
 &lt;li&gt;SSR (Server-side Rendered App) (+ optional PWA client takeover)&lt;/li&gt; 
 &lt;li&gt;PWAs (Progressive Web App)&lt;/li&gt; 
 &lt;li&gt;BEX (Browser Extension)&lt;/li&gt; 
 &lt;li&gt;Mobile Apps (Android, iOS, ...) through &lt;a href=&quot;../cordova&quot;&gt;Cordova&lt;/a&gt; or &lt;a href=&quot;../capacitorjs&quot;&gt;Capacitor&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;Multi-platform Desktop Apps (using &lt;a href=&quot;../electron&quot;&gt;Electron&lt;/a&gt;)&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;Quasar’s motto is: write code once and simultaneously deploy it as a website, a Mobile App and/or an Electron App. Yes, one codebase for all of them, helping you develop an app in record time by using a state-of-the-art CLI and backed by best-practice, blazing fast Quasar web components.&lt;/p&gt; 
&lt;p&gt;When using Quasar, you won’t need additional heavy libraries like Hammer.js, Moment.js or Bootstrap. It’s got those needs covered internally, and all with a small footprint!&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>raygui</title>
      <link>https://tedneward.github.io/Research/presentation/raygui/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/raygui/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/raysan5/raygui&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Redux</title>
      <link>https://tedneward.github.io/Research/presentation/react/redux/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/react/redux/index.html</guid>
      	<description>
	&lt;h3&gt;Reading&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;http://teropa.info/blog/2015/09/10/full-stack-redux-tutorial.html&quot;&gt;Full-Stack Redux Tutorial&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.robinwieruch.de/the-soundcloud-client-in-react-redux/&quot;&gt;SoundCloud Application in React + Redux&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://leanpub.com/redux-book&quot;&gt;The Complete Redux Book&lt;/a&gt; - Boris Dinkevich and Ilya Gelman &lt;em&gt;(Leanpub account or valid email requested)&lt;/em&gt;&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Remix</title>
      <link>https://tedneward.github.io/Research/presentation/remix/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/remix/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://remix.run/&quot;&gt;Website&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Apache Royale</title>
      <link>https://tedneward.github.io/Research/presentation/royale/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/royale/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://royale.apache.org/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://royale.apache.org/tourdejewel&quot;&gt;Tour De Jewel&lt;/a&gt; | &lt;a href=&quot;https://github.com/apache/royale-asjs/wiki/Apache-Royale-Source-Code-Repositories&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>SemanticUI</title>
      <link>https://tedneward.github.io/Research/presentation/semanticui/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/semanticui/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://semantic-ui.com/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/semantic-org/semantic-ui&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;(No updates since 2018)&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Shoelace</title>
      <link>https://tedneward.github.io/Research/presentation/shoelace/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/shoelace/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://shoelace.style/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/shoelace-style/shoelace&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://css-tricks.com/shoelace-component-frameowrk-introduction/&quot;&gt;Introducing Shoelace&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Skip</title>
      <link>https://tedneward.github.io/Research/presentation/skip/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/skip/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://skip.dev/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/skiptools/skip&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;h2&gt;Getting Started&lt;/h2&gt; 
&lt;p&gt;Skip is installed and updated using the popular Homebrew package management tool, which can be installed from brew.sh ↗. Once Homebrew has been setup, install Skip by running the Terminal command:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;brew install skiptools/skip/skip
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;This will download and install the skip tool itself, along with the Android SDK and gradle build tool that is necessary for building and running the Android side of your apps.&lt;/p&gt; 
&lt;p&gt;You can ensure that the basic development prerequisites are satisfied by running:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;skip checkup
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Create a new Skip app project with:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;skip create
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;You will be guided through a series of questions about the app you want to create. The first two are especially important:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;App or Library? The App option creates a single Swift and SwiftUI app that uses Skip’s Xcode plugin to automatically build for Android. The Library option creates a Swift library that you can use in a unified Skip app, or use as shared business logic in separate iOS and Android apps. Neither option prevents you from using a combination of Swift and Kotlin, SwiftUI and Compose in your final application.&lt;/li&gt; 
 &lt;li&gt;Skip Fuse or Skip Lite? Information about the different modes can be found in the Native and Transpiled Modes documentation. In this example, we create a Skip Fuse app, which uses the official Swift SDK for Android ↗.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;If you’re new to Skip, we recommend starting your exploration with an App project. An example session for creating a hello-skip/HelloSkip project (which generates a project identical to the minimal Skip Fuse sample app ↗ or Skip Lite sample app ↗) might look like:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;$ skip create

Welcome to Skip!

Select type of project to create:
1: App: mobile application for Android and iOS
2: Library: library project with one or more modules
Enter selection (default: App) [1..2] 1

Select the mode of the project:
1: Skip Fuse: natively compiled project
2: Skip Lite: transpiled project
Enter selection [1..2] 1

Enter the project-name for the App: hello-skip

Enter the CamelCase name of the App module: HelloSkip

Optionally enter additional module names:

Enter the app bundle identifier: com.example.HelloSkip

Create a free open-source project? (y/n) [n]: n
Initialize git repository for the project? (y/n) [n]: n
Initialize a Fastlane configuration for the project? (y/n) [y]: y
Pre-build the project? (y/n) [y]: y
Install the Swift Android SDK? (y/n) [y]: y
Open the Xcode project after initialization? (y/n) [y]: y

[✓] Install Swift Android SDK (48.4s)
[✓] Resolve dependencies (12.12s)
[✓] Build hello-skip (53.35s)
[✓] Check project schemes (6.12s)
[✓] Archive iOS ipa (17.18s)
[✓] Assemble HelloSkip-debug.ipa 1 MB
[✓] Verifying HelloSkip-debug.ipa: 1 MB
[✓] Assembling Android apk (78.91s)
[✓] Verify HelloSkip-debug.apk: 80 MB
[✓] Opening Xcode project (0.10s)
[✓] Skip create succeeded in 168.63s
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;You can alternatively create a Skip project using the non-interactive skip init command, as described in the command line reference.&lt;/p&gt; 
&lt;p&gt;Once your app pre-builds and opens in Xcode, you are almost ready to go. One more step is needed, which is to create and launch an Android emulator (which is the Android equivalent of the iPhone Simulator and is used for local app development). The skip tool has a command to quickly install and configure an Android emulator for your project:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;skip android emulator create

[✓] Configure Android SDK Manager (1.55s)
[✓] Install platform-tools (0.77s)
[✓] Install emulator (0.75s)
[✓] Install platforms;android-34 (0.76s)
[✓] Install system-images;android-34;google_apis;arm64-v8a (0.75s)
[✓] Create emulator: emulator-34-medium_phone (0.76s)
[✓] Create Android emulator succeeded in 5.35s
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Once this command completes successfully, you will have an Android emulator installed, which you can launch and observe the logging output with:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;skip android emulator launch
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Now you should be ready to launch your new app! In Xcode, ensure the “HelloSkip App” scheme is selected along with a simulator destination (e.g., “iPhone 17”), and then Run the scheme.&lt;/p&gt; 
&lt;p&gt;You may be prompted to “Trust and Enable” the Skip plugin, and then the project will build and launch simultaneously on both the iPhone Simulator and Android Emulator.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>StackEdit</title>
      <link>https://tedneward.github.io/Research/presentation/stackedit/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/stackedit/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://stackedit.io/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://benweet.github.io/stackedit.js/&quot;&gt;Source Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/benweet/stackedit.js&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;&amp;lt;blockquote&amp;gt;
    &amp;lt;textarea&amp;gt;Hello **Markdown** writer!&amp;lt;/textarea&amp;gt;
&amp;lt;/blockquote&amp;gt;

&amp;lt;script src=&quot;https://unpkg.com/stackedit-js@1.0.7/docs/lib/stackedit.min.js&quot;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;script&amp;gt;
// Import the lib.
const stackedit = new Stackedit();

function makeEditButton(el) {
  const div = document.createElement(&apos;div&apos;);
  div.className = &apos;stackedit-button-wrapper&apos;;
  div.innerHTML = &apos;&amp;lt;a href=&quot;javascript:void(0)&quot;&amp;gt;&amp;lt;img src=&quot;icon.svg&quot;&amp;gt;Edit with StackEdit&amp;lt;/a&amp;gt;&apos;;
  el.parentNode.insertBefore(div, el.nextSibling);
  return div.getElementsByTagName(&apos;a&apos;)[0];
}

const textareaEl = document.querySelector(&apos;textarea&apos;);
console.log(textareaEl)
makeEditButton(textareaEl)
  .addEventListener(&apos;click&apos;, function onClick() {
    const stackedit = new Stackedit();
    stackedit.on(&apos;fileChange&apos;, function onFileChange(file) {
      textareaEl.value = file.content.text;
    });
    stackedit.openFile({
      name: &apos;Markdown with StackEdit&apos;,
      content: {
        text: textareaEl.value
      }
    });
  });

const htmlEl = document.querySelector(&apos;.html&apos;);
let markdown = &apos;Hello **Markdown** writer!&apos;;

function doOpen(background) {
  const stackedit = new Stackedit();
  stackedit.on(&apos;fileChange&apos;, function onFileChange(file) {
    markdown = file.content.text;
    htmlEl.innerHTML = file.content.html;
  });
  stackedit.openFile({
    name: &apos;HTML with StackEdit&apos;,
    content: {
      text: markdown
    }
  }, background);
}

doOpen(true);
makeEditButton(htmlEl)
  .addEventListener(&apos;click&apos;, function onClick() {
    doOpen(false);
  });

&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
	</description>
    </item>
    <item>
      <title>Svelte</title>
      <link>https://tedneward.github.io/Research/presentation/svelte/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/svelte/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://svelte.dev/tutorial&quot;&gt;Tutorial&lt;/a&gt; | &lt;a href=&quot;https://svelte.dev/docs&quot;&gt;Docs/API&lt;/a&gt; | &lt;a href=&quot;https://discordapp.com/channels/457912077277855764/473466028106579978&quot;&gt;Discord&lt;/a&gt;&lt;/p&gt; 
&lt;h3&gt;Getting Started&lt;/h3&gt; 
&lt;p&gt;NodeJS-based tool chain. Svelte starts from either a .zip of the &lt;code&gt;sveltejs/template&lt;/code&gt; project or by using &lt;code&gt;npx degit sveltejs/template &amp;lt;project-directory&amp;gt;&lt;/code&gt;. From there it&apos;s a &lt;code&gt;cd&lt;/code&gt; and &lt;code&gt;npm install&lt;/code&gt;. Once updated, &lt;code&gt;npm run dev&lt;/code&gt; puts a local web server on &lt;a href=&quot;http://localhost:5000&quot;&gt;http://localhost:5000&lt;/a&gt; for dev examination.&lt;/p&gt; 
&lt;p&gt;Project directory layout:&lt;/p&gt; 
&lt;p&gt;&lt;code&gt;/&lt;/code&gt; - contains Rollup configuration, npm details, READMe, and so on. Probably nothing to do here.&lt;br&gt; &lt;code&gt;/public&lt;/code&gt; - looks like this has the browser-accessible assets, including &lt;code&gt;index.html&lt;/code&gt;.&lt;br&gt; &lt;code&gt;/src&lt;/code&gt; - looks like this has the component files (&lt;code&gt;App.svelte&lt;/code&gt;) as well as a global tie-together (&lt;code&gt;main.js&lt;/code&gt;) that instantiates the top-level component. Betting that &lt;code&gt;main&lt;/code&gt; gets referenced directly or indirectly from &lt;code&gt;index.html&lt;/code&gt; at some point--nope, looks like it gets bundled into a build directory and that&apos;s what&apos;s referenced from the index.&lt;/p&gt; 
&lt;h3&gt;Tutorial&lt;/h3&gt; 
&lt;p&gt;Component-centric; HTML/CSS/JS all go into a &lt;code&gt;.svelte&lt;/code&gt; file for use.&lt;/p&gt; 
&lt;h3&gt;Reading&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://svelte.dev/tutorial/basics&quot;&gt;Svelte Tutorial&lt;/a&gt; - Svelte.dev&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://flaviocopes.com/page/svelte-handbook/&quot;&gt;The Svelte Handbook&lt;/a&gt; - Flavio Copes (PDF, EPUB, Kindle) &lt;em&gt;(email address requested)&lt;/em&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Sapper&lt;/h3&gt; 
&lt;p&gt;&quot;Sapper is a framework for building extremely high-performance web apps. You&apos;re looking at one right now! There are two basic concepts:&lt;br&gt; * Each page of your app is a component&lt;br&gt; * You create pages by adding files to the src/routes directory of your project. These will be server-rendered so that a user&apos;s first visit to your app is as fast as possible, then a client-side app takes over&lt;/p&gt; 
&lt;p&gt;Building an app with all the modern best practices — code-splitting, offline support, server-rendered views with client-side hydration — is fiendishly complicated. Sapper does all the boring stuff for you so that you can get on with the creative part.&lt;/p&gt; 
&lt;p&gt;You don&apos;t need to know Svelte to understand the rest of this guide, but it will help. In short, it&apos;s a UI framework that compiles your components to highly optimized vanilla JavaScript.&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://sapper.svelte.dev/docs/&quot;&gt;Docs&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>TGUI</title>
      <link>https://tedneward.github.io/Research/presentation/tgui/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/tgui/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://tgui.eu/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/texus/TGUI/&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>TipTap</title>
      <link>https://tedneward.github.io/Research/presentation/tiptap/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/tiptap/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://tiptap.dev&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/ueberdosis/tiptap&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Based on the highly-available ProseMirror library. Complemented by collaboration open-source backend Hocuspocus.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Twitch</title>
      <link>https://tedneward.github.io/Research/presentation/twitch/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/twitch/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.twitch.tv/&quot;&gt;Website&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Vaadin</title>
      <link>https://tedneward.github.io/Research/presentation/vaadin/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/vaadin/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://vaadin.com/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://vaadin.com/learn/tutorials&quot;&gt;Tutorials&lt;/a&gt; | &lt;a href=&quot;https://github.com/vaadin/&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;h2&gt;&lt;a href=&quot;https://vaadin.com/flow&quot;&gt;Vaadin Flow&lt;/a&gt; (&lt;a href=&quot;https://github.com/vaadin/flow&quot;&gt;Source&lt;/a&gt;)&lt;/h2&gt; 
&lt;p&gt;&lt;em&gt;The Java framework binding Vaadin web components to Java. This is part of Vaadin 10+ Platform for building modern web sites that look great, perform well and make you and your users happy.&lt;/em&gt; &quot;Vaadin Flow is an open-source framework for building web apps in Java. You build your app from UI components without ever having to touch HTML or JavaScript.&quot;&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;@Route(&quot;hello-world&quot;)
public class HelloWorld extends VerticalLayout {

    public HelloWorld() {
        TextField name = new TextField(&quot;Name&quot;);
        Paragraph greeting = new Paragraph(&quot;&quot;);

        Button button = new Button(&quot;Greet&quot;, event -&amp;gt; {
            greeting.setText(&quot;Hello &quot; + name.getValue());
        });

        add(name, button, greeting);
    }
}
&lt;/code&gt;&lt;/pre&gt; 
&lt;h2&gt;&lt;a href=&quot;https://vaadin.com/fusion&quot;&gt;Vaadin Fusion&lt;/a&gt;&lt;/h2&gt; 
&lt;p&gt;&lt;em&gt;A TypeScript and Java web framework for building modern web applications. You can create UIs in TypeScript and connect to any backend through endpoints written in Java.&lt;/em&gt; &quot;Vaadin Fusion is a framework that helps you rapidly deliver beautiful reactive client-side web apps using TypeScript with a Java backend.&quot;&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-ts&quot;&gt;@SpringBootApplication
    @PWA(name = &quot;Fusion App&quot;, shortName = &quot;Fusion&quot;, offlineResources = {&quot;images/logo.png&quot;})
    public class Application extends SpringBootServletInitializer implements AppShellConfigurator {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

// --- Server ---

@Endpoint
public class TodoEndpoint {
    private TodoRepository repo;

    // Repository autowired by Spring
    public TodoEndpoint(TodoRepository repo) {
        this.repo = repo;
    }

    // Publish a typed endpoint
    public List&amp;gt;Todo&amp;lt; getTodos() {
        return repo.findAll();
    }
}

// --- Client ---

// Call the backend in TypeScript
const todos: Todo[] = await TodoEndpoint.getTodos();
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;&lt;strong&gt;Reactive views with declarative templates&lt;/strong&gt;; Vaadin Fusion has a reactive programming model based on &lt;a href=&quot;https://lit.dev/&quot;&gt;Lit&lt;/a&gt;.&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;The declarative template is automatically updated when the application state changes.&lt;/li&gt; 
 &lt;li&gt;Lit uses a simple template syntax based on standard JavaScript.&lt;/li&gt; 
 &lt;li&gt;Fusion comes with built-in support for &lt;a href=&quot;https://mobx.js.org/&quot;&gt;MobX&lt;/a&gt; for application state management.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;pre&gt;&lt;code&gt;@customElement(&apos;hello-world-view&apos;)
export class HelloWorldView extends View {
  @state() name = &apos;&apos;;
  @state() allNames: string[] = [];

  render() {
    return html`
      &amp;lt;h1&amp;gt;Greetings!&amp;lt;/h1&amp;gt;
      &amp;lt;ul&amp;gt;
        ${this.allNames.map((name) =&amp;gt; html`&amp;lt;li&amp;gt;Hello, ${name}&amp;lt;/li&amp;gt;`)}
        &amp;lt;li&amp;gt;
          &amp;lt;vaadin-text-field
            placeholder=&quot;Your name&quot;
            .value=${this.name}
            @value-changed=${this.nameChanged}
          &amp;gt;&amp;lt;/vaadin-text-field&amp;gt;
          &amp;lt;vaadin-button @click=${this.addGreeting}&amp;gt;Add name&amp;lt;/vaadin-button&amp;gt;
        &amp;lt;/li&amp;gt;
      &amp;lt;/ul&amp;gt;
    `;
  }

  nameChanged(e: CustomEvent) {
    this.name = e.detail.value;
  }

  addGreeting() {
    this.allNames = [...this.allNames, this.name];
    this.name = &apos;&apos;;
  }
}
&lt;/code&gt;&lt;/pre&gt; 
&lt;h2&gt;Vaadin Framework (&lt;a href=&quot;https://github.com/vaadin/framework&quot;&gt;Source&lt;/a&gt;)&lt;/h2&gt; 
&lt;p&gt;&lt;em&gt;Vaadin 8 and Vaadin 7, both of which use GWT as the base of client-side implementations.&lt;/em&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>vis.js</title>
      <link>https://tedneward.github.io/Research/presentation/visjs/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/visjs/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://visjs.org/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/visjs&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;The library consists of the components DataSet, Timeline, Network, Graph2d and Graph3d.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Web Components</title>
      <link>https://tedneward.github.io/Research/presentation/webcomponents/index/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/webcomponents/index/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.webcomponents.org/&quot;&gt;Website&lt;/a&gt;&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.webcomponents.org/introduction&quot;&gt;Introduction&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.webcomponents.org/specs&quot;&gt;Specifications&lt;/a&gt;: Four main specifications 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://w3c.github.io/webcomponents/spec/custom/&quot;&gt;Custom Elements&lt;/a&gt;: lays the foundation for designing and using new types of DOM elements.&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://w3c.github.io/webcomponents/spec/shadow/&quot;&gt;Shadow DOM&lt;/a&gt;: defines how to use encapsulated style and markup in web components.&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://html.spec.whatwg.org/multipage/webappapis.html#integration-with-the-javascript-module-system&quot;&gt;ES Modules&lt;/a&gt;: defines the inclusion and reuse of JS documents in a standards based, modular, performant way.&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://html.spec.whatwg.org/multipage/scripting.html#the-template-element/&quot;&gt;HTML Template&lt;/a&gt;: defines how to declare fragments of markup that go unused at page load, but can be instantiated later on at runtime.&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://www.webcomponents.org/libraries&quot;&gt;Libraries&lt;/a&gt;&lt;/p&gt; 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/hybridsjs/hybrids&quot;&gt;Hybrids&lt;/a&gt; is a UI library for creating Web Components with simple and functional API.&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/Polymer/lit-element&quot;&gt;LitElement&lt;/a&gt; uses lit-html to render into the element&apos;s Shadow DOM and adds API to help manage element properties and attributes.&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.polymer-project.org/&quot;&gt;Polymer&lt;/a&gt; provides a set of features for creating custom elements.&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://slimjs.com/&quot;&gt;Slim.js&lt;/a&gt; is an opensource lightweight web component library that provides data-binding and extended capabilities for components, using es6 native class inheritance.&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://stenciljs.com/&quot;&gt;Stencil&lt;/a&gt; is an opensource compiler that generates standards-compliant web components.&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://github.com/mdn/web-components-examples&quot;&gt;Examples&lt;/a&gt;: The following examples are available:&lt;/p&gt; 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/mdn/web-components-examples/blob/main/composed-composed-path&quot;&gt;composed-composed-path&lt;/a&gt;. A very simple example that shows the behavior of the &lt;code&gt;Event&lt;/code&gt; object &lt;code&gt;composed&lt;/code&gt; and &lt;code&gt;composedPath&lt;/code&gt; properties. &lt;a href=&quot;https://mdn.github.io/web-components-examples/composed-composed-path/&quot;&gt;See composed-composed-path live&lt;/a&gt;.&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/mdn/web-components-examples/blob/main/defined-pseudo-class&quot;&gt;defined-pseudo-class&lt;/a&gt;. A very simple example that shows how the &lt;code&gt;[:defined pseudo-class](https://developer.mozilla.org/en-US/docs/Web/CSS/:defined)&lt;/code&gt; works. &lt;a href=&quot;https://mdn.github.io/web-components-examples/defined-pseudo-class/&quot;&gt;See defined-pseudo-class live&lt;/a&gt;.&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/mdn/web-components-examples/blob/main/editable-list&quot;&gt;editable-list&lt;/a&gt; –&amp;nbsp;&lt;code&gt;&amp;lt;editable-list&amp;gt;&lt;/code&gt;. A simple example showing how elements can be consolidated to create a list with addable/removable items. Items are added by using a &lt;code&gt;list-item&lt;/code&gt; attribute or by entering text and clicking the plus sign. &lt;a href=&quot;https://mdn.github.io/web-components-examples/editable-list/&quot;&gt;See editable-list live&lt;/a&gt;.&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/mdn/web-components-examples/blob/main/edit-word&quot;&gt;edit-word&lt;/a&gt; — &lt;code&gt;&amp;lt;edit-word&amp;gt;&lt;/code&gt;. Wrapping one or more words in this element means that you can then click/focus the element to reveal a text input that can then be used to edit the word(s). &lt;a href=&quot;https://mdn.github.io/web-components-examples/edit-word/&quot;&gt;See edit-word live&lt;/a&gt;.&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/mdn/web-components-examples/blob/main/element-details&quot;&gt;element-details&lt;/a&gt; — &lt;code&gt;&amp;lt;element-details&amp;gt;&lt;/code&gt;. Displays a box containing an HTML element name and description. Provides an example of an autonomous custom element that gets its structure from a &lt;code&gt;&amp;lt;template&amp;gt;&lt;/code&gt; element (that also has its own styling defined), and also contains &lt;code&gt;&amp;lt;slot&amp;gt;&lt;/code&gt; elements populated at runtime. &lt;a href=&quot;https://mdn.github.io/web-components-examples/element-details/&quot;&gt;See element-details live&lt;/a&gt;.&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/mdn/web-components-examples/blob/main/expanding-list-web-component&quot;&gt;expanding-list-web-component&lt;/a&gt; — &lt;code&gt;&amp;lt;ul is=&quot;expanding-list&quot;&amp;gt;&lt;/code&gt;. Creates an unordered list with expandable/collapsible children. Provides an example of a customized built-in element (the class inherits from &lt;code&gt;HTMLUListElement&lt;/code&gt; rather than &lt;code&gt;HTMLElement&lt;/code&gt;). &lt;a href=&quot;https://mdn.github.io/web-components-examples/expanding-list-web-component/&quot;&gt;See expanding-list live&lt;/a&gt;.&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/mdn/web-components-examples/blob/main/life-cycle-callbacks&quot;&gt;life-cycle-callbacks&lt;/a&gt; — &lt;code&gt;&amp;lt;custom-square l=&quot;&quot; c=&quot;&quot;&amp;gt;&lt;/code&gt;. A trivial example web component that creates a square colored box on the page. The demo also includes buttons to create, destroy, and change attributes on the element, to demonstrate how the &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/Web_Components/Using_custom_elements#Using_the_lifecycle_callbacks&quot;&gt;web components life cycle callbacks&lt;/a&gt; work &lt;a href=&quot;https://mdn.github.io/web-components-examples/life-cycle-callbacks/&quot;&gt;See life-cycle-callbacks live&lt;/a&gt;.&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/mdn/web-components-examples/blob/main/popup-info-box-web-component&quot;&gt;popup-info-box-web-component&lt;/a&gt; — &lt;code&gt;&amp;lt;popup-info img=&quot;&quot; text=&quot;&quot;&amp;gt;&lt;/code&gt;. Creates an info icon that when focused displays a popup info box. Provides an example of an autonomous custom element that takes information from its attributes, and defines structure and basic style in an attached shadow DOM. &lt;a href=&quot;https://mdn.github.io/web-components-examples/popup-info-box-web-component/&quot;&gt;See popup-info-box live&lt;/a&gt;.&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/mdn/web-components-examples/blob/main/simple-template&quot;&gt;simple-template&lt;/a&gt; — A very simple trivial example that quickly demonstrates usage of the &lt;code&gt;&amp;lt;template&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;slot&amp;gt;&lt;/code&gt; elements. &lt;a href=&quot;https://mdn.github.io/web-components-examples/simple-template/&quot;&gt;See simple-template live&lt;/a&gt;.&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/mdn/web-components-examples/blob/main/slotchange&quot;&gt;slotchange example&lt;/a&gt; — &lt;code&gt;&amp;lt;summary-display&amp;gt;&lt;/code&gt;. An example that takes as its two slot values a list of possible choices, and a description for the selected choice. Multiple paragraphs are included inside the element containing all the possible descriptions; when a choice is clicked, its corresponding description paragraph is given an appropriate slot attribute so that it appears in the second slot. This example is written to demonstrate usage of the slotchange attribute, and features of the HTMLSlotElement interface &lt;a href=&quot;https://mdn.github.io/web-components-examples/slotchange&quot;&gt;See the slotchange example live&lt;/a&gt;.&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/mdn/web-components-examples/blob/main/slotted-pseudo-element&quot;&gt;slotted-pseudo-element&lt;/a&gt;. A very simple example that shows how the &lt;code&gt;::slotted&lt;/code&gt; pseudo-element works. &lt;a href=&quot;https://mdn.github.io/web-components-examples/slotted-pseudo-element/&quot;&gt;See slotted-pseudo-element live&lt;/a&gt;.&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/mdn/web-components-examples/blob/main/word-count-web-component&quot;&gt;word-count-web-component&lt;/a&gt; — &lt;code&gt;&amp;lt;word-count&amp;gt;&lt;/code&gt;. When added to an element, counts all the words inside that element and displays them inside an attached shadow DOM. It also contains an interval that periodically updates the word count as it changes. Provides an example of a customized built-in element (the class inherits from &lt;code&gt;HTMLParagraphElement&lt;/code&gt; rather than &lt;code&gt;HTMLElement&lt;/code&gt;). &lt;a href=&quot;https://mdn.github.io/web-components-examples/word-count-web-component/&quot;&gt;See word-count live&lt;/a&gt;.&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://gomakethings.com/my-html-web-component-boilerplate-for-2026/&quot;&gt;My HTML Web Component boilerplate&lt;/a&gt;: the &lt;a href=&quot;https://gomakethings.com/snippets/boilerplates/web-component/&quot;&gt;boilerplate&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Components (&quot;Standalones&quot;)&lt;/p&gt; 
  &lt;ul&gt; 
   &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://genericcomponents.netlify.app/&quot;&gt;&quot;Generic&quot;&lt;/a&gt;:&lt;/p&gt; 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://genericcomponents.netlify.app/demo/demo-app&quot;&gt;showcase app&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://genericcomponents.netlify.app/generic-accordion/demo/&quot;&gt;generic-accordion&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://genericcomponents.netlify.app/generic-alert/demo/&quot;&gt;generic-alert&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://genericcomponents.netlify.app/generic-dialog/demo/&quot;&gt;generic-dialog&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://genericcomponents.netlify.app/generic-disclosure/demo/&quot;&gt;generic-disclosure&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://genericcomponents.netlify.app/generic-listbox/demo/&quot;&gt;generic-listbox&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://genericcomponents.netlify.app/generic-radio/demo/&quot;&gt;generic-radio&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://genericcomponents.netlify.app/generic-skiplink/demo/&quot;&gt;generic-skiplink&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://genericcomponents.netlify.app/generic-spinner/demo/&quot;&gt;generic-spinner&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://genericcomponents.netlify.app/generic-switch/demo/&quot;&gt;generic-switch&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://genericcomponents.netlify.app/generic-tabs/demo/&quot;&gt;generic-tabs&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://genericcomponents.netlify.app/generic-visually-hidden/demo/&quot;&gt;generic-visually-hidden&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;Extensions: Web Components that extend or add to an existing semantic element.&lt;/p&gt; 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://codepen.io/levimcg/pen/ZEYapRY&quot;&gt;&lt;code&gt;&amp;lt;accordion-container&amp;gt;&lt;/code&gt;&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://github.com/andrico1234/autosize-textarea&quot;&gt;&lt;code&gt;&amp;lt;autosize-textarea&amp;gt;&lt;/code&gt;&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://github.com/github/details-dialog-element&quot;&gt;&lt;code&gt;&amp;lt;details-dialog&amp;gt;&lt;/code&gt;&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://github.com/github/details-menu-element&quot;&gt;&lt;code&gt;&amp;lt;details-menu&amp;gt;&lt;/code&gt;&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://github.com/zachleat/details-utils&quot;&gt;&lt;code&gt;&amp;lt;details-utils&amp;gt;&lt;/code&gt;&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://darn.es/heading-anchors-web-component&quot;&gt;&lt;code&gt;&amp;lt;heading-anchors&amp;gt;&lt;/code&gt;&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://image-compare-component.netlify.app&quot;&gt;&lt;code&gt;&amp;lt;image-compare&amp;gt;&lt;/code&gt;&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://darn.es/link-peek-web-component&quot;&gt;&lt;code&gt;&amp;lt;link-peek&amp;gt;&lt;/code&gt;&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://github.com/rg-wood/link-preview&quot;&gt;&lt;code&gt;&amp;lt;link-preview&amp;gt;&lt;/code&gt;&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://github.com/github/time-elements&quot;&gt;&lt;code&gt;&amp;lt;local-time&amp;gt;&lt;/code&gt;&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://darn.es/play-button-web-component&quot;&gt;&lt;code&gt;&amp;lt;play-button&amp;gt;&lt;/code&gt;&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://darn.es/random-source-web-component&quot;&gt;&lt;code&gt;&amp;lt;random-source&amp;gt;&lt;/code&gt;&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://github.com/github/time-elements&quot;&gt;&lt;code&gt;&amp;lt;relative-time&amp;gt;&lt;/code&gt;&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://darn.es/share-button-web-component&quot;&gt;&lt;code&gt;&amp;lt;share-button&amp;gt;&lt;/code&gt;&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://stephen.band/slide-show/&quot;&gt;&lt;code&gt;&amp;lt;slide-show&amp;gt;&lt;/code&gt;&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://github.com/github/tab-container-element&quot;&gt;&lt;code&gt;&amp;lt;tab-container&amp;gt;&lt;/code&gt;&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://github.com/github/task-lists-element&quot;&gt;&lt;code&gt;&amp;lt;task-lists&amp;gt;&lt;/code&gt;&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://github.com/github/time-elements&quot;&gt;&lt;code&gt;&amp;lt;time-ago&amp;gt;&lt;/code&gt;&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;Form: Web Components that are, or can be used with, form submissions.&lt;/p&gt; 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://github.com/lamplightdev/aeon&quot;&gt;&lt;code&gt;&amp;lt;aeon-datepicker&amp;gt;&lt;/code&gt;&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://github.com/RamseyInHouse/feedback-component&quot;&gt;&lt;code&gt;&amp;lt;feedback-component&amp;gt;&lt;/code&gt;&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://github.com/GoogleChromeLabs/file-drop&quot;&gt;&lt;code&gt;&amp;lt;file-drop&amp;gt;&lt;/code&gt;&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://github.com/GoogleChromeLabs/input-knob&quot;&gt;&lt;code&gt;&amp;lt;input-knob&amp;gt;&lt;/code&gt;&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://github.com/andreruffert/range-slider-element&quot;&gt;&lt;code&gt;&amp;lt;range-slider&amp;gt;&lt;/code&gt;&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://github.com/sunnywalker/show-password-toggle&quot;&gt;&lt;code&gt;&amp;lt;show-password-toggle&amp;gt;&lt;/code&gt;&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://codepen.io/nonsalant/pen/OPJLJoL&quot;&gt;&lt;code&gt;&amp;lt;toggle-categories&amp;gt;&lt;/code&gt;&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://jquery.github.io/typesense-minibar/demo/&quot;&gt;&lt;code&gt;&amp;lt;typesense-minibar&amp;gt;&lt;/code&gt;&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;Utility: Useful little Web Components.&lt;/p&gt; 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://oddbird.github.io/browser-support/&quot;&gt;&lt;code&gt;&amp;lt;browser-support&amp;gt;&lt;/code&gt;&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://github.com/github/clipboard-copy-element&quot;&gt;&lt;code&gt;&amp;lt;clipboard-copy&amp;gt;&lt;/code&gt;&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://darn.es/duration-property-web-component&quot;&gt;&lt;code&gt;&amp;lt;duration-property&amp;gt;&lt;/code&gt;&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://github.com/sakamies/filter-element&quot;&gt;&lt;code&gt;&amp;lt;filter-&amp;gt;&lt;/code&gt;&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://darn.es/is-playing-web-component&quot;&gt;&lt;code&gt;&amp;lt;is-playing&amp;gt;&lt;/code&gt;&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://darn.es/live-filter-web-component&quot;&gt;&lt;code&gt;&amp;lt;live-filter&amp;gt;&lt;/code&gt;&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://github.com/knowler/log-form-element&quot;&gt;&lt;code&gt;&amp;lt;log-form&amp;gt;&lt;/code&gt;&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://codepen.io/nonsalant/pen/yyBmeBp&quot;&gt;&lt;code&gt;&amp;lt;print-button&amp;gt;&lt;/code&gt;&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://darn.es/sample-input-web-component&quot;&gt;&lt;code&gt;&amp;lt;sample-input&amp;gt;&lt;/code&gt;&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://slide-deck.netlify.app/&quot;&gt;&lt;code&gt;&amp;lt;slide-deck&amp;gt;&lt;/code&gt;&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://darn.es/storage-form-web-component&quot;&gt;&lt;code&gt;&amp;lt;storage-form&amp;gt;&lt;/code&gt;&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://jamesbasoo.com/visual-viewport/&quot;&gt;&lt;code&gt;&amp;lt;visual-viewport&amp;gt;&lt;/code&gt;&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;Media: Web Components that are, or can be used with, media of any kind.&lt;/p&gt; 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://darn.es/bluesky-post-web-component&quot;&gt;&lt;code&gt;&amp;lt;bluesky-post&amp;gt;&lt;/code&gt;&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://darn.es/bluesky-replies-web-component&quot;&gt;&lt;code&gt;&amp;lt;bluesky-replies&amp;gt;&lt;/code&gt;&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://darn.es/code-pen-web-component&quot;&gt;&lt;code&gt;&amp;lt;code-pen&amp;gt;&lt;/code&gt;&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://github.com/paulirish/lite-youtube-embed&quot;&gt;&lt;code&gt;&amp;lt;lite-youtube&amp;gt;&lt;/code&gt;&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://darn.es/mastodon-post-web-component&quot;&gt;&lt;code&gt;&amp;lt;mastodon-post&amp;gt;&lt;/code&gt;&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://github.com/GoogleWebComponents/model-viewer&quot;&gt;&lt;code&gt;&amp;lt;model-viewer&amp;gt;&lt;/code&gt;&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://github.com/GoogleChromeLabs/pinch-zoom&quot;&gt;&lt;code&gt;&amp;lt;pinch-zoom&amp;gt;&lt;/code&gt;&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://mirisuzanne.github.io/track-list/demo.html&quot;&gt;&lt;code&gt;&amp;lt;track-list&amp;gt;&lt;/code&gt;&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://github.com/GoogleChromeLabs/two-up&quot;&gt;&lt;code&gt;&amp;lt;two-up&amp;gt;&lt;/code&gt;&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://youtube-player.alanwsmith.com/&quot;&gt;&lt;code&gt;&amp;lt;youtube-player&amp;gt;&lt;/code&gt;&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;Design: Web Components that help with visual presentation.&lt;/p&gt; 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://github.com/GoogleChromeLabs/dark-mode-toggle&quot;&gt;&lt;code&gt;&amp;lt;dark-mode-toggle&amp;gt;&lt;/code&gt;&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://github.com/compmeist/easy-row&quot;&gt;&lt;code&gt;&amp;lt;easy-row&amp;gt;&lt;/code&gt;&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://github.com/lekoala/flex-grid&quot;&gt;&lt;code&gt;&amp;lt;flex-grid&amp;gt;&lt;/code&gt;&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://github.com/sakamies/conditional-elements&quot;&gt;&lt;code&gt;&amp;lt;if-/or-/else-&amp;gt;&lt;/code&gt;&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://github.com/lekoala/last-icon&quot;&gt;&lt;code&gt;&amp;lt;l-i&amp;gt;&lt;/code&gt;&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://github.com/ingmarh/scroll-shadow-element&quot;&gt;&lt;code&gt;&amp;lt;scroll-shadow&amp;gt;&lt;/code&gt;&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;Custom: Frequently-solved problems in web component form.&lt;/p&gt; 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://github.com/mattdsteele/bt-device&quot;&gt;&lt;code&gt;&amp;lt;bt-device&amp;gt;&lt;/code&gt;&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://www.npmjs.com/package//html-include-element&quot;&gt;&lt;code&gt;&amp;lt;html-include&amp;gt;&lt;/code&gt;&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://github.com/justinfagnani/katex-elements&quot;&gt;&lt;code&gt;&amp;lt;katex-display&amp;gt;&lt;/code&gt;&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://github.com/andrico1234/no-spoilers&quot;&gt;&lt;code&gt;&amp;lt;no-spoilers&amp;gt;&lt;/code&gt;&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://github.com/Noleli/place-holder&quot;&gt;&lt;code&gt;&amp;lt;place-holder&amp;gt;&lt;/code&gt;&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://github.com/pwa-builder/pwa-install&quot;&gt;&lt;code&gt;&amp;lt;pwa-install&amp;gt;&lt;/code&gt;&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;Novelty&lt;/p&gt; 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://wbrowar.com/web-components/admin-bar-component&quot;&gt;&lt;code&gt;&amp;lt;admin-bar&amp;gt;&lt;/code&gt;&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://justinfagnani.github.io/chessboard-element/&quot;&gt;&lt;code&gt;&amp;lt;chess-board&amp;gt;&lt;/code&gt;&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://darn.es/contrast-details-web-component&quot;&gt;&lt;code&gt;&amp;lt;contrast-details&amp;gt;&lt;/code&gt;&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://noahliebman.net/projects/plucky-underline/&quot;&gt;&lt;code&gt;&amp;lt;plucky-underline&amp;gt;&lt;/code&gt;&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://github.com/erikkroes/spacer-gif&quot;&gt;&lt;code&gt;&amp;lt;spacer-gif&amp;gt;&lt;/code&gt;&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://github.com/grislyeye/vellum-dice&quot;&gt;&lt;code&gt;&amp;lt;vellum-dice&amp;gt;&lt;/code&gt;&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;Accessible: (from &lt;a href=&quot;https://scottaohara.github.io/accessible_components/&quot;&gt;https://scottaohara.github.io/accessible_components/&lt;/a&gt;) I&apos;ve &lt;em&gt;[sic]&lt;/em&gt; built a good handful of accessible markup patterns and widgets at this point. Most of which were bespoke and incorporated into websites/products. But, there are a baseline patterns I was able to use over and over again, and the following represent the most common widgets that I was able to distill into basic examples (i.e., vanicall html/css/js). Each was based on testing with users, UX and design needs from those past projects, and from following normative specifications &amp;amp; informative notes.&lt;/p&gt; 
    &lt;ul&gt; 
     &lt;li&gt;&lt;a href=&quot;https://github.com/scottaohara/accessible_accordions&quot;&gt;Accordions (v3)&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://github.com/scottaohara/aria-links&quot;&gt;ARIA Links (v2)&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://github.com/scottaohara/a11y_button&quot;&gt;ARIA Buttons (v2)&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://github.com/scottaohara/a11y_breadcrumbs&quot;&gt;Breadcrumb Navigation (v1.1)&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://github.com/scottaohara/clear-text-field-button&quot;&gt;Clear text field buttons (v1)&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://github.com/scottaohara/aria_disclosure_widget&quot;&gt;Disclosure Widgets (v2.0.1)&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://github.com/scottaohara/landmarks_demo&quot;&gt;Landmarks Demonstration&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://github.com/scottaohara/accessible_modal_window&quot;&gt;Modal Dialogs (v3 - archived)&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://github.com/scottaohara/a11y_switch_web_component&quot;&gt;Switch Toggle Web Component (v0)&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://github.com/scottaohara/aria-switch-button&quot;&gt;Switch Toggles (v2.0.1)&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://github.com/scottaohara/a11y_tab_widget&quot;&gt;Tab Widgets (v2)&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://github.com/scottaohara/a11y_tooltips&quot;&gt;Tooltips (v1)&lt;/a&gt;&lt;/li&gt; 
     &lt;li&gt;&lt;a href=&quot;https://github.com/scottaohara/a11y_styled_form_controls&quot;&gt;Various Styled Form Controls&lt;/a&gt;&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Reading&lt;/h2&gt; 
&lt;h3&gt;Articles/Blog Posts&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://dev.to/ryansolid/web-components-are-not-the-future-48bh&quot;&gt;&quot;WebComponents are not the future&quot;&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://dev.to/besworks/the-hidden-power-of-web-components-1jei&quot;&gt;&quot;The Hidden Power of WebComponents&quot;&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://dev.to/besworks/the-problem-with-web-components-4f8&quot;&gt;&quot;The Problem with WebComponents&quot;&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://kinsta.com/blog/web-components/&quot;&gt;&quot;A Complete Introduction to WebComponents&quot;&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://thenewstack.io/web-components-are-the-comeback-nobody-saw-coming/&quot;&gt;&quot;Web Components are the Comback Nobody Saw Coming&quot;&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://frontendmasters.com/blog/the-missing-link-for-web-components/&quot;&gt;The Missing Link for Web Components&lt;/a&gt;:&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>JustPy</title>
      <link>https://tedneward.github.io/Research/presentation/python/justpy/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/python/justpy/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://justpy.io/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/justpy-org/justpy&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;With a few lines of only Python code, you can create interactive websites without any JavaScript programming. JustPy can also be used to create graphic user interfaces for Python programs.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;NOTE:&lt;/strong&gt; &quot;justpy has been a great project and our goal to reach 1000 stars soon was reached now.&lt;br&gt; Given that nicegui is somewhat of a fork of justpy and is much more successful with &amp;gt;4000 stars there is not much use to try to build on justpy and move it further. Therefore I intend to close most issues now that ask for enhancements pointing to nicegui as an alternative that might implement these features and concentrate on helping people migrate to nicegui or keep their existing justpy code running for a while. justpy 0.13 seems to be sufficiently stable to not cause too many worries.&quot;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>q5JS</title>
      <link>https://tedneward.github.io/Research/presentation/q5xjs/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/q5xjs/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://q5xjs.netlify.app/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/LingDong-/q5xjs&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Qwik</title>
      <link>https://tedneward.github.io/Research/presentation/qwik/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/qwik/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/builderio/qwik&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;From the blog:&lt;br&gt; - &lt;a href=&quot;https://dev.to/mhevery/a-first-look-at-qwik-the-html-first-framework-af&quot;&gt;First look&lt;/a&gt;&lt;br&gt; - &lt;a href=&quot;https://dev.to/mhevery/death-by-closure-and-how-qwik-solves-it-44jj&quot;&gt;Death by closure&lt;/a&gt;&lt;br&gt; - &lt;a href=&quot;https://dev.to/mhevery/html-first-javascript-last-the-secret-to-web-speed-4ic9&quot;&gt;HTML first, JS last&lt;/a&gt;&lt;br&gt; - &lt;a href=&quot;https://dev.to/mhevery/qwik-the-answer-to-optimal-fine-grained-lazy-loading-2hdp&quot;&gt;Answer to optimal fine-grained loading&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Elemental UI</title>
      <link>https://tedneward.github.io/Research/presentation/react/elemental-ui/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/react/elemental-ui/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;http://elemental-ui.com/&quot;&gt;Website&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Tanstack</title>
      <link>https://tedneward.github.io/Research/presentation/react/tanstack/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/react/tanstack/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://tanstack.com&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/tanstack&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;h2&gt;Features/Contents&lt;/h2&gt; 
&lt;p&gt;Data and State Management&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;TanStack Start: Full-stack Framework powered by TanStack Router for React and Solid&lt;/li&gt; 
 &lt;li&gt;TanStack Router: A powerful React router for client-side and full-stack react applications. Fully type-safe APIs, first-class search-params for managing state in the URL and seamless integration with the existing React ecosystem.&lt;/li&gt; 
 &lt;li&gt;TanStack Query: Powerful asynchronous state management, server-state utilities and data fetching. Fetch, cache, update, and wrangle all forms of async data in your TS/JS, React, Vue, Solid, Svelte &amp;amp; Angular applications all without touching any &quot;global state&quot;&lt;/li&gt; 
 &lt;li&gt;TanStack DB: TanStack DB extends TanStack Query with collections, live queries and optimistic mutations that keep your UI reactive, consistent and blazing fast&lt;/li&gt; 
 &lt;li&gt;TanStack Store: The immutable-reactive data store that powers the core of TanStack libraries and their framework adapters.&lt;/li&gt; 
 &lt;li&gt;TanStack Pacer: Optimize your application&apos;s performance with TanStack Pacer&apos;s core primitives: Debouncing, Throttling, Rate Limiting, Queuing, and Batching.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;Headless UI&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;TanStack Table: Supercharge your tables or build a datagrid from scratch for TS/JS, React, Vue, Solid, Svelte, Qwik, Angular, and Lit while retaining 100% control over markup and styles.&lt;/li&gt; 
 &lt;li&gt;TanStack Form: Headless, performant, and type-safe form state management for TS/JS, React, Vue, Angular, Solid, Lit and Svelte.&lt;/li&gt; 
 &lt;li&gt;TanStack Virtual: Virtualize only the visible content for massive scrollable DOM nodes at 60FPS in TS/JS, React, Vue, Solid, Svelte, Lit &amp;amp; Angular while retaining 100% control over markup and styles.&lt;/li&gt; 
 &lt;li&gt;TanStack Ranger: Headless, lightweight, and extensible primitives for building range and multi-range sliders.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;Other&lt;br&gt; * TanStack Devtools: A unified devtools panel that houses all TanStack devtools and allows you to create and integrate your own custom devtools.&lt;br&gt; * TanStack Config: Configuration and tools for publishing and maintaining high-quality JavaScript packages. Opinionated tooling to lint, build, test, version, and publish JS/TS packages — minimal config, consistent results.&lt;/p&gt; 
&lt;h2&gt;Reading&lt;/h2&gt; 
&lt;h3&gt;Articles&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.freecodecamp.org/news/how-to-build-a-crud-app-with-tanstack-start-and-tanstackdb-with-rxdb-integration/&quot;&gt;How to Build a CRUD App with TanStack Start and TanStackDB (with RxDB Integration)&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Responsive Grid System</title>
      <link>https://tedneward.github.io/Research/presentation/responsivegridsystem/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/responsivegridsystem/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;http://www.responsivegridsystem.com/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/grahammiller/ResponsiveGridSystem&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Ruffle</title>
      <link>https://tedneward.github.io/Research/presentation/ruffle/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/ruffle/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://ruffle.rs/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/ruffle-rs/ruffle&quot;&gt;Github&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Sencha (ExtJS)</title>
      <link>https://tedneward.github.io/Research/presentation/sencha/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/sencha/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.sencha.com/products/extjs/&quot;&gt;Website&lt;/a&gt; | Commercial--no source&lt;/p&gt; 
&lt;h2&gt;Sencha Tools&lt;/h2&gt; 
&lt;p&gt;Sencha Architect: Build Ext JS applications using drag-and-drop features and spend less time on manual coding.&lt;/p&gt; 
&lt;p&gt;Sencha Themer: Design customized application themes using graphical tools — without writing code.&lt;/p&gt; 
&lt;p&gt;IDE and Code Editor Plugins: integrate Sencha frameworks into your enterprise workflow, enabling code completion, inspection, generation, navigation, refactoring and more.&lt;/p&gt; 
&lt;p&gt;ExtGen: a node based cross-platform command line tool that provides multiple modes for application generation.&lt;/p&gt; 
&lt;p&gt;ExtBuild: a new node based tool to build Ext JS applications that currently uses Sencha Cmd and Google Closure compiler for building and transpiling Ext JS applications.&lt;/p&gt; 
&lt;p&gt;Sencha Fiddle: a free tool that allows you to try Ext JS code in your browser without downloading or installing anything. You can easily share your Ext JS code by saving and sharing fiddle URLs.&lt;/p&gt; 
&lt;p&gt;Sencha Cmd: A full set of lifecycle management features including scaffolding, code minification, transpilation from ES6, dynamic package loading, build generation for PWAs and more.&lt;/p&gt; 
&lt;p&gt;Inspector: Debugging tool that provides direct access to components, classes, objects, and more for apps built using Sencha frameworks.&lt;/p&gt; 
&lt;p&gt;Sencha Stencils: a complete UI asset kit for Adobe Illustrator, Sketch, Balsamiq and is also available as SVG/PNG for use with other programs.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>SimpleMDE</title>
      <link>https://tedneward.github.io/Research/presentation/simplemde/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/simplemde/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://simplemde.com/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/sparksuite/simplemde-markdown-editor&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>SMenu</title>
      <link>https://tedneward.github.io/Research/presentation/smenu/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/smenu/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/p-gen/smenu&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;smenu is a selection filter just like sed is an editing filter.&lt;/p&gt; 
&lt;p&gt;This tool reads words from standard input or from a file, and presents them to the terminal screen in different layouts in a scrolling window. A cursor, easily moved using the keyboard and/or the mouse, makes it possible to select one or more words.&lt;/p&gt; 
&lt;p&gt;Note that the screen is not cleared at the start and end of smenu execution. The selection window is displayed at the cursor position, and the previous contents of the terminal are neither modified nor lost.&lt;/p&gt; 
&lt;p&gt;I&apos;ve tried to make it as easy to use as possible. It should work on all terminals managed in the terminfo database.&lt;/p&gt; 
&lt;p&gt;UTF-8 encoding is supported. This support includes double-width characters and extended grapheme clusters. The latter is still experimental, however, and works much better if appropriate terminals such as WezTerm or iTerm are used.&lt;/p&gt; 
&lt;p&gt;The encoding of UTF-8 glyphs must also be in canonical form, as no effort will be made to put them in this form.&lt;/p&gt; 
&lt;p&gt;Please refer to the included man page to find out more about this little program.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Static Site Generators list</title>
      <link>https://tedneward.github.io/Research/presentation/static-site-generators/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/static-site-generators/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://staticsitegenerators.net/&quot;&gt;Website&lt;/a&gt;&lt;/p&gt; 
&lt;h3&gt;JVM&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/jbake-org/jbake&quot;&gt;jbake&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/agrison/jssg&quot;&gt;jssg&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Blogs&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.11ty.io/&quot;&gt;11ty&lt;/a&gt; - Eleventy is a simpler static site generator. - &lt;code&gt;#JavaScript&lt;/code&gt; &lt;code&gt;#Node.js&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://ablog.readthedocs.org/&quot;&gt;ABlog&lt;/a&gt; - A Sphinx extension that converts any documentation or personal website project into a full-fledged blog. - &lt;code&gt;#Python&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://adduce.vale.rocks&quot;&gt;Adduce&lt;/a&gt; - A versatile static site generator that handles both blogs and standard pages. - &lt;code&gt;#Rust&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://github.com/atas/ssg&quot;&gt;Ata&apos;s SSG&lt;/a&gt; - A PHP-based blog-aware vanilla-HTML static site generator for GitHub Pages with markdown support.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/capjamesg/aurora&quot;&gt;Aurora&lt;/a&gt; - An extensible, Python-based static site generator with support for jinja2 and markdown templates. - &lt;code&gt;#Python&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/cfenollosa/bashblog&quot;&gt;BashBlog&lt;/a&gt; - A single Bash script to create blogs. - &lt;code&gt;#Bash&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/venthur/blag&quot;&gt;Blag&lt;/a&gt; - blag is a blog-aware, static site generator -- it uses Markdown and is written in Python. - &lt;code&gt;#Python&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/tesar-tech/BlazorStatic&quot;&gt;BlazorStatic&lt;/a&gt; - Use ASP.NET Blazor to generate static pages. - &lt;code&gt;#.NET&lt;/code&gt; &lt;code&gt;#C#&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://code.rosaelefanten.org/blogcpp/&quot;&gt;BlogC++&lt;/a&gt; - A static blog generator, written in C++17. - &lt;code&gt;#C++&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://bloggrify.com/&quot;&gt;Bloggrify&lt;/a&gt; - A static blog generator using Markdown, built on top of Nuxt-Content. - &lt;code&gt;#Vue.js&lt;/code&gt; &lt;code&gt;#Markdown&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://cobalt-org.github.io&quot;&gt;Cobalt&lt;/a&gt; - A Rust static site generator. - &lt;code&gt;#Rust&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/coleslaw-org/coleslaw&quot;&gt;Coleslaw&lt;/a&gt; - Flexible blog and site generator with a lot of plugins. - &lt;code&gt;#CommonLisp&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/spekulatius/laravel-commonmark-blog&quot;&gt;CommonMark Blog for Laravel&lt;/a&gt; - Static generator to use with Laravel projects. Uses CommonMark and FrontMatter to generate and publish files in the &lt;code&gt;public&lt;/code&gt;-folder. Supports articles as well as listing pages &lt;code&gt;#PHP&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://franklinjl.org/&quot;&gt;Franklin&lt;/a&gt; - A static site generator written in Julia that is primarily intended for technical blogging. - &lt;code&gt;#Julia&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/imfunniee/gitfolio&quot;&gt;Gitfolio&lt;/a&gt; - A portfolio website where you could showcase your work + a blog that will help you spread your ideas into real world. - &lt;code&gt;#Node.js&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/dannyvankooten/gozer&quot;&gt;Gozer&lt;/a&gt; - Simple &amp;amp; fast static site generator in a single static binary. - &lt;code&gt;#Go&lt;/code&gt; &lt;code&gt;#Golang&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/hexojs/hexo&quot;&gt;Hexo&lt;/a&gt; - A fast, simple &amp;amp; powerful blog framework. - &lt;code&gt;#JavaScript&lt;/code&gt; &lt;code&gt;#Node.js&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/hyde/hyde&quot;&gt;Hyde&lt;/a&gt; - &lt;code&gt;#Python&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/hydephp/hyde&quot;&gt;HydePHP&lt;/a&gt; - Elegant and powerful static site generator with rich support for blogs, documentation sites, and more using Markdown and/or Blade - &lt;code&gt;#PHP&lt;/code&gt; &lt;code&gt;#Laravel&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.jamify.org/&quot;&gt;Jamify Gatsby&lt;/a&gt; - Publish flaring fast blogs with Gatsby and Ghost. - &lt;code&gt;#JavaScript&lt;/code&gt; &lt;code&gt;#React&lt;/code&gt; &lt;code&gt;#Gastby&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/styxlab/next-cms-ghost&quot;&gt;Jamify NextJS&lt;/a&gt; - Publish flaring fast blogs with Next.js and Ghost. - &lt;code&gt;#JavaScript&lt;/code&gt; &lt;code&gt;#React&lt;/code&gt; &lt;code&gt;#Next.js&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/jekyll/jekyll&quot;&gt;Jekyll&lt;/a&gt; - Jekyll is a simple, blog-aware, static site generator perfect for personal, project, or organization sites. - &lt;code&gt;#Ruby&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/kabukky/journey&quot;&gt;Journey&lt;/a&gt; - &lt;code&gt;#Go&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/sunainapai/makesite&quot;&gt;Makesite&lt;/a&gt; - Simple, lightweight, and magic-free static site/blog generator (&amp;lt; 130 lines) for Python coders &lt;code&gt;#Python&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://mkws.sh&quot;&gt;mkws&lt;/a&gt; - simple static site generator &lt;code&gt;#sh&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://getnikola.com/&quot;&gt;Nikola&lt;/a&gt; - &lt;code&gt;#Python&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/imathis/octopress&quot;&gt;Octopress&lt;/a&gt; - Similar to Jekyll but where everything you need is already setup. - &lt;code&gt;#Ruby&lt;/code&gt; &lt;code&gt;#Jekyll&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://orchid.netlify.app&quot;&gt;Orchid Posts&lt;/a&gt; - Add Jekyll-like blogging functionality to your Orchid site. - &lt;code&gt;#Orchid&lt;/code&gt; &lt;code&gt;#Java&lt;/code&gt; &lt;code&gt;#Kotlin&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/getpelican/pelican&quot;&gt;Pelican&lt;/a&gt; - Uses Markdown or ReST for content and Jinja2 for themes. - &lt;code&gt;#Python&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://prpl.dev&quot;&gt;PRPL&lt;/a&gt; - A modular static site generator built for longevity - &lt;code&gt;#TypeScript&lt;/code&gt; &lt;code&gt;#JavaScript&lt;/code&gt; &lt;code&gt;#Node.js&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.qgoda.net/&quot;&gt;Qgoda&lt;/a&gt; - Arbitrary taxonomies and cross-links, multi-lingua. - &lt;code&gt;#Perl&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://quartz.jzhao.xyz/&quot;&gt;Quartz&lt;/a&gt; - Batteries-included extensible Markdown renderer for your digital garden, complete with GH Pages integration and RSS. - &lt;code&gt;#TypeScript&lt;/code&gt; &lt;code&gt;#Node.js&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/williamd1k0/sake&quot;&gt;Sake&lt;/a&gt; - A simple static site generator built with make. - &lt;code&gt;#make&lt;/code&gt; &lt;code&gt;#Jinja2&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://dalgona.github.io/Serum/&quot;&gt;Serum&lt;/a&gt; - Serum is a static website generator written in Elixir Programming Language. - &lt;code&gt;#Elixir&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://sphido.cz&quot;&gt;Sphido&lt;/a&gt; - A rocket 🚀 fast, lightweight, static site generator &lt;code&gt;#Node.js&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/spress/Spress/&quot;&gt;Spress&lt;/a&gt; - &lt;code&gt;#PHP&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.stapy.net&quot;&gt;Stapy&lt;/a&gt; - Works without any additional package and without command line on Windows. - &lt;code&gt;#Python&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/nakkaya/static&quot;&gt;Static&lt;/a&gt; - Supports org-mode and markdown. - &lt;code&gt;#Clojure&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://preaction.me/statocles/&quot;&gt;Statocles&lt;/a&gt; - Markdown, code highlighting etc. &apos; &lt;code&gt;#Perl&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/vladris/tinkerer&quot;&gt;Tinkerer&lt;/a&gt; - &lt;code&gt;#Python&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/leonstafford&quot;&gt;WP2Static&lt;/a&gt; - WordPress static site generator for security, performance and cost benefits&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://xlog.emadelsaid.com/&quot;&gt;Xlog&lt;/a&gt; - Personal knowledge management application with focus on enriching markdown files and surfacing implicit links between pages.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;CMS&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://ari.se.net&quot;&gt;Arise&lt;/a&gt; - A 90s-web inspired Bash static site generator designed around slow-moving stable dependencies, modular page hierarchy, and cloud-native CI deployment. - &lt;code&gt;#Bash&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://datenstrom.se/yellow/&quot;&gt;Datenstrom Yellow&lt;/a&gt; - For people who make small websites. - &lt;code&gt;#PHP&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.getlektor.com/&quot;&gt;Lektor&lt;/a&gt; - An easy to use static CMS and blog engine. - &lt;code&gt;#Python&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://primo.so&quot;&gt;Primo&lt;/a&gt; - An all-in-one static site builder. - &lt;code&gt;#Svelte&lt;/code&gt; &lt;code&gt;#Electron&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://getpublii.com/&quot;&gt;Publii&lt;/a&gt; - Easy-to-use desktop app to generate static websites. - &lt;code&gt;#JavaScript&lt;/code&gt; &lt;code&gt;#Electron&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://tipe.io/&quot;&gt;Tipe&lt;/a&gt; - An easy to use API-first CMS engine to generate static sites. - &lt;code&gt;#JavaScript&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://wordmogul.com&quot;&gt;Wordmogul&lt;/a&gt; - Minimalistic blogging platform with ZIP export of .md files (GUI for Hugo/Jekyll). - &lt;code&gt;#Go&lt;/code&gt; &lt;code&gt;#Golang&lt;/code&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Courseware&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://sjzeil.github.io/CoWeM/&quot;&gt;CoWeM&lt;/a&gt; &lt;a href=&quot;https://github.com/sjzeil/CoWeM&quot;&gt;Source&lt;/a&gt;: Static site generator for course websites, based on markdown&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Documentation&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://heinventions.github.io/docnado-site&quot;&gt;Docnado&lt;/a&gt; - A rapid documentation tool that will blow you away; batteries and style included. - &lt;code&gt;#Python&lt;/code&gt; &lt;code&gt;#Jinja2&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/docpad/docpad&quot;&gt;DocPad&lt;/a&gt; - &lt;code&gt;#JavaScript&lt;/code&gt; &lt;code&gt;#CoffeeScript&lt;/code&gt; &lt;code&gt;#Node.js&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://docsify.js.org/&quot;&gt;Docsify&lt;/a&gt; - A magical documentation site generator. &lt;code&gt;#JavaScript&lt;/code&gt; &lt;code&gt;#Node.js&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/Doctave/doctave&quot;&gt;Doctave&lt;/a&gt; - A batteries-included developer documentation site generator. - &lt;code&gt;#Rust&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://docusaurus.io/&quot;&gt;Docusaurus&lt;/a&gt; - Easy to maintain open source documentation websites. - &lt;code&gt;#JavaScript&lt;/code&gt; &lt;code&gt;#React&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.mkdocs.org/&quot;&gt;MkDocs&lt;/a&gt; - Write your docs in Markdown and configure the generator with a single YAML configuration file. - &lt;code&gt;#Python&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://orchid.run/plugins/orchidjavadoc&quot;&gt;Orchid Javadoc&lt;/a&gt; - Create beautiful Javadocs for your project within your Orchid site. - &lt;code&gt;#Orchid&lt;/code&gt; &lt;code&gt;#Java&lt;/code&gt; &lt;code&gt;#Kotlin&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/lord/slate&quot;&gt;Slate&lt;/a&gt; - &lt;code&gt;#Ruby&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://sphinx-doc.org/&quot;&gt;Sphinx&lt;/a&gt; - &lt;code&gt;#Python&lt;/code&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Science&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://curvenote.com/docs/web&quot;&gt;Curvenote&lt;/a&gt; - Build scientific and technical websites for books, preprints, papers and reports using MyST Markdown and Jupyter Notebooks - &lt;code&gt;#Node.js&lt;/code&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Marketing&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/Tsukumogami-Software/milou&quot;&gt;Milou&lt;/a&gt; - Create beautiful and informative press kits to showcase your company and products to the medias - &lt;code&gt;#Node.js&lt;/code&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Code Playground&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/shi-yan/codestage&quot;&gt;CodeStage&lt;/a&gt; - A static site generator to create javascript playgrounds / interactive demos.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Frameworks&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;http://assemble.io/&quot;&gt;Assemble&lt;/a&gt; - &lt;code&gt;#JavaScript&lt;/code&gt; &lt;code&gt;#Node.js&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://docs.astro.build/&quot;&gt;Astro&lt;/a&gt; - Framework agnostic static site generator with component-level support for partial hydration on page load, page idle, component visible or none. - &lt;code&gt;#JavaScript&lt;/code&gt; &lt;code&gt;#Node.Js&lt;/code&gt; &lt;code&gt;#React.js&lt;/code&gt; &lt;code&gt;#Vue.js&lt;/code&gt; &lt;code&gt;#Svelte.js&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/blurry-dev/blurry&quot;&gt;Blurry&lt;/a&gt; - Blurry is a schema-first, plugin-enabled static site generator. Markdown front matter directly to Schema.org types, so your content is SEO-friendly and rich results-ready out of the box. - &lt;code&gt;#Python&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.bridgetownrb.com/&quot;&gt;Bridgetown&lt;/a&gt; - A next-generation, progressive site generator &amp;amp; fullstack framework, powered by Ruby. - &lt;code&gt;#Ruby&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/koenbok/Cactus&quot;&gt;Cactus&lt;/a&gt; - &lt;code&gt;#Python&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://capri.build/&quot;&gt;Capri&lt;/a&gt; - Static site generator based on Vite with partial hydration for a variety of frameworks. - &lt;code&gt;#TypeScript&lt;/code&gt; &lt;code&gt;#React.js&lt;/code&gt; &lt;code&gt;#Preact&lt;/code&gt; &lt;code&gt;#Solid&lt;/code&gt; &lt;code&gt;#Vue&lt;/code&gt; &lt;code&gt;#Svelte&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/xy2z/capro&quot;&gt;Capro&lt;/a&gt; - Flexible PHP8 static site generator, using Blade template engine. - &lt;code&gt;#PHP&lt;/code&gt; &lt;code&gt;#Blade&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/badosu/coil&quot;&gt;coil&lt;/a&gt; - &lt;code&gt;#elixir&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://complexity.readthedocs.org/en/latest/&quot;&gt;Complexity&lt;/a&gt; - For those who like to work in HTML. - &lt;code&gt;#Python&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://amokfa.github.io/posts/constexprjs.html&quot;&gt;ConstexprJS&lt;/a&gt; - Evaluate and struo JS in your website ahead of time. - &lt;code&gt;#JavaScript&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://cuttlebelle.com/&quot;&gt;Cuttlebelle&lt;/a&gt; - The react static site generator that separates editing and code concerns. - &lt;code&gt;#JavaScript&lt;/code&gt; &lt;code&gt;#Node.js&lt;/code&gt; &lt;code&gt;#React.js&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/tfpk/dewar&quot;&gt;Dewar&lt;/a&gt; - A flask-like static site generator. - &lt;code&gt;#Python&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://elderguide.com/tech/elderjs/&quot;&gt;Elder.js&lt;/a&gt; - An opinionated, SEO focused, static site generator for Svelte.js. - &lt;code&gt;#JavaScript&lt;/code&gt; &lt;code&gt;#Node.js&lt;/code&gt; &lt;code&gt;#Svelte.js&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/SimonSapin/Frozen-Flask&quot;&gt;Flask-Frozen&lt;/a&gt; - Freezes a Flask application into a set of static files. - &lt;code&gt;#Python&lt;/code&gt; &lt;code&gt;#Flask&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/kobo/gaiden&quot;&gt;Gaiden&lt;/a&gt; - A tool that makes it easy to create documentation with Markdown. - &lt;code&gt;#Groovy&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/gatsbyjs/gatsby&quot;&gt;Gatsby&lt;/a&gt; - &lt;code&gt;#JavaScript&lt;/code&gt; &lt;code&gt;#Node.js&lt;/code&gt; &lt;code&gt;#React.js&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/FooSoft/goldsmith&quot;&gt;Goldsmith&lt;/a&gt; - Fast and simple pipeline-based static site generator, extensible via plugins. &lt;code&gt;#Go&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/sysgears/grain&quot;&gt;Grain&lt;/a&gt; - &lt;code&gt;#Groovy&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://gridsome.org&quot;&gt;Gridsome&lt;/a&gt; - Vue.js-powered, modern site generator for building the fastest possible websites for any Headless CMS, APIs or Markdown-files. - &lt;code&gt;#Vue.js&lt;/code&gt; &lt;code&gt;#JavaScript&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/jaspervdj/hakyll&quot;&gt;Hakyll&lt;/a&gt; - Hakyll is a Haskell library for generating static sites, mostly aimed at small-to-medium sites and personal blogs. It is written in a very configurable way and uses an xmonad-like DSL for configuration. - &lt;code&gt;#Haskell&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://harpjs.com/&quot;&gt;Harp&lt;/a&gt; - &lt;code&gt;#JavaScript&lt;/code&gt; &lt;code&gt;#Node.js&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://hexo.io/&quot;&gt;Hexo&lt;/a&gt; - &lt;code&gt;#JavaScript&lt;/code&gt; &lt;code&gt;#Node.js&lt;/code&gt; &lt;a href=&quot;https://github.com/hexojs/hexo&quot;&gt;Source&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/spf13/hugo&quot;&gt;Hugo&lt;/a&gt; - It is optimized for speed, easy use and configurability. - &lt;code&gt;#Go&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://iles.pages.dev&quot;&gt;îles&lt;/a&gt; - Generates static sites with islands of interactivity - &lt;code&gt;#Vue&lt;/code&gt;, &lt;code&gt;#Preact&lt;/code&gt;, &lt;code&gt;#Svelte&lt;/code&gt;, &lt;code&gt;#Solid&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/jbake-org/jbake&quot;&gt;JBake&lt;/a&gt; &lt;code&gt;#Java&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/gar1t/lambdapad&quot;&gt;LambdaPad&lt;/a&gt; - &lt;code&gt;#Erlang&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/datagrok/makebakery&quot;&gt;m4-bakery&lt;/a&gt; - &lt;code&gt;#make&lt;/code&gt; &lt;code&gt;#m4&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/segmentio/metalsmith&quot;&gt;Metalsmith&lt;/a&gt; - An extremely simple, pluggable static site generator. - &lt;code&gt;#JavaScript&lt;/code&gt; &lt;code&gt;#Node.js&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/middleman/middleman&quot;&gt;Middleman&lt;/a&gt; - Middleman is a static site generator using all the shortcuts and tools in modern web development. - &lt;code&gt;#Ruby&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/nanoc/nanoc&quot;&gt;nanoc&lt;/a&gt; - Flexible support for small personal to large corporate web sites. - &lt;code&gt;#Ruby&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://nuxtjs.org/&quot;&gt;Nuxt.js&lt;/a&gt; - Versatile vue-based framework for server-side-rendered, static and traditional single page applications.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/BennyHallett/obelisk&quot;&gt;obelisk&lt;/a&gt; - &lt;code&gt;#elixir&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://orchid.netlify.com/&quot;&gt;Orchid&lt;/a&gt; - A beautiful and truly unique documentation engine and static site generator. - &lt;code&gt;#Java&lt;/code&gt; &lt;code&gt;#Kotlin&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://pagegen.phnd.net/&quot;&gt;Pagegen&lt;/a&gt; - &lt;code&gt;#Python&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://phenomic.io/&quot;&gt;Phenomic&lt;/a&gt; - Modern static website generator based on the React and Webpack ecosystem. - &lt;code&gt;#Javascript&lt;/code&gt; &lt;code&gt;#Node.js&lt;/code&gt; &lt;code&gt;#React.js&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/JohnSundell/Publish&quot;&gt;Publish&lt;/a&gt; - enables entire websites to be built using Swift, and supports themes, plugins and tons of other powerful customization options - &lt;code&gt;#Swift&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://quarto.org/&quot;&gt;Quarto&lt;/a&gt; - An open-source scientific and technical publishing system with literate programming in multiple languages.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/nozzle/react-static&quot;&gt;React Static&lt;/a&gt; - A progressive static-site framework for React. - &lt;code&gt;#React.js&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/scullyio/scully&quot;&gt;Scully&lt;/a&gt; - The Static Site Generator for Angular apps. - &lt;code&gt;#TypeScript&lt;/code&gt; &lt;code&gt;#Angular&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://sculpin.io/&quot;&gt;Sculpin&lt;/a&gt; - &lt;code&gt;#PHP&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://gitlab.com/olfek/silssig&quot;&gt;Silssig&lt;/a&gt; - Dart powered static site generator for GitHub/GitLab pages and other similar services with support for markdown. - &lt;code&gt;#Dart&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/leafo/sitegen&quot;&gt;Sitegen&lt;/a&gt; - &lt;code&gt;#Lua&lt;/code&gt; &lt;code&gt;#MoonScript&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://designmodo.com/slides/&quot;&gt;Slides&lt;/a&gt; - &lt;code&gt;#JavaScript&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://soupault.app/&quot;&gt;Soupault&lt;/a&gt; - A static site framework and post-processor that works with HTML element trees and can automatically manipulate them. - &lt;code&gt;#Lua&lt;/code&gt; &lt;code&gt;#OCaml&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://styx-static.github.io/styx-site/&quot;&gt;Styx&lt;/a&gt; - The Purely Functional Static Site Generator. - &lt;code&gt;#Nix&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://kit.svelte.dev/&quot;&gt;SvelteKit&lt;/a&gt; - SvelteKit is a framework for building web applications of all sizes, with a beautiful development experience and flexible filesystem-based routing. - &lt;code&gt;#JavaScript&lt;/code&gt; &lt;code&gt;#TypeScript&lt;/code&gt; &lt;code&gt;#Svelte&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/braceio/tags&quot;&gt;Tags&lt;/a&gt; - &lt;code&gt;#Python&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://urubu.jandecaluwe.com/&quot;&gt;Urubu&lt;/a&gt; - &lt;code&gt;#Python&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://vuepress.vuejs.org/&quot;&gt;VuePress&lt;/a&gt; - Vue.js powered static site generator. - &lt;code&gt;#JavaScript&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://webgen.gettalong.org/&quot;&gt;webgen&lt;/a&gt; - &lt;code&gt;#Ruby&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/jnordberg/wintersmith&quot;&gt;Wintersmith&lt;/a&gt; - &lt;code&gt;#JavaScript&lt;/code&gt; &lt;code&gt;#Node.js&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/bk/wmk&quot;&gt;wmk&lt;/a&gt; - Flexible and versatile, uses Mako templates - &lt;code&gt;#Python&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/jgm/yst&quot;&gt;yst&lt;/a&gt; - Powered by YAML. - &lt;code&gt;#Haskell&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.getzola.org&quot;&gt;Zola&lt;/a&gt; - Rust powered static site generator - &lt;code&gt;#Rust&lt;/code&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Photography&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/Jack000/Expose&quot;&gt;Expose&lt;/a&gt; - For photoessays. - &lt;code&gt;#Bash&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/waynezhang/foto&quot;&gt;foto&lt;/a&gt; - Yet another another publishing tool for minimalist photographers. - &lt;code&gt;#Go&lt;/code&gt; &lt;code&gt;#Golang&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/Psycojoker/prosopopee/&quot;&gt;Prosopopee&lt;/a&gt; A static website generator to make beautiful customizable pictures galleries that tell a story - &lt;code&gt;#Python&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://sigal.readthedocs.org/en/latest/&quot;&gt;Sigal&lt;/a&gt; - &lt;code&gt;#Python&lt;/code&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Single Page&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/chrisdiana/cms.js&quot;&gt;CMS.js&lt;/a&gt; - A fully client-side, JavaScript Markdown site generator. - &lt;code&gt;#JavaScript&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://ricostacruz.com/flatdoc/&quot;&gt;Flatdoc&lt;/a&gt; - A small JavaScript file that fetches Markdown files and renders them as full pages. - &lt;code&gt;#JavaScript&lt;/code&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Tools&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://git.mills.io/prologic/zs&quot;&gt;zs&lt;/a&gt; - an extremely minimal static site generator. - &lt;code&gt;#Go&lt;/code&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Wikis&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/GitbookIO/gitbook&quot;&gt;GitBook&lt;/a&gt; - Modern documentation format and toolchain using Git and Markdown. - &lt;code&gt;#GitBook&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/gollum/gollum&quot;&gt;Gollum&lt;/a&gt; - Gollum is a simple wiki system built on top of Git. - &lt;code&gt;#Ruby&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://ikiwiki.info/&quot;&gt;ikiwiki&lt;/a&gt; - &lt;code&gt;#Perl&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/rust-lang/mdBook&quot;&gt;mdBook&lt;/a&gt; - Create book from markdown files. Like Gitbook but implemented in Rust. - &lt;code&gt;#Rust&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://orchid.run/wiki/learn/tutorials/how-to-document-kotlin#wiki&quot;&gt;Orchid Wiki&lt;/a&gt; - A Gitbook-like wiki for your Orchid site. - &lt;code&gt;#Orchid&lt;/code&gt; &lt;code&gt;#Java&lt;/code&gt; &lt;code&gt;#Kotlin&lt;/code&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Helpful Tools and Services&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.cloud66.com/&quot;&gt;Cloud 66&lt;/a&gt; - Builds and deploys static websites to your own cloud account.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.formspree.io/&quot;&gt;Formspree&lt;/a&gt; - Adds functional forms to your static web sites.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://git-annex.branchable.com/tips/setup_a_public_repository_on_a_web_site/&quot;&gt;git-annex&lt;/a&gt; - Configure git-annex for a public repository for a static web site.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://jamstackthemes.dev/&quot;&gt;JAMStack Themes&lt;/a&gt; - A collection of themes filterable by static site generator and CMS support.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://statichunt.com/&quot;&gt;Statichunt&lt;/a&gt; - An open sources directory of 700+ free themes and resources for static site generators submitted by the community.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Web Hosts&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;http://aws.amazon.com/s3/&quot;&gt;AWS S3&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://docs.microsoft.com/en-us/azure/static-web-apps/&quot;&gt;Azure Static Web Apps&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://about.gitlab.com/product/pages/&quot;&gt;GitLab Pages&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://kinsta.com/static-site-hosting/&quot;&gt;Kinsta Static Site Hosting&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.netlify.com/&quot;&gt;Netlify&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://surge.sh/&quot;&gt;Surge&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://vercel.com&quot;&gt;Vercel&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Other Lists of Static Web Site Generators&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://bejamas.io/blog/static-site-generators/&quot;&gt;Beginner’s Guide to Static Site Generators&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://snipcart.com/blog/choose-best-static-site-generator&quot;&gt;Best Static Site Generators in 2019&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://headlesscms.org/&quot;&gt;HeadlessCMS&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://staticsitegenerators.net/&quot;&gt;Static Site Generators&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.staticgen.com/&quot;&gt;StaticGen&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Related Awesome&lt;/h2&gt; 
&lt;p&gt;Awesome lists that help you with your new static web site.&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/therebelrobot/awesome-bootstrap&quot;&gt;Awesome Bootstrap&lt;/a&gt; - A curated list of free Bootstrap themes.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/diegocard/awesome-html5&quot;&gt;Awesome HTML5&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/heyalexej/awesome-images&quot;&gt;Awesome Images&lt;/a&gt; - A curated list of amazingly awesome free (stock) photo resources.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/b-long/awesome-static-hosting&quot;&gt;Awesome Static Hosting Providers&lt;/a&gt; - A collection of awesome static hosting providers and related resources.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/aharris88/awesome-static-website-services&quot;&gt;Awesome Static Website Services&lt;/a&gt; - A curated list of awesome static websites services&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/shime/creative-commons-media&quot;&gt;Creative Commons Media&lt;/a&gt; - A curated list of resources that provide media licensed under Creative Commons licenses.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/dypsilon/frontend-dev-bookmarks&quot;&gt;Frontend Development&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Static Web Site Generators in Other Awesome Lists&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/forhappy/awesome-lua#static-site-generator&quot;&gt;forhappy/awesome-lua - Static Site Generator&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/h4cc/awesome-elixir#static-page-generation&quot;&gt;h4cc/awesome-elixir - Static Page Generation&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/kdabir/awesome-groovy#static-web&quot;&gt;kdabir/awesome-groovy - Static Web&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/markets/awesome-ruby#static-site-generation&quot;&gt;markets/awesome-ruby - Static Site Generators&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/Sdogruyol/awesome-ruby#static-page-generation&quot;&gt;Sdogruyol/awesome-ruby - Static Page Generation&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/sindresorhus/awesome-nodejs#static-site-generators&quot;&gt;sindresorhus/awesome-nodejs - Static Site Generators&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/vinta/awesome-python#static-site-generator&quot;&gt;vinta/awesome-python - Static Site Generators&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/ziadoz/awesome-php#static-site-generators&quot;&gt;ziadoz/awesome-php - Static Site Generators&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>TabrisJS</title>
      <link>https://tedneward.github.io/Research/presentation/tabrisjs/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/tabrisjs/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://tabris.com/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/eclipsesource/tabris-js/&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Cross-platform, true native. Tabris.js does not use WebViews for rendering the UI. Instead, it creates native widgets on the mobile platform via a JavaScript to native bridge. ... use existing JavaScript libraries, node modules, and Cordova plugins to build your apps. Tabris.js implements many APIs core to web applications, e.g. XMLHttpRequest or the 2D canvas. Create gorgeous graphs with chart.js, easily integrate underscore.js or access device features with Cordova device.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Three.js</title>
      <link>https://tedneward.github.io/Research/presentation/threejs/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/threejs/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://threejs.org/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/mrdoob/three.js/&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Titanium Mobile</title>
      <link>https://tedneward.github.io/Research/presentation/titanium/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/titanium/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://titaniumsdk.com/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/tidev/titanium_mobile&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;&quot;All private source code of the Titanium SDK will be made public in the open source Titanium SDK github repository by March 1, 2022&quot;&lt;/p&gt; 
&lt;/blockquote&gt; 
&lt;p&gt;Uses extensions for VSCode or Atom as its IDE. There is also a CLI (&lt;code&gt;npm install titanium -g&lt;/code&gt;) available.&lt;/p&gt; 
&lt;p&gt;The Titanium SDK supports two project types: Alloy and Classic. Alloy is an MVC framework that lets you develop applications in less time and with less code than is possible in a Classic project. In general, it&apos;s recommended you use Alloy for your projects.&lt;/p&gt; 
&lt;p&gt;Example code from &lt;a href=&quot;https://titaniumsdk.com/guide/Titanium_SDK/Titanium_SDK_Getting_Started/Hello_Titanium_App_Tutorial.html&quot;&gt;tutorial&lt;/a&gt;:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-xml&quot;&gt;&amp;lt;Alloy&amp;gt;
    &amp;lt;Window class=&quot;container&quot;&amp;gt;
        &amp;lt;Label id=&quot;label&quot; onClick=&quot;doClick&quot;&amp;gt;Hello, Titanium&amp;lt;/Label&amp;gt;
    &amp;lt;/Window&amp;gt;
&amp;lt;/Alloy&amp;gt;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Uses XML as its visual layout (replacement for HTML, similar in spirit to XAML, sort of), and Javascript as its event-handling/programmatic support language, and &quot;TSS&quot; (a variant of CSS) for styling and visual organization. Renders on both iOS and Android, so it&apos;s a single-source/multi-deliverable tool.&lt;/p&gt; 
&lt;p&gt;Also does game development?&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>uhtml</title>
      <link>https://tedneward.github.io/Research/presentation/uhtml/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/uhtml/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.npmjs.com/package/uhtml&quot;&gt;NPM&lt;/a&gt; | &lt;a href=&quot;https://github.com/WebReflection/uhtml&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Valdi</title>
      <link>https://tedneward.github.io/Research/presentation/valdi/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/valdi/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/Snapchat/Valdi&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Vivaldi</title>
      <link>https://tedneward.github.io/Research/presentation/vivaldi/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/vivaldi/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://vivaldi.com/&quot;&gt;Website&lt;/a&gt; | Source unavailable, free download&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>OpenVidu</title>
      <link>https://tedneward.github.io/Research/presentation/openvidu/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/openvidu/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://openvidu.io/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/OpenVidu/openvidu&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>P5</title>
      <link>https://tedneward.github.io/Research/presentation/p5/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/p5/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://p5js.org/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/processing/p5.js/&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Part of the Processing project.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Photino</title>
      <link>https://tedneward.github.io/Research/presentation/photino/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/photino/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.tryphotino.io/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/tryphotino&quot;&gt;GitHub&lt;/a&gt; | &lt;a href=&quot;https://docs.tryphotino.io/&quot;&gt;Docs&lt;/a&gt;&lt;/p&gt; 
&lt;h2&gt;Getting started&lt;/h2&gt; 
&lt;pre&gt;&lt;code&gt;dotnet new -i TryPhotino.VSCode.Project.Templates\
&amp;amp;&amp;amp; dotnet new photinoapp -o MyPhotinoApp\
&amp;amp;&amp;amp; cd MyPhotinoApp\
&amp;amp;&amp;amp; dotnet run
&lt;/code&gt;&lt;/pre&gt;
	</description>
    </item>
    <item>
      <title>Pretext</title>
      <link>https://tedneward.github.io/Research/presentation/pretext/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/pretext/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://chenglou.me/pretext/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/chenglou/pretext&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;h2&gt;Reading&lt;/h2&gt; 
&lt;h3&gt;Articles/Blogs/Essays&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://venturebeat.com/technology/midjourney-engineer-debuts-new-vibe-coded-open-source-standard-pretext-to&quot;&gt;Midjourney engineer debuts new vibe coded, open source standard Pretext to revolutionize web design&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Progressive Web applications (PWAs)</title>
      <link>https://tedneward.github.io/Research/presentation/pwa/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/pwa/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://web.dev/learn/pwa/?utm_source=tldrnewsletter&quot;&gt;Learn PWA&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Oqtane</title>
      <link>https://tedneward.github.io/Research/presentation/oqtane/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/oqtane/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.oqtane.org/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/oqtane/framework&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&quot;Oqtane was inspired by DotNetNuke, the pionering open source .NET CMS. Specifically it supports multi-tenancy, a fully dynamic page compositing model, designer friendly skins, extensibility via third party modules, and a familiar data model.&quot;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Panel</title>
      <link>https://tedneward.github.io/Research/presentation/panel/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/panel/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://panel.holoviz.org/index.html&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/holoviz/panel&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;h2&gt;&lt;a href=&quot;https://panel.holoviz.org/how_to/wasm/standalone.html&quot;&gt;Using Pyodide and Panel&lt;/a&gt;&lt;/h2&gt; 
&lt;p&gt;Create a file called script.html with the following content:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html&amp;gt;
  &amp;lt;head&amp;gt;
    &amp;lt;meta charset=&quot;UTF-8&quot;&amp;gt;
    &amp;lt;meta name=&quot;viewport&quot; content=&quot;width=device-width,initial-scale=1.0&quot;&amp;gt;
    &amp;lt;script type=&quot;text/javascript&quot; src=&quot;https://cdn.jsdelivr.net/pyodide/v0.28.2/full/pyodide.js&quot;&amp;gt;&amp;lt;/script&amp;gt;
    &amp;lt;script type=&quot;text/javascript&quot; src=&quot;https://cdn.bokeh.org/bokeh/release/bokeh-3.8.1.js&quot;&amp;gt;&amp;lt;/script&amp;gt;
    &amp;lt;script type=&quot;text/javascript&quot; src=&quot;https://cdn.bokeh.org/bokeh/release/bokeh-widgets-3.8.1.min.js&quot;&amp;gt;&amp;lt;/script&amp;gt;
    &amp;lt;script type=&quot;text/javascript&quot; src=&quot;https://cdn.bokeh.org/bokeh/release/bokeh-tables-3.8.1.min.js&quot;&amp;gt;&amp;lt;/script&amp;gt;
    &amp;lt;script type=&quot;text/javascript&quot; src=&quot;https://cdn.jsdelivr.net/npm/@holoviz/panel@1.8.4/dist/panel.min.js&quot;&amp;gt;&amp;lt;/script&amp;gt;
  &amp;lt;/head&amp;gt;
  &amp;lt;body&amp;gt;
    &amp;lt;div id=&quot;simple_app&quot;&amp;gt;&amp;lt;/div&amp;gt;
    &amp;lt;script type=&quot;text/javascript&quot;&amp;gt;
      async function main() {
        let pyodide = await loadPyodide();
        await pyodide.loadPackage(&quot;micropip&quot;);
        const micropip = pyodide.pyimport(&quot;micropip&quot;);
        await micropip.install([
          &quot;https://cdn.holoviz.org/panel/1.8.4/dist/wheels/bokeh-3.8.1-py3-none-any.whl&quot;,
          &quot;https://cdn.holoviz.org/panel/1.8.4/dist/wheels/panel-1.8.4-py3-none-any.whl&quot;
        ]);
        pyodide.runPython(`
          import panel as pn
          pn.extension(sizing_mode=&quot;stretch_width&quot;)
          slider = pn.widgets.FloatSlider(start=0, end=10, name=&apos;Amplitude&apos;)
          def callback(new):
              return f&apos;Amplitude is: {new}&apos;

          pn.Row(slider, pn.bind(callback, slider)).servable(target=&apos;simple_app&apos;);
      `);
      }
      main();
    &amp;lt;/script&amp;gt;
  &amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Serve the app with: &lt;code&gt;python -m http.server&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;Open the app in your browser at &lt;a href=&quot;http://localhost:8000/script.html&quot;&gt;http://localhost:8000/script.html&lt;/a&gt;.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>PixiJS</title>
      <link>https://tedneward.github.io/Research/presentation/pixijs/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/pixijs/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;http://www.pixijs.com/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://pixijs.download/release/docs/index.html&quot;&gt;Docs&lt;/a&gt; | &lt;a href=&quot;https://pixijs.io/examples/#/demos-basic/container.js&quot;&gt;Examples&lt;/a&gt; | &lt;a href=&quot;https://github.com/pixijs/pixijs&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://github.com/kittykatattack/learningPixi&quot;&gt;Tutorial&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Features&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;WebGL renderer (with automatic smart batching allowing for REALLY fast performance)&lt;/li&gt; 
 &lt;li&gt;Canvas renderer (Fastest in town!)&lt;/li&gt; 
 &lt;li&gt;Full scene graph&lt;/li&gt; 
 &lt;li&gt;Super easy to use API (similar to the flash display list API)&lt;/li&gt; 
 &lt;li&gt;Support for texture atlases&lt;/li&gt; 
 &lt;li&gt;Asset loader / sprite sheet loader&lt;/li&gt; 
 &lt;li&gt;Auto-detect which renderer should be used&lt;/li&gt; 
 &lt;li&gt;Full Mouse and Multi-touch Interaction&lt;/li&gt; 
 &lt;li&gt;Text&lt;/li&gt; 
 &lt;li&gt;BitmapFont text&lt;/li&gt; 
 &lt;li&gt;Multiline Text&lt;/li&gt; 
 &lt;li&gt;Render Texture&lt;/li&gt; 
 &lt;li&gt;Primitive Drawing&lt;/li&gt; 
 &lt;li&gt;Masking&lt;/li&gt; 
 &lt;li&gt;Filters&lt;/li&gt; 
 &lt;li&gt;User Plugins&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Basic Usage Example&lt;/h3&gt; 
&lt;pre&gt;&lt;code class=&quot;language-js&quot;&gt;import * as PIXI from &apos;pixi.js&apos;;

// The application will create a renderer using WebGL, if possible,
// with a fallback to a canvas render. It will also setup the ticker
// and the root stage PIXI.Container
const app = new PIXI.Application();

// The application will create a canvas element for you that you
// can then insert into the DOM
document.body.appendChild(app.view);

// load the texture we need
app.loader.add(&apos;bunny&apos;, &apos;bunny.png&apos;).load((loader, resources) =&amp;gt; {
    // This creates a texture from a &apos;bunny.png&apos; image
    const bunny = new PIXI.Sprite(resources.bunny.texture);

    // Setup the position of the bunny
    bunny.x = app.renderer.width / 2;
    bunny.y = app.renderer.height / 2;

    // Rotate around the center
    bunny.anchor.x = 0.5;
    bunny.anchor.y = 0.5;

    // Add the bunny to the scene we are building
    app.stage.addChild(bunny);

    // Listen for frame updates
    app.ticker.add(() =&amp;gt; {
         // each frame we spin the bunny around a bit
        bunny.rotation += 0.01;
    });
});
&lt;/code&gt;&lt;/pre&gt;
	</description>
    </item>
    <item>
      <title>Processing</title>
      <link>https://tedneward.github.io/Research/presentation/processing/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/processing/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://processing.org/&quot;&gt;Processing Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/processing&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://android.processing.org/&quot;&gt;Processing for Android Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/processing/processing-android&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://p5js.org/&quot;&gt;p5js Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/processing/p5.js&quot;&gt;p5js Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://py.processing.org/&quot;&gt;Processing.py&lt;/a&gt; | &lt;a href=&quot;https://github.com/jdf/processing.py&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Flet</title>
      <link>https://tedneward.github.io/Research/presentation/python/flet/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/python/flet/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://flet.dev/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/flet-dev/flet&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;h3&gt;What is Flet?&lt;/h3&gt; 
&lt;p&gt;Flet is a framework that allows building web, desktop and mobile applications in Python without prior experience in frontend development.&lt;/p&gt; 
&lt;p&gt;You can build a UI for your program with Flet &lt;a href=&quot;https://flet.dev/docs/controls&quot;&gt;controls&lt;/a&gt; which are based on &lt;a href=&quot;https://flutter.dev/&quot;&gt;Flutter&lt;/a&gt; by Google. Flet goes beyond merely wrapping Flutter widgets. It adds its own touch by combining smaller widgets, simplifying complexities, implementing UI best practices, and applying sensible defaults. This ensures that your applications look stylish and polished without requiring additional design efforts on your part.&lt;/p&gt; 
&lt;h3&gt;Flet app example&lt;/h3&gt; 
&lt;p&gt;Create a sample &quot;Counter&quot; app:&lt;/p&gt; 
&lt;p&gt;counter.py&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;import flet as ft

def main(page: ft.Page):
    page.title = &quot;Flet counter example&quot;
    page.vertical_alignment = ft.MainAxisAlignment.CENTER

    txt_number = ft.TextField(value=&quot;0&quot;, text_align=ft.TextAlign.RIGHT, width=100)

    def minus_click(e):
        txt_number.value = str(int(txt_number.value) - 1)
        page.update()

    def plus_click(e):
        txt_number.value = str(int(txt_number.value) + 1)
        page.update()

    page.add(
        ft.Row(
            [
                ft.IconButton(ft.Icons.REMOVE, on_click=minus_click),
                txt_number,
                ft.IconButton(ft.Icons.ADD, on_click=plus_click),
            ],
            alignment=ft.MainAxisAlignment.CENTER,
        )
    )

ft.app(main)
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;To run the app install &lt;code&gt;flet&lt;/code&gt; module (&lt;a href=&quot;https://flet.dev/docs/getting-started&quot;&gt;create a new Flet environment&lt;/a&gt;):&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;pip install flet
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;and &lt;a href=&quot;https://flet.dev/docs/getting-started/running-app&quot;&gt;run the program&lt;/a&gt;:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;flet run counter.py
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;The app will be started in a native OS window - what a nice alternative to Electron!&lt;/p&gt; 
&lt;h3&gt;macOS&lt;/h3&gt; 
&lt;p&gt;&lt;img src=&quot;https://flet.dev/img/docs/getting-started/flet-counter-macos.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt; 
&lt;h3&gt;Windows&lt;/h3&gt; 
&lt;p&gt;&lt;img src=&quot;https://flet.dev/img/docs/getting-started/flet-counter-windows.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt; 
&lt;p&gt;Now, run your app as a web app:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;flet run --web counter.py
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;A new browser window or tab will be opened:&lt;/p&gt; 
&lt;p&gt;&lt;img src=&quot;https://flet.dev/img/docs/getting-started/flet-counter-safari.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Orbitiny</title>
      <link>https://tedneward.github.io/Research/presentation/orbitiny/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/orbitiny/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://gitea.com/sasko.usinov/orbitiny-desktop&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;h2&gt;Reading&lt;/h2&gt; 
&lt;h3&gt;Articles, Blogs, Essays&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.zdnet.com/article/orbitiny-portable-modular-unique-linux-desktop/&quot;&gt;This new Linux desktop runs like an app on your existing desktop&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Paper websites</title>
      <link>https://tedneward.github.io/Research/presentation/paper-websites/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/paper-websites/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://daily.tinyprojects.dev/paper_website&quot;&gt;Blog post&lt;/a&gt; | &lt;a href=&quot;https://paperwebsite.com/&quot;&gt;Website&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Polymer</title>
      <link>https://tedneward.github.io/Research/presentation/polymer/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/polymer/index.html</guid>
      	<description>
	&lt;p&gt;The Polymer library is in maintenance mode. For new development, we recommend &lt;a href=&quot;./lit&quot;&gt;Lit&lt;/a&gt;.&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://polymer-library.polymer-project.org/&quot;&gt;Website&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>ProseMirror</title>
      <link>https://tedneward.github.io/Research/presentation/prosemirror/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/prosemirror/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://prosemirror.net&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/ProseMirror/prosemirror&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>OOUI</title>
      <link>https://tedneward.github.io/Research/presentation/ooui/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/ooui/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/praeclarum/Ooui&quot;&gt;Source&lt;/a&gt; | &lt;a href=&quot;http://ooui.mecha.parts/&quot;&gt;Interactive examples&lt;/a&gt; and &lt;a href=&quot;https://github.com/praeclarum/Ooui/tree/master/Samples&quot;&gt;source&lt;/a&gt;&lt;/p&gt; 
&lt;h3&gt;Example App&lt;/h3&gt; 
&lt;pre&gt;&lt;code&gt;using System;
using Ooui;

class Program
{
    static void Main(string[] args)
    {
        // Create the UI
        var button = new Button(&quot;Click me!&quot;);

        // Add some logic to it
        var count = 0;
        button.Click += (s, e) =&amp;gt; {
            count++;
            button.Text = $&quot;Clicked {count} times&quot;;
        };

        // Publishing makes an object available at a given URL
        // The user should be directed to http://localhost:8080/shared-button
        UI.Publish (&quot;/shared-button&quot;, button);

        // Don&apos;t exit the app until someone hits return
        Console.ReadLine ();
    }
}
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Make sure to add a reference to Ooui before you start running!&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-shell&quot;&gt;dotnet add package Ooui
dotnet run
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;&lt;a href=&quot;&quot;&gt;Button-XAML Example&lt;/a&gt;&lt;/h3&gt; 
&lt;p&gt;An example of doing an interactive Xamarin Forms app.&lt;/p&gt; 
&lt;p&gt;XAML:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot; ?&amp;gt;
&amp;lt;ContentPage xmlns=&quot;http://xamarin.com/schemas/2014/forms&quot;
             xmlns:x=&quot;http://schemas.microsoft.com/winfx/2009/xaml&quot;
             x:Class=&quot;ButtonXaml.ButtonXamlPage&quot;&amp;gt;

    &amp;lt;StackLayout Padding=&quot;20&quot;&amp;gt;
        &amp;lt;Label Text=&quot;Welcome to Xamarin.Forms!&quot; FontSize=&quot;32&quot; FontAttributes=&quot;Bold&quot; /&amp;gt;
        &amp;lt;Entry x:Name=&quot;LabelCount&quot; Text=&quot;Click Count: 0&quot;/&amp;gt;
        &amp;lt;Button Text=&quot;Tap for click count!&quot;
                Clicked=&quot;OnButtonClicked&quot; /&amp;gt;
    &amp;lt;/StackLayout&amp;gt;
&amp;lt;/ContentPage&amp;gt;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;XAML.CS:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;using System;
using Xamarin.Forms;

namespace ButtonXaml
{
    public partial class ButtonXamlPage
    {
        int count = 0;

        public ButtonXamlPage()
        {
            InitializeComponent();
        }

        public void OnButtonClicked(object sender, EventArgs args)
        {
            count++;
            LabelCount.Text = $&quot;Click Count: {count}&quot;;
           
        }
    }
}
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;C#:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;using Ooui;
using Xamarin.Forms;

namespace Samples
{
    public class ButtonXamlSample : ISample
    {
        public string Title =&amp;gt; &quot;Xamarin.Forms Button XAML&quot;;
        public string Path =&amp;gt; &quot;buttons&quot;;

        public Ooui.Element CreateElement ()
        {
            var page = new ButtonXaml.ButtonXamlPage ();
            return page.GetOouiElement ();
        }

        public void Publish()
        {
            UI.Publish(Path, CreateElement);
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
	</description>
    </item>
    <item>
      <title>Otterwiki</title>
      <link>https://tedneward.github.io/Research/presentation/otterwiki/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/otterwiki/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://otterwiki.com/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/redimp/otterwiki&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>UI patterns</title>
      <link>https://tedneward.github.io/Research/presentation/patterns/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/patterns/index.html</guid>
      	<description>
	&lt;h2&gt;Articles&lt;/h2&gt; 
&lt;p&gt;&lt;a href=&quot;https://www.smashingmagazine.com/taking-pattern-libraries-next-level/&quot;&gt;Taking Pattern Libraries to the Next Level&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://www.smashingmagazine.com/2009/06/10-ui-design-patterns-you-should-be-paying-attention-to/&quot;&gt;10 UI Design Patterns You Should Be Paying Attention To&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://www.smashingmagazine.com/2010/02/designing-user-interfaces-for-business-web-applications/&quot;&gt;Designing UI for Business Web Apps&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;7 Rules for Creating Gorgeous UI: &lt;a href=&quot;https://www.learnui.design/blog/7-rules-for-creating-gorgeous-ui-part-1.html&quot;&gt;Part 1&lt;/a&gt; &lt;a href=&quot;https://www.learnui.design/blog/7-rules-for-creating-gorgeous-ui-part-2.html&quot;&gt;Part 2&lt;/a&gt;:&lt;/p&gt; 
&lt;ol&gt; 
 &lt;li&gt;Light comes from the sky 
  &lt;ol&gt; 
   &lt;li&gt;Black and white first&lt;/li&gt; 
   &lt;li&gt;Double your whitespace&lt;/li&gt; 
   &lt;li&gt;Learn the methods of overlaying text on images&lt;/li&gt; 
   &lt;li&gt;Make text pop — and un-pop&lt;/li&gt; 
   &lt;li&gt;Use only good fonts&lt;/li&gt; 
   &lt;li&gt;Steal like an artist&lt;/li&gt; 
  &lt;/ol&gt; &lt;/li&gt; 
&lt;/ol&gt; 
&lt;h2&gt;Websites&lt;/h2&gt; 
&lt;p&gt;&lt;a href=&quot;http://designingwebinterfaces.com/&quot;&gt;Designing Web Interfaces&lt;/a&gt;: Supporting website for the book of the same name. &lt;em&gt;(Posts until 2012)&lt;/em&gt;&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;http://designingwebinterfaces.com/designing-web-interfaces-12-screen-patterns&quot;&gt;Standard Screen Patterns&lt;/a&gt; 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;http://designingwebinterfaces.com/essential_controls&quot;&gt;Essential Controls&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;http://designingwebinterfaces.com/15-common-components&quot;&gt;Components for Commonly Requested Features&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;&lt;a href=&quot;https://centercentre.com/&quot;&gt;https://centercentre.com/&lt;/a&gt; - For UX leaders.&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://ui-patterns.com/&quot;&gt;https://ui-patterns.com/&lt;/a&gt; - a large collection of design patterns for UI designers to gain inspiration from. The site allows users to keep sets of their own (publicly accessible to site visitors) so that you can see other UI design pattern collections.&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://uipatternfactory.com/&quot;&gt;https://uipatternfactory.com/&lt;/a&gt; - The UI Pattern Factory is a UI design library and gallery. What’s great at UIPF is that they sometimes share videos in each entry to improve the description of design problems and solutions. Entries are further enhanced by user-submitted examples of the pattern, which they archive in their Flickr group: UIPatternFactory.com.&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://www.lukew.com/ff/&quot;&gt;https://www.lukew.com/ff/&lt;/a&gt; - the weblog of UI designer and author Luke Wroblewski. You can learn about designing for humans by reading through his insightful articles on the site and find useful lists such as a collection of resources on website buttons.&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://www.hcipatterns.org/&quot;&gt;https://www.hcipatterns.org/&lt;/a&gt; - This is the homepage of people interested in pattern languages in human-computer interaction (HCI) and user interface design and the IFIP TC13 HCI Patterns Task Group.&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://speckyboy.com/topic/web-design-inspiration/&quot;&gt;https://speckyboy.com/topic/web-design-inspiration/&lt;/a&gt; - Web design inspiration, a collection of ideas&lt;/p&gt; 
&lt;h3&gt;Flickr Groups:&lt;/h3&gt; 
&lt;p&gt;&lt;a href=&quot;https://www.flickr.com/groups/namics_uipatterns/&quot;&gt;https://www.flickr.com/groups/namics_uipatterns/&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://www.flickr.com/groups/designpatterns/&quot;&gt;https://www.flickr.com/groups/designpatterns/&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Preact</title>
      <link>https://tedneward.github.io/Research/presentation/preact/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/preact/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://preactjs.com/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/preactjs/preact&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Pug</title>
      <link>https://tedneward.github.io/Research/presentation/pug/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/pug/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://pugjs.org/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://pugjs.org/api/getting-started.html&quot;&gt;Docs&lt;/a&gt; | &lt;a href=&quot;https://github.com/pugjs/pug&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;h3&gt;&lt;a href=&quot;https://learnxinyminutes.com/docs/pug/&quot;&gt;Learn X in Y Minutes Quick Intro&lt;/a&gt;&lt;/h3&gt; 
&lt;pre&gt;&lt;code class=&quot;language-pug&quot;&gt;
//- Single Line Comment

//- Multi Line
    Comment

//- ---TAGS---
//- Basic
div
//- &amp;lt;div&amp;gt;&amp;lt;/div&amp;gt;
h1
//- &amp;lt;h1&amp;gt;&amp;lt;/h1&amp;gt;
my-customTag
//- &amp;lt;my-customTag&amp;gt;&amp;lt;/my-customTag&amp;gt;

//- Sibling
div
div
//- &amp;lt;div&amp;gt;&amp;lt;/div&amp;gt;
    &amp;lt;div&amp;gt;&amp;lt;/div&amp;gt;

//- Child
div
  div
//- &amp;lt;div&amp;gt;
      &amp;lt;div&amp;gt;&amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;

//- Text
h1 Hello there
//- &amp;lt;h1&amp;gt;Hello there&amp;lt;/h1&amp;gt;

//- Multi Line Text
div.
  Hello
  There
//- &amp;lt;div&amp;gt;
      Hello
      There
    &amp;lt;/div&amp;gt;

//- ---ATTRIBUTES---
div(class=&quot;my-class&quot; id=&quot;my-id&quot; my-custom-attrs=&quot;data&quot; enabled)
//- &amp;lt;div class=&quot;my-class&quot; id=&quot;my-id&quot; my-custom-attrs=&quot;data&quot; enabled&amp;gt;&amp;lt;/div&amp;gt;

//- Short Hand
span.my-class
//- &amp;lt;span class=&quot;my-class&quot;&amp;gt;&amp;lt;/span&amp;gt;
.my-class
//- &amp;lt;div class=&quot;my-class&quot;&amp;gt;&amp;lt;/div&amp;gt;
div#my-id
//- &amp;lt;div id=&quot;my-id&quot;&amp;gt;&amp;lt;/div&amp;gt;
div#my-id.my-class
//- &amp;lt;div class=&quot;my-class&quot; id=&quot;my-id&quot;&amp;gt;&amp;lt;/div&amp;gt;


//- ---JS---
- const lang = &quot;pug&quot;;

//- Multi Line JS
-
  const lang = &quot;pug&quot;;
  const awesome = true;

//- JS Classes
- const myClass = [&apos;class1&apos;, &apos;class2&apos;, &apos;class3&apos;]
div(class=myClass)
//- &amp;lt;div class=&quot;class1 class2 class3&quot;&amp;gt;&amp;lt;/div&amp;gt;

//- JS Styles
- const myStyles = {&apos;color&apos;:&apos;white&apos;, &apos;background-color&apos;:&apos;blue&apos;}
div(styles=myStyles)
//- &amp;lt;div styles=&quot;{&amp;amp;quot;color&amp;amp;quot;:&amp;amp;quot;white&amp;amp;quot;,&amp;amp;quot;background-color&amp;amp;quot;:&amp;amp;quot;blue&amp;amp;quot;}&quot;&amp;gt;&amp;lt;/div&amp;gt;

//- JS Attributes
- const myAttributes = {&quot;src&quot;: &quot;photo.png&quot;, &quot;alt&quot;: &quot;My Photo&quot;}
img&amp;amp;attributes(myAttributes)
//- &amp;lt;img src=&quot;photo.png&quot; alt=&quot;My Photo&quot;&amp;gt;
- let disabled = false
input(type=&quot;text&quot; disabled=disabled)
//- &amp;lt;input type=&quot;text&quot;&amp;gt;
- disabled = true
input(type=&quot;text&quot; disabled=disabled)
//- &amp;lt;input type=&quot;text&quot; disabled&amp;gt;

//- JS Templating
- const name = &quot;Bob&quot;;
h1 Hi #{name}
h1= name
//- &amp;lt;h1&amp;gt;Hi Bob&amp;lt;/h1&amp;gt;
//- &amp;lt;h1&amp;gt;Bob&amp;lt;/h1&amp;gt;

//- ---LOOPS---

//- &apos;each&apos; and &apos;for&apos; do the same thing we will use &apos;each&apos; only.

each value, i in [1,2,3]
  p=value
//-
  &amp;lt;p&amp;gt;1&amp;lt;/p&amp;gt;
  &amp;lt;p&amp;gt;2&amp;lt;/p&amp;gt;
  &amp;lt;p&amp;gt;3&amp;lt;/p&amp;gt;

each value, index in [1,2,3]
  p=value + &apos;-&apos; + index
//-
  &amp;lt;p&amp;gt;1-0&amp;lt;/p&amp;gt;
  &amp;lt;p&amp;gt;2-1&amp;lt;/p&amp;gt;
  &amp;lt;p&amp;gt;3-2&amp;lt;/p&amp;gt;

each value in []
  p=value
//- 

each value in []
  p=value
else
  p No Values are here

//- &amp;lt;p&amp;gt;No Values are here&amp;lt;/p&amp;gt;

//- ---CONDITIONALS---

- const number = 5
if number &amp;lt; 5
  p number is less then 5
else if number &amp;gt; 5
  p number is greater then 5
else
  p number is 5
//- &amp;lt;p&amp;gt;number is 5&amp;lt;/p&amp;gt;

- const orderStatus = &quot;Pending&quot;;
case orderStatus
  when &quot;Pending&quot;
    p.warn Your order is pending
  when &quot;Completed&quot;
    p.success Order is Completed.
  when -1
    p.error Error Occurred
  default
    p No Order Record Found
//- &amp;lt;p class=&quot;warn&quot;&amp;gt;Your order is pending&amp;lt;/p&amp;gt;

//- --INCLUDE--
//- File path -&amp;gt; &quot;includes/nav.png&quot;
h1 Company Name
nav
  a(href=&quot;index.html&quot;) Home
  a(href=&quot;about.html&quot;) About Us

//- File path -&amp;gt; &quot;index.png&quot;
html
  body
    include includes/nav.pug
//-
  &amp;lt;html&amp;gt;
    &amp;lt;body&amp;gt;
      &amp;lt;h1&amp;gt;Company Name&amp;lt;/h1&amp;gt;
      &amp;lt;nav&amp;gt;&amp;lt;a href=&quot;index.html&quot;&amp;gt;Home&amp;lt;/a&amp;gt;&amp;lt;a href=&quot;about.html&quot;&amp;gt;About Us&amp;lt;/a&amp;gt;&amp;lt;/nav&amp;gt;
    &amp;lt;/body&amp;gt;
  &amp;lt;/html&amp;gt;

//- Importing JS and CSS
script
  include scripts/index.js
style
  include styles/theme.css

//- ---MIXIN---
mixin basic()
  div Hello
+basic(&quot;Bob&quot;)
//- &amp;lt;div&amp;gt;Hello&amp;lt;/div&amp;gt;

mixin comment(name, comment)
  div
    span.comment-name= name
    div.comment-text= comment
+comment(&quot;Bob&quot;, &quot;This is Awesome&quot;)
//- &amp;lt;div&amp;gt;Hello&amp;lt;/div&amp;gt;

&lt;/code&gt;&lt;/pre&gt;
	</description>
    </item>
    <item>
      <title>Kraken (OpenKraken)</title>
      <link>https://tedneward.github.io/Research/presentation/kraken/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/kraken/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://openkraken.com/en-US&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/openkraken/kraken&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&quot;Kraken is a high-performance rendering engine based on W3C standards. Kraken&apos;s bottom layer is rendered based on Flutter, and its self-drawn rendering feature ensures multi-end consistency. The upper layer is implemented based on W3C standards and has a very large front -end developer ecosystem.&quot;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>libui</title>
      <link>https://tedneward.github.io/Research/presentation/libui/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/libui/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/andlabs/libui&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Litho</title>
      <link>https://tedneward.github.io/Research/presentation/litho/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/litho/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://fblitho.com/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/facebook/litho&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Declarative: Litho uses a declarative API to define UI components. You simply describe the layout for your UI based on a set of immutable inputs and the framework takes care of the rest.&lt;/li&gt; 
 &lt;li&gt;Asynchronous layout: Litho can measure and layout your UI ahead of time without blocking the UI thread.&lt;/li&gt; 
 &lt;li&gt;View flattening: Litho uses Yoga for layout and automatically reduces the number of ViewGroups that your UI contains.&lt;/li&gt; 
 &lt;li&gt;Fine-grained recycling: Any component such as a text or image can be recycled and reused anywhere in the UI.&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Lucee</title>
      <link>https://tedneward.github.io/Research/presentation/lucee/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/lucee/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.lucee.org/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/lucee&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Looks like another Java Web framework, supporting &lt;a href=&quot;../../languages/cfml&quot;&gt;CFML&lt;/a&gt;, albeit with some interesting elements to it.&lt;/p&gt; 
&lt;p&gt;Forked from &lt;a href=&quot;https://github.com/getrailo/railo&quot;&gt;Railo&lt;/a&gt;, another CFML engine.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Marp</title>
      <link>https://tedneward.github.io/Research/presentation/marp/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/marp/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://marp.app&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/marp-team/marp&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Build presentations in Markdown. (Broken out into components, could be useful in other ways as well.)&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Metawidget</title>
      <link>https://tedneward.github.io/Research/presentation/metawidget/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/metawidget/index.html</guid>
      	<description>
	&lt;p&gt;&quot;Metawidget does [UI generation] without introducing new technologies. It inspects your existing back-end architecture (such as JSON, REST, existing annotations, existing configuration files) and creates widgets native to your existing front-end framework (such as JavaScript, Java Server Faces, Android). Metawidget does not replace or restrict your existing UI framework. It does not try to &apos;own&apos; your UI. Its Open Source license allows the use of Metawidget in open source and commercial projects.&quot;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;http://metawidget.org/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;http://metawidget.org/download.php&quot;&gt;Download&lt;/a&gt; | &lt;a href=&quot;https://github.com/metawidget/metawidget&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Last update appears to be 2015; according to the author, this is due to maturity and personal distraction, but that &quot;others have taken up the mantle&quot; and points to ports to major SPA frameworks: &lt;a href=&quot;https://github.com/SDS-React-Metawidget/react-metawidget&quot;&gt;React&lt;/a&gt; and &lt;a href=&quot;https://github.com/AmitsBizruntime/MetawidetA2&quot;&gt;Angular&lt;/a&gt;.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Mobile Angular UI</title>
      <link>https://tedneward.github.io/Research/presentation/mobileangularui/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/mobileangularui/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;http://mobileangularui.com/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/mcasimir/mobile-angular-ui&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>NanoGUI</title>
      <link>https://tedneward.github.io/Research/presentation/nanogui/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/nanogui/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/wjakob/nanogui&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>NoesisGUI</title>
      <link>https://tedneward.github.io/Research/presentation/noesisgui/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/noesisgui/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.noesisengine.com/&quot;&gt;Website&lt;/a&gt; | Commercial/closed-source&lt;/p&gt; 
&lt;p&gt;Pros: battle tested / production ready, impressive list of platforms and backends, markup language, best-in-class visual editor (Microsoft Blend), great documentation with many examples&lt;br&gt; Cons: closed-source, limited free license, developers and UI designers must use Windows, heavy setup and integration&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>OhMyForm</title>
      <link>https://tedneward.github.io/Research/presentation/ohmyform/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/ohmyform/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://ohmyform.com/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/ohmyform&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Looks to be in Python.&lt;/p&gt; 
&lt;p&gt;Features&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Multi-Language Support&lt;/li&gt; 
 &lt;li&gt;11 possible question types&lt;/li&gt; 
 &lt;li&gt;Editable start and end pages&lt;/li&gt; 
 &lt;li&gt;Export Submissions to XLS, JSON or CSV&lt;/li&gt; 
 &lt;li&gt;Native Analytics and Google Analytics Support&lt;/li&gt; 
 &lt;li&gt;Embeddable Forms&lt;/li&gt; 
 &lt;li&gt;Forms as a Service API&lt;/li&gt; 
 &lt;li&gt;Customizable Notifications on Form Submission&lt;/li&gt; 
 &lt;li&gt;Web Hooks on Form Submission&lt;/li&gt; 
 &lt;li&gt;Deployable with Heroku and DockerHub&lt;/li&gt; 
 &lt;li&gt;PostgreSQL and sqlite&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>LCARS Desktop Environment</title>
      <link>https://tedneward.github.io/Research/presentation/lcarsde/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/lcarsde/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://lcarsde.github.io/index.html&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/lcarsde&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Interesting, but doesn&apos;t look really ready yet. (Aug 2025)&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Lightning</title>
      <link>https://tedneward.github.io/Research/presentation/lightning/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/lightning/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://developer.salesforce.com/docs/component-library/overview/components&quot;&gt;Components&lt;/a&gt; | &lt;a href=&quot;https://www.lightningdesignsystem.com/&quot;&gt;Design System&lt;/a&gt; | &lt;a href=&quot;https://developer.salesforce.com/docs/atlas.en-us.lightning.meta/lightning/intro_framework.htm&quot;&gt;Lightning Aura Components&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>LiveKit</title>
      <link>https://tedneward.github.io/Research/presentation/livekit/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/livekit/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://livekit.io/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/livekit/livekit-server&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>LynxJS</title>
      <link>https://tedneward.github.io/Research/presentation/lynxjs/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/lynxjs/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://lynxjs.org/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/lynx-family/lynx&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>.NET Multi-platform App UI (MAUI)</title>
      <link>https://tedneward.github.io/Research/presentation/maui/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/maui/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://learn.microsoft.com/en-us/dotnet/maui&quot;&gt;MAUI Docs&lt;/a&gt; (&lt;a href=&quot;https://learn.microsoft.com/en-us/dotnet/maui/opbuildpdf/fb09dc9e6631000255afc54e0ec4c50a/toc.pdf?branch=live&amp;amp;view=net-maui-7.0&quot;&gt;PDF&lt;/a&gt;) | &lt;a href=&quot;https://github.com/dotnet/maui&quot;&gt;Github&lt;/a&gt;&lt;/p&gt; 
&lt;h2&gt;Lists and resources&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/jsuarezruiz/awesome-dotnet-maui&quot;&gt;Awesome MAUI&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>microui</title>
      <link>https://tedneward.github.io/Research/presentation/microui/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/microui/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/rxi/microui&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Morphic</title>
      <link>https://tedneward.github.io/Research/presentation/morphic/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/morphic/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Morphic_(software)&quot;&gt;Wikipedia&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;http://wiki.squeak.org/squeak/morphic&quot;&gt;Squeak Morphic&lt;/a&gt; | &lt;a href=&quot;http://rmod-files.lille.inria.fr/FreeBooks/CollectiveNBlueBook/morphic.final.pdf&quot;&gt;Intro to Squeak Morphic&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://handbook.selflanguage.org/2017.1/morphic.html&quot;&gt;Self Morphic&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://github.com/jmoenig/morphic.js&quot;&gt;morphic.js&lt;/a&gt; | &lt;a href=&quot;https://thiscontext.com/2017/06/28/a-faster-morphic-with-morphic-js/&quot;&gt;&quot;A faster Morphic with morphic.js&quot;&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://github.com/jmoenig/morphic.py&quot;&gt;Morphic for Python&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;See also &lt;a href=&quot;../lively&quot;&gt;Lively Kernel&lt;/a&gt;.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Nativeblocks</title>
      <link>https://tedneward.github.io/Research/presentation/nativeblocks/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/nativeblocks/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://nativeblocks.io/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/nativeblocks&quot;&gt;Source&lt;/a&gt; | &lt;a href=&quot;https://nativeblocks.io/docs/get-started/introduction/&quot;&gt;Docs&lt;/a&gt; | &lt;a href=&quot;https://github.com/nativeblocks/nbx&quot;&gt;NBX UI DSL&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Nuklear</title>
      <link>https://tedneward.github.io/Research/presentation/nuklear/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/nuklear/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://immediate-mode-ui.github.io/Nuklear/doc/nuklear.html&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/Immediate-Mode-UI/Nuklear&quot;&gt;Source&lt;/a&gt; (&lt;a href=&quot;https://github.com/vurtun/nuklear&quot;&gt;Archived repo&lt;/a&gt;)&lt;/p&gt; 
&lt;p&gt;Pros: single header :o, no dependencies, pretty&lt;/p&gt; 
&lt;p&gt;Bindings (some out of date) for Java, D, Go, Rust, Chicken, Nim, Lua, Python, C#, V&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>One</title>
      <link>https://tedneward.github.io/Research/presentation/one/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/one/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://onestack.dev/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/onejs/one&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;One takes Vite, makes it serve React web and React Native. Then adds FS routes, render modes, loaders, middleware, a CLI, Hono, etc.&lt;/p&gt; 
&lt;p&gt;One is a simpler framework because it&apos;s being designed alongside a sync engine, Zero.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>LeanQt</title>
      <link>https://tedneward.github.io/Research/presentation/leanqt/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/leanqt/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/rochus-keller/LeanQt&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>LisaGUI</title>
      <link>https://tedneward.github.io/Research/presentation/lisagui/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/lisagui/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://lisagui.com/&quot;&gt;Website&lt;/a&gt;&lt;/p&gt; 
&lt;h2&gt;Reading&lt;/h2&gt; 
&lt;h3&gt;Articles&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://hackaday.com/2025/07/14/explore-the-granddaddy-of-all-macs-with-lisagui/&quot;&gt;https://hackaday.com/2025/07/14/explore-the-granddaddy-of-all-macs-with-lisagui/&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Lively Kernel</title>
      <link>https://tedneward.github.io/Research/presentation/lively/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/lively/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://lively-kernel.org/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/LivelyKernel/LivelyKernel&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Modern &lt;a href=&quot;../morphic&quot;&gt;Morphic&lt;/a&gt; interface for browsers.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Marked.js</title>
      <link>https://tedneward.github.io/Research/presentation/markedjs/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/markedjs/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://marked.js.org/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/markedjs/marked&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Written in TypeScript, usable either server-side/static-generation or client-side/render-on-demand.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>MDP</title>
      <link>https://tedneward.github.io/Research/presentation/mdp/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/mdp/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/visit1985/mdp&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Miso</title>
      <link>https://tedneward.github.io/Research/presentation/miso/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/miso/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/dmjio/miso&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;It features a virtual-dom, recursive diffing / patching algorithm, attribute and property normalization, event delegation, event batching, SVG, Server-sent events, Websockets, type-safe servant-style routing and an extensible Subscription-based subsystem. Inspired by Elm, Redux and Bobril. Miso is pure by default, but side effects (like XHR) can be introduced into the system via the Effect data type. Miso makes heavy use of the GHCJS FFI and therefore has minimal dependencies. Miso can be considered a shallow embedded domain-specific language for modern web programming.&lt;/p&gt; 
&lt;/blockquote&gt; 
&lt;p&gt;&lt;a href=&quot;https://github.com/smelc/miso-darkcraw&quot;&gt;Card game using Miso&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Mux</title>
      <link>https://tedneward.github.io/Research/presentation/mux/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/mux/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://mux.com/&quot;&gt;Website&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;SDK support for Ruby Go Python PHP Elixir Node&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>NextJS</title>
      <link>https://tedneward.github.io/Research/presentation/nextjs/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/nextjs/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://nextjs.org&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/vercel/next.js&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>nw.js</title>
      <link>https://tedneward.github.io/Research/presentation/nwjs/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/nwjs/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://nwjs.io/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/nwjs/nw.js&quot;&gt;Source&lt;/a&gt; | &lt;a href=&quot;https://docs.nwjs.io/&quot;&gt;Docs&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Onsen UI</title>
      <link>https://tedneward.github.io/Research/presentation/onsenui/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/onsenui/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://onsen.io/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/OnsenUI/OnsenUI&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>JujutsuUI (jjui)</title>
      <link>https://tedneward.github.io/Research/presentation/jujutsuui/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/jujutsuui/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://idursun.github.io/jjui/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/idursun/jjui&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Less (CSS)</title>
      <link>https://tedneward.github.io/Research/presentation/less/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/less/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://lesscss.org/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/less/&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Less (which stands for Leaner Style Sheets) is a backwards-compatible language extension for CSS. This is the official documentation for Less, the language and Less.js, the JavaScript tool that converts your Less styles to CSS styles.&lt;/p&gt; 
&lt;p&gt;Because Less looks just like CSS, learning it is a breeze. Less only makes a few convenient additions to the CSS language, which is one of the reasons it can be learned so quickly.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Lit</title>
      <link>https://tedneward.github.io/Research/presentation/lit/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/lit/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://lit.dev/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/lit/lit/&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>ltk</title>
      <link>https://tedneward.github.io/Research/presentation/ltk/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/ltk/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://pyscript.github.io/ltk/?runtime=py&quot;&gt;Website&lt;/a&gt; (running Pyodide) | &lt;a href=&quot;pyscript.github.io/ltk/?runtime=mpy&quot;&gt;Website&lt;/a&gt; (running MicroPython) | &lt;a href=&quot;https://github.com/pyscript/ltk&quot;&gt;Source&lt;/a&gt; | &lt;a href=&quot;https://pyscript.github.io/ltk/&quot;&gt;LTK kitchensink&lt;/a&gt;&lt;/p&gt; 
&lt;h2&gt;Installing LTK&lt;/h2&gt; 
&lt;p&gt;Install LTK from pypi:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;python3 -m pip install pyscript-ltk
&lt;/code&gt;&lt;/pre&gt; 
&lt;h2&gt;Hello World&lt;/h2&gt; 
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;import ltk

ltk.Text(&quot;Hello World&quot;).appendTo(ltk.body)
&lt;/code&gt;&lt;/pre&gt; 
&lt;h2&gt;Getting Started&lt;/h2&gt; 
&lt;p&gt;To get started with LTK, we recommend you try it out on pyscript.com:&lt;br&gt; - &lt;a href=&quot;https://pyscript.com/@laffra/ltk-on-micropython/latest&quot;&gt;Minimal LTK with MicroPython&lt;/a&gt;&lt;br&gt; - &lt;a href=&quot;https://pyscript.com/@laffra/ltk-on-pyodide/latest&quot;&gt;Minimal LTK with PyOdide&lt;/a&gt;&lt;/p&gt; 
&lt;h2&gt;Widget Specification&lt;/h2&gt; 
&lt;p&gt;New widget types are created by subclassing &lt;code&gt;ltk.Widget&lt;/code&gt;:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;class HBox(Widget):
    classes = [ &quot;ltk-hbox&quot; ]
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;By default, widgets are created as &lt;code&gt;div&lt;/code&gt; DOM elements. You can choose a different tag:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;class Preformatted(Widget):
    classes = [ &quot;ltk-pre&quot; ]
    tag = &quot;pre&quot;
&lt;/code&gt;&lt;/pre&gt; 
&lt;h2&gt;Creating a UI&lt;/h2&gt; 
&lt;p&gt;To create a UI, elements are constructed declaratively:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;ltk.Table(
    ltk.TableRow(
        ltk.TableHeader(&quot;header1&quot;)
        ltk.TableHeader(&quot;header2&quot;)
    ),
    [
        ltk.TableRow(
            ltk.TableData(value1),
            ltk.TableData(value2),
        )
        for value1, value2 in data
    ],
)
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Widgets are added to others by using &lt;code&gt;jQuery&lt;/code&gt;&apos;s &lt;code&gt;append&lt;/code&gt; and &lt;code&gt;appendTo&lt;/code&gt; calls:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;ltk.body.append(
    ltk.Table(...).element
)

container = ltk.VBox(...)
ltk.H1(&quot;This is a header&quot;).appendTo(container)
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;When an LTK widget is created, a corresponding jQuery element is attached to it in&lt;br&gt; the &lt;code&gt;ltk.Widget.__init__&lt;/code&gt; constructor. It uses the &lt;code&gt;tag&lt;/code&gt; value defined by the&lt;br&gt; declaring class and the constructed element is referred to as &lt;code&gt;element&lt;/code&gt;.&lt;br&gt; As the &lt;code&gt;append&lt;/code&gt; call is a JavaScript function, implemented by jQuery, we do not&lt;br&gt; pass the LTK widget directly, but pass its &lt;code&gt;element&lt;/code&gt; to append to the DOM.&lt;/p&gt; 
&lt;h2&gt;Styling&lt;/h2&gt; 
&lt;p&gt;Widgets can be styled using using three different approaches:&lt;/p&gt; 
&lt;ol&gt; 
 &lt;li&gt;Styling with element styles using &lt;code&gt;jQuery&lt;/code&gt;&apos;s &lt;code&gt;css&lt;/code&gt; function:&lt;/li&gt; 
&lt;/ol&gt; 
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;ltk.Text(&quot;Error: Flux capacitor low!&quot;)
    .css(&quot;background-color&quot;, &quot;red&quot;)
    .css(&quot;color&quot;, &quot;white&quot;)
    .css(&quot;padding&quot;, 8)
&lt;/code&gt;&lt;/pre&gt; 
&lt;ol&gt; 
 &lt;li&gt;Styling using a &lt;code&gt;dict&lt;/code&gt; to make it easier to share styles:&lt;/li&gt; 
&lt;/ol&gt; 
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;error = {
    &quot;background-color&quot;: &quot;red&quot;,
    &quot;color&quot;: &quot;white&quot;,
    &quot;padding&quot;: 8,
}
ltk.Text(&quot;Error: Flux capacitor low!&quot;, error)
&lt;/code&gt;&lt;/pre&gt; 
&lt;ol&gt; 
 &lt;li&gt;Styling using CSS classes and an external stylesheet, using &lt;code&gt;jQuery&lt;/code&gt;&apos;s &lt;code&gt;addClass&lt;/code&gt; function:&lt;/li&gt; 
&lt;/ol&gt; 
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;ltk.Text(&quot;Some text&quot;).addClass(&quot;my-special-text)
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;The external style sheet should have these rules:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-css&quot;&gt;.ltk-text {
    font-family: Arial;
}

.my-special-text {
    font-family: Courier;
    background-color: red;
    color: white;
    padding: 8px;
}
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;External stylesheets can be included in the original &lt;code&gt;index.html&lt;/code&gt; or injected at runtime from Python using:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;ltk.inject_style(&quot;https://example.org/awesome_styles.css&quot;)
&lt;/code&gt;&lt;/pre&gt; 
&lt;h2&gt;Events&lt;/h2&gt; 
&lt;p&gt;Event handlers are attached using &lt;code&gt;jQuery&lt;/code&gt; mechanisms.&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;def buy(event):
    purchase(...)

ltk.Card(&quot;Buy Now&quot;).on(&quot;click&quot;, ltk.proxy(buy))
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;You can also use the more declarative decorator:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;@ltk.callback
def buy(event):
    purchase(...)

ltk.Card(&quot;Buy Now&quot;).on(&quot;click&quot;, buy)
&lt;/code&gt;&lt;/pre&gt;
	</description>
    </item>
    <item>
      <title>Marko</title>
      <link>https://tedneward.github.io/Research/presentation/markojs/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/markojs/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://markojs.com/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/marko-js/marko&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>MDWiki</title>
      <link>https://tedneward.github.io/Research/presentation/mdwiki/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/mdwiki/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://dynalon.github.io/mdwiki/#!index.md&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/Dynalon/mdwiki&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Not really a &quot;wiki&quot;, per se (doesn&apos;t automatically create links to other pages, doesn&apos;t create a new page on request, etc). More like a JS browser-hosted Markdown renderer.&lt;/p&gt; 
&lt;p&gt;Does support client-side &quot;gimmicks&quot; to do various Bootstrappy things, a la alerts, specially-rendered links, and so on.&lt;/p&gt; 
&lt;h2&gt;Configuration&lt;/h2&gt; 
&lt;p&gt;You can create a &lt;code&gt;config.json&lt;/code&gt; file in the same folder as the &lt;code&gt;mdwiki.html&lt;/code&gt; file which is then used for configuration. The file has to be valid JSON. Currently these options are available:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;code&gt;&quot;useSideMenu&quot;: false&lt;/code&gt; - disable the side navigation&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;&quot;lineBreaks&quot;: &quot;original&quot;&lt;/code&gt; - Instead of using the &lt;a href=&quot;https://help.github.com/articles/github-flavored-markdown&quot;&gt;GFM&lt;/a&gt; line breaks, use the original line breaking as &lt;a href=&quot;http://daringfireball.net/projects/markdown/&quot;&gt;introduced by John Gruber&lt;/a&gt;: 
  &lt;ul&gt; 
   &lt;li&gt;line breaks in the markdown files are ignored, except if a line ends with two spaces&lt;/li&gt; 
   &lt;li&gt;Default is &lt;code&gt;lineBreaks: &quot;gfm&quot;&lt;/code&gt; (line breaks in markdown will create a new paragraph)&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;&quot;additionalFooterText&quot;: &quot;&quot;&lt;/code&gt; 
  &lt;ul&gt; 
   &lt;li&gt;Can be used to add text to the copyright footer at the bottom, like custom copyright notices.&lt;/li&gt; 
   &lt;li&gt;Example: &lt;code&gt;additionalFooterText: &quot;All content and images &amp;amp;copy; by John Doe&quot;&lt;/code&gt;&lt;/li&gt; 
   &lt;li&gt;Default: &lt;code&gt;&quot;&quot;&lt;/code&gt; (empty string)&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;&quot;anchorCharacter&quot;: &quot;&amp;amp;para;&quot;&lt;/code&gt; 
  &lt;ul&gt; 
   &lt;li&gt;The character/text displayed and used as a hyperlink when hovering over headings.&lt;/li&gt; 
   &lt;li&gt;Unicode characters can be used in HTML notation. Example: &lt;code&gt;&amp;amp;#x2693;&lt;/code&gt; will render as ⚓&lt;/li&gt; 
   &lt;li&gt;Default: The pilcrow (paragraph) sign: ¶&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;&quot;title&quot;: &quot;ACME Industries Wiki&quot;&lt;/code&gt; 
  &lt;ul&gt; 
   &lt;li&gt;Changes the title of the webpage.&lt;/li&gt; 
   &lt;li&gt;Default: &lt;code&gt;&quot;MDWiki&quot;&lt;/code&gt;&lt;/li&gt; 
   &lt;li&gt;Note - this parameter does not change the title of your wiki in Google search results. Edit &lt;code&gt;mdwiki.html&lt;/code&gt; directly to correct this. (&lt;a href=&quot;https://github.com/Dynalon/mdwiki/issues/58&quot;&gt;Issue #58&lt;/a&gt;)&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;A sample &lt;code&gt;config.json&lt;/code&gt; might thus look like this:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;{
    &quot;useSideMenu&quot;: true,
    &quot;lineBreaks&quot;: &quot;gfm&quot;,
    &quot;additionalFooterText&quot;: &quot;All content and images &amp;amp;copy; by John Doe&quot;,
    &quot;anchorCharacter&quot;: &quot;#&quot;
}
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Note: More configuration options will be available in future versions of MDwiki.&lt;/p&gt; 
&lt;p&gt;Hint: It is adviced that you create an empty config.json in each cases, to avoid 404 errors which will not get cached by your browser. Having an &lt;code&gt;config.json&lt;/code&gt; file present thus will speed up page loading (even if its empty).&lt;/p&gt; 
&lt;h2&gt;Example&lt;/h2&gt; 
&lt;p&gt;Website-as-Markdown-source: &lt;a href=&quot;https://github.com/Dynalon/mdwiki/tree/gh-pages&quot;&gt;https://github.com/Dynalon/mdwiki/tree/gh-pages&lt;/a&gt;&lt;/p&gt; 
&lt;h4&gt;Gimmicks: &lt;a href=&quot;https://dynalon.github.io/mdwiki/#!./gimmicks.md&quot;&gt;https://dynalon.github.io/mdwiki/#!./gimmicks.md&lt;/a&gt;&lt;/h4&gt; 
&lt;p&gt;Gimmicks are little helper that bring plenty of dynamic features into your page. For example, you can use them to inline youtube videos, image slideshows or facebook like buttons.&lt;/p&gt; 
&lt;p&gt;To use Gimmicks, all you have to do is include some specially crafted link into your markdown file. For example, if you want to embed a Youtube video (instead of linking to it), you just have to insert a link to the video:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;[](http://www.youtube.com/watch?v=RMINSD7MmT4)
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Gimmicks are realized via Javascript and work out of the box. Some gimmicks can be called with parameters on them, to customize their behaviour:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;[gimmick:ForkMeOnGitHub ({ color: &apos;red&apos;,  position: &apos;left&apos; })](http://www.github.com/Dynalon/mdwiki)
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;The arguments are passed as a Javascript object. But for convienience reasons, you can omit the curly brackets &lt;code&gt;{ }&lt;/code&gt;. The gimmick name after &lt;code&gt;gimmick:&lt;/code&gt; is also case-insensitive:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;[gimmick:forkmeongithub(color: &apos;red&apos;, position: &apos;left&apos;)](http://www.github.com/Dynalon/mdwiki)
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Gimmicks are designed to always chose sane default values when no parameters are given, therefore &lt;em&gt;most&lt;/em&gt; gimmicks do not require any parameters to work.&lt;/p&gt; 
&lt;p&gt;Note: Gimmicks will usually load code or stylesheets from the internet, therefore they won&apos;t work in offline mode&lt;/p&gt; 
&lt;hr&gt; 
&lt;h5&gt;Alerts&lt;/h5&gt; 
&lt;p&gt;Alerts are automatically placed whenever you start a paragraph with a special &lt;em&gt;trigger&lt;/em&gt; word, that &lt;em&gt;has&lt;/em&gt; to be followed by a colon &lt;code&gt;:&lt;/code&gt; or exclamation mark &lt;code&gt;!&lt;/code&gt;.&lt;/p&gt; 
&lt;p&gt;Trigger words are case insensitive, and must be one of the following:&lt;/p&gt; 
&lt;table&gt; 
 &lt;thead&gt; 
  &lt;tr&gt;
   &lt;th&gt; Type &lt;/th&gt;
   &lt;th&gt; Trigger &lt;/th&gt;
  &lt;/tr&gt; 
 &lt;/thead&gt; 
 &lt;tbody&gt; 
  &lt;tr&gt;
   &lt;td&gt; Warning &lt;/td&gt;
   &lt;td&gt; warning, achtung, attention, warnung, atención, guarda, advertimiento, attenzione &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; Note &lt;/td&gt;
   &lt;td&gt; note, beachte, nota &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; Hint &lt;/td&gt;
   &lt;td&gt; hint, tip, tipp, hinweis, suggerimento &lt;/td&gt;
  &lt;/tr&gt; 
 &lt;/tbody&gt; 
&lt;/table&gt; 
&lt;p&gt;Preview:&lt;/p&gt; 
&lt;p&gt;Attention: This text is important.&lt;/p&gt; 
&lt;p&gt;Note! This is a note.&lt;/p&gt; 
&lt;p&gt;Hint: This is a hint.&lt;/p&gt; 
&lt;hr&gt; 
&lt;h5&gt;GitHub Gists&lt;/h5&gt; 
&lt;p&gt;Gists on github can be embedded by passing their numeric id:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;[gimmick:gist](5641564)
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Preview:&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;5641564&quot;&gt;gimmick:gist&lt;/a&gt;&lt;/p&gt; 
&lt;hr&gt; 
&lt;h5&gt;UML Diagrams via yUML.me&lt;/h5&gt; 
&lt;p&gt;Embeds diagrams from the excellent &lt;a href=&quot;http://yuml.me&quot;&gt;yUML.me&lt;/a&gt; service (see their website for documentation).&lt;/p&gt; 
&lt;p&gt;Examples:&lt;/p&gt; 
&lt;p&gt;[gimmick:yuml]( [HttpContext]uses -.-&amp;gt;[Response] )&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;[gimmick:yuml]( [HttpContext]uses -.-&amp;gt;[Response] )
&lt;/code&gt;&lt;/pre&gt; 
&lt;hr&gt; 
&lt;p&gt;&lt;a href=&quot;[User|+Forename;+Surname;+HashedPassword;-Salt]&quot;&gt;gimmick:yuml (type: &apos;class&apos;)&lt;/a&gt;&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;[gimmick:yuml]([User|+Forename+;Surname;+HashedPassword;-Salt|+Login();+Logout()])
&lt;/code&gt;&lt;/pre&gt; 
&lt;hr&gt; 
&lt;p&gt;[gimmick:yuml (type: &apos;activity&apos;, style: &apos;plain&apos;) ]( &lt;code&gt;Make Coffee´-&amp;gt;&lt;/code&gt;want more coffee´ )&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;[gimmick:yuml (type: &apos;activity&apos;, style: &apos;plain&apos;) ]( `Make Coffee´-&amp;gt;`want more coffee´ )
&lt;/code&gt;&lt;/pre&gt; 
&lt;hr&gt; 
&lt;p&gt;[gimmick:yuml (type: &apos;usecase&apos;, scale: 150) ]( [Customer]-&lt;code&gt;Sign In´, [Customer]-&lt;/code&gt;Buy Products´ )&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;[gimmick:yuml (diag: &apos;usecase&apos;, scale: 150) ]( [Customer]-`Sign In´, [Customer]-`Buy Products´ )
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Arguments&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;strong&gt;direction&lt;/strong&gt;&lt;/li&gt; 
 &lt;li&gt;is one of [ &apos;TB&apos;, &apos;LR&apos; ]&lt;/li&gt; 
 &lt;li&gt;direction of the diagram: top-to-bottom or left-to-right&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;scale&lt;/strong&gt;&lt;/li&gt; 
 &lt;li&gt;is an integer percentage value, i.e. 150 or 200&lt;/li&gt; 
 &lt;li&gt;defines the scaling applied to the diagram in percent, 100% = no scaling&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;type&lt;/strong&gt;&lt;/li&gt; 
 &lt;li&gt;is one of [ &apos;class&apos;, &apos;activity&apos;, &apos;usecase&apos; ]&lt;/li&gt; 
 &lt;li&gt;type of the UML diagram&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;style&lt;/strong&gt;&lt;/li&gt; 
 &lt;li&gt;is one of [ &apos;plain&apos;, &apos;scruffy&apos; ]&lt;/li&gt; 
 &lt;li&gt;defines the applied theme, &lt;em&gt;plain&lt;/em&gt; for clean and &lt;em&gt;scruffy&lt;/em&gt; for comic-style look&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h5&gt;Math&lt;/h5&gt; 
&lt;p&gt;&lt;a href=&quot;&quot;&gt;gimmick: math&lt;/a&gt;&lt;br&gt; Math formulas are realized through the &lt;a href=&quot;http://www.mathjax.org&quot;&gt;MathJax&lt;/a&gt; library. To enable math formulas on a page, the &lt;code&gt;math&lt;/code&gt; gimmick must be loaded by adding this link anywhere in the file:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;[gimmick: math]()
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;To enable math for all sites, put the above link into the &lt;code&gt;navigation.md&lt;/code&gt; file. Putting this link onto the site will load MathJax dynamically from a CDN provider.&lt;/p&gt; 
&lt;p&gt;Note: The MathJax script is very large and loads some more dependencies like fonts. Using the math gimmick might result in slow page loads.&lt;/p&gt; 
&lt;h6&gt;Math inserted to new paragraph&lt;/h6&gt; 
&lt;p&gt;You can add math formulas by putting them between to &lt;code&gt;$$&lt;/code&gt; signs and use LateX syntax:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;$$ x = \frac{-b \pm \sqrt{b^2 - 4ac}}{2a} $$
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;$$ x = \frac{-b \pm \sqrt{b^2 - 4ac}}{2a} $$&lt;/p&gt; 
&lt;h6&gt;# Inline equations&lt;/h6&gt; 
&lt;p&gt;Inline equations can be inserted by surrounding them with the delimiters &lt;code&gt;\\(&lt;/code&gt; and &lt;code&gt;\\)&lt;/code&gt;:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;Diameter \\( d \\) of a circle given area \\( A \\) can by obtained via \\(d=\sqrt{\frac{4A}{\pi}}\\)
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Will show as: Diameter \( d \) of a circle given area \( A \) can by obtained via \(d=\sqrt{\frac{4A}{\pi}}\)&lt;/p&gt; 
&lt;h6&gt;# Some examples&lt;/h6&gt; 
&lt;p&gt;$$ \frac{\partial \phi}{\partial x} \vert_b = \frac{1}{\Delta x/2}(\phi_0-\phi_b) $$&lt;/p&gt; 
&lt;p&gt;$$&lt;br&gt; \int u \frac{dv}{dx},dx=uv-\int&lt;br&gt; \frac{du}{dx}v,dx\lim_{n\rightarrow \infty }&lt;br&gt; \left ( 1 +\frac{1}{n} \right )^n&lt;br&gt; $$&lt;/p&gt; 
&lt;h5&gt;Youtube&lt;/h5&gt; 
&lt;p&gt;Whenever you insert a regular link with an empty caption that points to a video on &lt;code&gt;youtube.com&lt;/code&gt; or &lt;code&gt;youtu.be&lt;/code&gt;, the link is automatically turned into an embedded iframe, which will display a preview thumbnail of the video on your website.&lt;/p&gt; 
&lt;p&gt;Example:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;This will show the video preview on your website:
[](https://www.youtube.com/watch?v=aqz-KE-bpKQ)
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=aqz-KE-bpKQ&quot;&gt;&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;To omit the preview and just get a regular link, add a caption:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;[Click to see an awesome video](https://www.youtube.com/watch?v=aqz-KE-bpKQ)
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=aqz-KE-bpKQ&quot;&gt;Click to see an awesome video&lt;/a&gt;&lt;/p&gt; 
&lt;h5&gt;Chart&lt;/h5&gt; 
&lt;p&gt;Adds a chart to the screen using data from your Markdown table.&lt;/p&gt; 
&lt;h6&gt;Options&lt;/h6&gt; 
&lt;ul&gt; 
 &lt;li&gt;labelColumn: This is a string that indicates which column will be used to label the data points. This String must be a direct match to your table header fro the column.&lt;/li&gt; 
 &lt;li&gt;dataColumns: This is an array of strings that indicated the column to be plotted. This String must be a direct match to your table header fro the column.&lt;/li&gt; 
 &lt;li&gt;canvasId: This is an ID for the generated chart. Defaults to a random number between 1-1000.&lt;/li&gt; 
 &lt;li&gt;chartOptions: This is an object that is passed to chartjs to configure its options. Refer to chartjs for documentation on available options.&lt;/li&gt; 
 &lt;li&gt;chartType: This string is the type of chart render. Bar, Line, or Radar. Defaults to Line.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;Note: Currently only support a single table on a page. You CAN have multiple charts from the same table.&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;| #  | Sprint          | Points | Sum | Avg  | Note |
| -  | --------        |------- | --- | ---- | ---- |
| 1  | Sprint 1        | 6      | 6   | 6.0  | |
| 2  | Sprint 2        | 6      | 12  | 6.0  | |
| 3  | Sprint 3        | 15     | 27  | 9.0  | |
| 4  | Sprint 4        | 9      | 36  | 9.0  | |
| 5  | Sprint 5        | 6      | 42  | 8.4  | |
| 6  | Sprint 6        | 9      | 51  | 8.5  | |

[gimmick:chart ({dataColumns: [&apos;Avg&apos;], labelColumn: &quot;Sprint&quot;, chartType: &apos;Line&apos;, width: &apos;660px&apos;, height: &apos;300px&apos;})]()

[gimmick:chart ({dataColumns: [&apos;Avg&apos;], labelColumn: &quot;Sprint&quot;, chartType: &apos;Bar&apos;, width: &apos;660px&apos;, height: &apos;300px&apos;})]()
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Example:&lt;/p&gt; 
&lt;table&gt; 
 &lt;thead&gt; 
  &lt;tr&gt;
   &lt;th&gt; # &lt;/th&gt;
   &lt;th&gt; Sprint &lt;/th&gt;
   &lt;th&gt; Points &lt;/th&gt;
   &lt;th&gt; Sum &lt;/th&gt;
   &lt;th&gt; Avg &lt;/th&gt;
   &lt;th&gt; Note &lt;/th&gt;
  &lt;/tr&gt; 
 &lt;/thead&gt; 
 &lt;tbody&gt; 
  &lt;tr&gt;
   &lt;td&gt; 1 &lt;/td&gt;
   &lt;td&gt; Sprint 1 &lt;/td&gt;
   &lt;td&gt; 6 &lt;/td&gt;
   &lt;td&gt; 6 &lt;/td&gt;
   &lt;td&gt; 6.0 &lt;/td&gt;
   &lt;td&gt; &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; 2 &lt;/td&gt;
   &lt;td&gt; Sprint 2 &lt;/td&gt;
   &lt;td&gt; 6 &lt;/td&gt;
   &lt;td&gt; 12 &lt;/td&gt;
   &lt;td&gt; 6.0 &lt;/td&gt;
   &lt;td&gt; &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; 3 &lt;/td&gt;
   &lt;td&gt; Sprint 3 &lt;/td&gt;
   &lt;td&gt; 15 &lt;/td&gt;
   &lt;td&gt; 27 &lt;/td&gt;
   &lt;td&gt; 9.0 &lt;/td&gt;
   &lt;td&gt; &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; 4 &lt;/td&gt;
   &lt;td&gt; Sprint 4 &lt;/td&gt;
   &lt;td&gt; 9 &lt;/td&gt;
   &lt;td&gt; 36 &lt;/td&gt;
   &lt;td&gt; 9.0 &lt;/td&gt;
   &lt;td&gt; &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; 5 &lt;/td&gt;
   &lt;td&gt; Sprint 5 &lt;/td&gt;
   &lt;td&gt; 6 &lt;/td&gt;
   &lt;td&gt; 42 &lt;/td&gt;
   &lt;td&gt; 8.4 &lt;/td&gt;
   &lt;td&gt; &lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt; 6 &lt;/td&gt;
   &lt;td&gt; Sprint 6 &lt;/td&gt;
   &lt;td&gt; 9 &lt;/td&gt;
   &lt;td&gt; 51 &lt;/td&gt;
   &lt;td&gt; 8.5 &lt;/td&gt;
   &lt;td&gt; &lt;/td&gt;
  &lt;/tr&gt; 
 &lt;/tbody&gt; 
&lt;/table&gt; 
&lt;p&gt;&lt;a href=&quot;&quot;&gt;gimmick:chart ({dataColumns: [&apos;Avg&apos;], labelColumn: &quot;Sprint&quot;, chartType: &apos;Line&apos;, width: &apos;660px&apos;, height: &apos;300px&apos;})&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;&quot;&gt;gimmick:chart ({dataColumns: [&apos;Avg&apos;], labelColumn: &quot;Sprint&quot;, chartType: &apos;Bar&apos;, width: &apos;660px&apos;, height: &apos;300px&apos;})&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Mithril</title>
      <link>https://tedneward.github.io/Research/presentation/mithril/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/mithril/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://mithril.js.org/index.html&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/MithrilJS/mithril.js&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Naked Objects Framework</title>
      <link>https://tedneward.github.io/Research/presentation/nakedobjects/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/nakedobjects/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/NakedObjectsGroup/NakedObjectsFramework&quot;&gt;Source&lt;/a&gt; | &lt;a href=&quot;https://github.com/NakedObjectsGroup/NakedObjectsFramework/blob/master/Template_NOF10/Template_NOF10.zip?raw=true&quot;&gt;NOF 10 Starter Template&lt;/a&gt; | &lt;a href=&quot;https://github.com/NakedObjectsGroup/NakedObjectsFramework/blob/master/Documentation/NOF10DeveloperManual.docx?raw=true&quot;&gt;Developer&apos;s Manual&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;See also: &lt;a href=&quot;/distribution/restfulobjects.html&quot;&gt;Restful Objects&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Nodify</title>
      <link>https://tedneward.github.io/Research/presentation/nodify/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/nodify/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://miroiu.github.io/nodify/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/miroiu/nodify&quot;&gt;Source&lt;/a&gt; | &lt;a href=&quot;https://github.com/miroiu/nodify/wiki&quot;&gt;Docs&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Avalonia port: &lt;a href=&quot;https://github.com/BAndysc/nodify-avalonia&quot;&gt;https://github.com/BAndysc/nodify-avalonia&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>NXUI</title>
      <link>https://tedneward.github.io/Research/presentation/nxui/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/nxui/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;http://www.nxui.net/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/wieslawsoltes/NXUI&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Usage:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;Window Build() =&amp;gt; Window().Content(Label().Content(&quot;NXUI&quot;));

AppBuilder.Configure&amp;lt;Application&amp;gt;()
  .UsePlatformDetect()
  .UseFluentTheme()
  .StartWithClassicDesktopLifetime(Build, args);

var count = 0;
&lt;/code&gt;&lt;/pre&gt; 
&lt;pre&gt;&lt;code&gt;Window Build()
  =&amp;gt; Window(out var window)
    .Title(&quot;NXUI&quot;).Width(400).Height(300)
    .Content(
      StackPanel()
        .Children(
          Button(out var button)
            .Content(&quot;Welcome to Avalonia, please click me!&quot;),
          TextBox(out var tb1)
            .Text(&quot;NXUI&quot;),
          TextBox()
            .Text(window.BindTitle()),
          Label()
            .Content(button.ObserveOnClick().Select(_ =&amp;gt; ++count).Select(x =&amp;gt; $&quot;You clicked {x} times.&quot;))))
    .Title(tb1.ObserveText().Select(x =&amp;gt; x?.ToUpper()));

AppBuilder.Configure&amp;lt;Application&amp;gt;()
  .UsePlatformDetect()
  .UseFluentTheme()
  .WithApplicationName(&quot;NXUI&quot;)
  .StartWithClassicDesktopLifetime(Build, args);
&lt;/code&gt;&lt;/pre&gt;
	</description>
    </item>
    <item>
      <title>Lanterna</title>
      <link>https://tedneward.github.io/Research/presentation/console/lanterna/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/console/lanterna/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/mabe02/lanterna&quot;&gt;Source&lt;/a&gt; | &lt;a href=&quot;https://github.com/mabe02/lanterna/blob/master/docs/contents.md&quot;&gt;Documentation&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Lanterna is supporting xterm compatible terminals and terminal emulators such as konsole, gnome-terminal, putty, xterm and many more. One of the main benefits of lanterna is that it&apos;s not dependent on any native library but runs 100% in pure Java.&lt;/p&gt; 
&lt;p&gt;Also, when running Lanterna on computers with a graphical environment (such as Windows or Xorg), a bundled terminal emulator written in Swing will be used rather than standard output. This way, you can develop as usual from your IDE (most of them doesn&apos;t support ANSI control characters in their output window) and then deploy to your headless server without changing any code.&lt;/p&gt; 
&lt;p&gt;Lanterna is structured into three layers, each built on top of the other and you can easily choose which one fits your needs best.&lt;/p&gt; 
&lt;ol&gt; 
 &lt;li&gt; &lt;p&gt;The first is a low level terminal interface which gives you the most basic control of the terminal text area. You can move around the cursor and enable special modifiers for characters put to the screen. You will find these classes in package com.googlecode.lanterna.terminal.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;The second level is a full screen buffer, the whole text screen in memory and allowing you to write to this before flushing the changes to the actual terminal. This makes writing to the terminal screen similar to modifying a bitmap. You will find these classes in package com.googlecode.lanterna.screen.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;The third level is a full GUI toolkit with windows, buttons, labels and some other components. It&apos;s using a very simple window management system (basically all windows are modal) that is quick and easy to use. You will find these classes in package com.googlecode.lanterna.gui2.&lt;/p&gt; &lt;/li&gt; 
&lt;/ol&gt;
	</description>
    </item>
    <item>
      <title>Textual</title>
      <link>https://tedneward.github.io/Research/presentation/console/textual/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/console/textual/index.html</guid>
      	<description>
	&lt;h2&gt;Articles&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://realpython.com/python-textual/&quot;&gt;&quot;Python Textual: Build Beautiful UIs in the Terminal&quot;&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Corecalc</title>
      <link>https://tedneward.github.io/Research/presentation/corecalc/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/corecalc/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.itu.dk/people/sestoft/corecalc/&quot;&gt;Website&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Corecalc is an implementation of core spreadsheet functionality in C#, intended as a platform for experiments with technology and novel functionality. Corecalc is a research prototype, not a usable replacement for Microsoft Excel, Gnumeric or LibreOffice Calc.&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://www.itu.dk/people/sestoft/corecalc/corecalc-0.7.1.zip&quot;&gt;Corecalc (old) Source&lt;/a&gt; | &lt;a href=&quot;https://www.itu.dk/people/sestoft/corecalc/ITU-TR-2006-91.pdf&quot;&gt;Report (PDF)&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Funcalc is an extension of Corecalc in which users can define their own functions via sheet-defined functions, without resorting to external languages such as VBA. These are compiled to .NET bytecode at run-time, thus offering high performance while preserving the usual mode of interaction in which all edits take effect immediately. Funcalc is a research prototype.&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://www.itu.dk/people/sestoft/corecalc/funcalc-20140927.zip&quot;&gt;Funcalc Source&lt;/a&gt; &lt;a href=&quot;https://www.itu.dk/people/sestoft/corecalc/funcalc-src-20140927.pdf&quot;&gt;A4 PDF pretty-printed&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>PicoCSS</title>
      <link>https://tedneward.github.io/Research/presentation/css/picocss/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/css/picocss/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://picocss.com/&quot;&gt;Website&lt;/a&gt;&lt;/p&gt; 
&lt;h2&gt;Articles&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://blog.logrocket.com/getting-started-pico-css/&quot;&gt;&quot;Getting Started with Pico CSS&quot;&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Dear ImGui</title>
      <link>https://tedneward.github.io/Research/presentation/dearimgui/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/dearimgui/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/ocornut/imgui&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Designed for game platforms, but I don&apos;t see any reason why it couldn&apos;t work for other things too.&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;.NET: &lt;a href=&quot;https://github.com/ImGuiNET/ImGui.NET&quot;&gt;ImGuiNET&lt;/a&gt;: An ImGui wrapper for .NET. Included is a basic sample program that shows how to use the library, and renders the UI using Veldrid, a portable graphics library for .NET. By itself, Dear ImGui does not care what technology you use for rendering; it simply outputs textured triangles. Example renderers also exist for MonoGame and OpenTK (OpenGL).&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;Pros: battle tested / production ready, available on conan, minimal dependencies&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Discourse</title>
      <link>https://tedneward.github.io/Research/presentation/discourse/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/discourse/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.discourse.org/&quot;&gt;Website&lt;/a&gt; &lt;a href=&quot;https://github.com/discourse/discourse&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>DotVVM</title>
      <link>https://tedneward.github.io/Research/presentation/dotvvm/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/dotvvm/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.dotvvm.com/&quot;&gt;Website&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Commercial options (more components available).&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Eleventy</title>
      <link>https://tedneward.github.io/Research/presentation/eleventy/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/eleventy/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.11ty.dev/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/11ty/eleventy/&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Epoxy</title>
      <link>https://tedneward.github.io/Research/presentation/epoxy/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/epoxy/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/airbnb/epoxy&quot;&gt;Source&lt;/a&gt; | &lt;a href=&quot;https://medium.com/airbnb-engineering/epoxy-airbnbs-view-architecture-on-android-c3e1af150394#.9hno4vdc0&quot;&gt;Blog post&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Flakes</title>
      <link>https://tedneward.github.io/Research/presentation/flakes/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/flakes/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://getflakes.com/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/kumailht/flakes/&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;h3&gt;From the Website&lt;/h3&gt; 
&lt;p&gt;&lt;strong&gt;Quick Start Guide&lt;/strong&gt;&lt;/p&gt; 
&lt;ol&gt; 
 &lt;li&gt;Download the Flakes framework on Github.&lt;/li&gt; 
 &lt;li&gt;Install Dependencies using the &quot;bower install&quot; command. If you don&apos;t have the Bower Package Manager, install it using the instructions on their official site.&lt;/li&gt; 
 &lt;li&gt;Example.html has some boilerplate code that you can use to get started.&lt;/li&gt; 
&lt;/ol&gt; 
&lt;p&gt;&lt;strong&gt;When should I use Flakes?&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;Flakes is intended to be used for business facing web applications. If you&apos;re building an internal tool to help your sales team manage leads or are building an inventory tracking solution for your watch business, you&apos;ll need Flakes.&lt;/p&gt; 
&lt;p&gt;Flakes is a starting point, It helps you get a quick start. It is not a collection of everything you&apos;ll ever need and it doesn&apos;t aim to become one.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;What sort of layouts can I build with Flakes?&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;Flakes is a collection of components. These components follow the Flakes aesthetic and go well together. Since these components are low level abstractions like forms and grids, you really can build almost anything you&apos;ll need.&lt;/p&gt; 
&lt;p&gt;I&apos;ve built a few example layouts for you play around with. Check out the example layouts using the navigation to your left to get a feel for what is possible.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;How do I contribute to Flakes?&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;Until now, Flakes has been a one man show with me designing and developing for it. When you work on something for long enough, you&apos;ll run out of ideas on how to improve it. If you are keen on contributing I&apos;d love to have you make a pull request with your change. If it&apos;s a sufficiently big change, I&apos;d recommend filing an issue on Github to discuss the change to avoid duplicate or unnecessary work.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>FormIO</title>
      <link>https://tedneward.github.io/Research/presentation/formio/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/formio/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://form.io/&quot;&gt;Website&lt;/a&gt; | Commercial?&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Frappe</title>
      <link>https://tedneward.github.io/Research/presentation/frappe/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/frappe/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://frappeframework.com/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/frappe/frappe&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;From the website:&lt;/p&gt; 
&lt;h2&gt;Batteries Included&lt;/h2&gt; 
&lt;p&gt;Frappe ships with essential modules that are required to build any serious business application&lt;/p&gt; 
&lt;h3&gt;Metadata First&lt;/h3&gt; 
&lt;p&gt;Everything in Frappe is a DocType. DocTypes can be defined easily without code used everywhere.&lt;/p&gt; 
&lt;h3&gt;Admin User Interface&lt;/h3&gt; 
&lt;p&gt;Frappe comes with a rich single page application (SPA) with built in forms, list, search and navigation.&lt;/p&gt; 
&lt;h3&gt;Roles and Permissions&lt;/h3&gt; 
&lt;p&gt;You define user roles and permissions that are applied out of the box on all interactions.&lt;/p&gt; 
&lt;h3&gt;Extensible&lt;/h3&gt; 
&lt;p&gt;With a modular architecture, you can create your own apps that can be extended by other apps.&lt;/p&gt; 
&lt;h3&gt;REST API + Webhooks&lt;/h3&gt; 
&lt;p&gt;Frappe is integration friendly and comes with REST API and Webhooks on all models based on authentication.&lt;/p&gt; 
&lt;h3&gt;Job Scheduler&lt;/h3&gt; 
&lt;p&gt;You can configure background workers and run periodic tasks powered by Python RQ.&lt;/p&gt; 
&lt;h3&gt;Socket.io&lt;/h3&gt; 
&lt;p&gt;Frappe comes with first class socket.io support based on NodeJS and using Redis pub-sub.&lt;/p&gt; 
&lt;h3&gt;Email Setup&lt;/h3&gt; 
&lt;p&gt;Send, receive, view and manage emails easily using SMTP and IMAP based email accounts.&lt;/p&gt; 
&lt;h3&gt;Multi-tenant&lt;/h3&gt; 
&lt;p&gt;Database driven multi-tenant architecture easily lets you host multiple sites on a single server.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Graphics and Animation</title>
      <link>https://tedneward.github.io/Research/presentation/graphics/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/graphics/index.html</guid>
      	<description>
	&lt;h3&gt;Graphics Programming Books&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/lettier/3d-game-shaders-for-beginners&quot;&gt;3D Game Shaders For Beginners&lt;/a&gt; - David Lettier (Git) &lt;a href=&quot;https://lettier.github.io/3d-game-shaders-for-beginners&quot;&gt;(HTML)&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://en.wikibooks.org/wiki/Blender_3D%3A_Noob_to_Pro&quot;&gt;Blender 3D: Noob to Pro&lt;/a&gt; - Wikibooks&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://docs.blender.org/manual/en/latest&quot;&gt;Blender Manual&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://gabrielgambetta.com/computer-graphics-from-scratch&quot;&gt;Computer Graphics from scratch&lt;/a&gt; - Gabriel Gambetta (:construction: &lt;em&gt;in process&lt;/em&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://user.xmission.com/~legalize/book/download/index.html&quot;&gt;DirectX manual&lt;/a&gt; (draft)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://developer.nvidia.com/gpugems/GPUGems/gpugems_pref01.html&quot;&gt;GPU Gems&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.gamedev.net/page/resources/_/technical/graphics-programming-and-theory/graphics-programming-black-book-r1698&quot;&gt;Graphics Programming Black Book&lt;/a&gt; - Michael Abrash&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://open.gl&quot;&gt;Introduction to Modern OpenGL&lt;/a&gt; - Alexander Overvoorde (HTML, EPUB, PDF) (C++)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://leanpub.com/introductiontotouchdesigner/&quot;&gt;Introduction to TouchDesigner 099&lt;/a&gt; &lt;em&gt;(Leanpub account or valid email requested)&lt;/em&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.scratchapixel.com&quot;&gt;Learn Computer Graphics From Scratch!&lt;/a&gt; - Scratchapixel (:construction: &lt;em&gt;in process&lt;/em&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://learnopengl.com&quot;&gt;Learn OpenGL&lt;/a&gt; - Joey de Vries&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/bwasty/learn-opengl-rs&quot;&gt;Learn OpenGL RS&lt;/a&gt; - Benjamin Wasty et al. (:construction: &lt;em&gt;in process&lt;/em&gt;) (Rust)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://web.archive.org/web/20150225192611/http://www.arcsynthesis.org/gltut/index.html&quot;&gt;Learning Modern 3D Graphics Programming&lt;/a&gt; - Jason L. McKesson (draft)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.cs.csustan.edu/~rsc/CS3600F00/Notes.pdf&quot;&gt;Notes for a Computer Graphics Programming Course&lt;/a&gt; - Dr. Steve Cunningham (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.songho.ca/opengl/index.html&quot;&gt;OpenGL&lt;/a&gt; - Concepts and illustrations.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://raytracing.github.io&quot;&gt;Ray Tracing in One Weekend&lt;/a&gt; - Peter Shirley (HTML)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.realtimerendering.com/resources/shaderx/&quot;&gt;ShaderX series&lt;/a&gt; - Wolfgang Engel&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.opengl-tutorial.org&quot;&gt;Tutorials for modern OpenGL&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://webglinsights.com&quot;&gt;WebGL Insights&lt;/a&gt; - Patrick Cozzi and Contributors&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>HBuilder</title>
      <link>https://tedneward.github.io/Research/presentation/hbuilder/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/hbuilder/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.dcloud.io/index.html&quot;&gt;Website&lt;/a&gt; and &lt;a href=&quot;https://www.dcloud.io/hbuilderx.html&quot;&gt;here&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Not much English docs, but seems reasonable to use. &lt;a href=&quot;../vue&quot;&gt;Vue&lt;/a&gt;-based&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>HyperText Markup Language (HTML)</title>
      <link>https://tedneward.github.io/Research/presentation/html/index/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/html/index/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://html.spec.whatwg.org/multipage/&quot;&gt;Standard&lt;/a&gt; (&lt;a href=&quot;https://html.spec.whatwg.org/print.pdf&quot;&gt;PDF&lt;/a&gt;)&lt;/p&gt; 
&lt;h2&gt;Reading&lt;/h2&gt; 
&lt;h3&gt;Books&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;http://learn.shayhowe.com/html-css/&quot;&gt;A beginner&apos;s guide to HTML&amp;amp;CSS&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://marksheet.io&quot;&gt;A free guide to learn HTML and CSS&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://adaptivewebdesign.info/1st-edition/&quot;&gt;Adaptive Web Design&lt;/a&gt; - Aaron Gustafson&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://learn.shayhowe.com/advanced-html-css/&quot;&gt;An advanced guide to HTML&amp;amp;CSS&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://atomicdesign.bradfrost.com&quot;&gt;Atomic Design&lt;/a&gt; - Brad Frost&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://web.archive.org/web/20160505010319/http://learnjs.io/canvassing/read/&quot;&gt;Canvassing&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://mdo.github.io/code-guide/&quot;&gt;Code Guide: Standards for developing flexible, durable, and sustainable HTML and CSS&lt;/a&gt; - Mark Otto&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://diveinto.html5doctor.com&quot;&gt;Dive Into HTML5&lt;/a&gt; - Mark Pilgrim (&lt;a href=&quot;http://mislav.net/2011/10/dive-into-html5/&quot;&gt;PDF&lt;/a&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://domenlightenment.com&quot;&gt;DOM Enlightenment&lt;/a&gt; - Cody Lindley (HTML)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://dash.generalassemb.ly&quot;&gt;GA Dash&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://google.github.io/styleguide/htmlcssguide.html&quot;&gt;Google&apos;s HTML/CSS Style Guide&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.digitalocean.com/community/books/how-to-build-a-website-with-html-ebook&quot;&gt;How To Build a Website with HTML&lt;/a&gt; - Erin Glass (PDF, EPUB)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://web.archive.org/web/20180816174417/http://howtocodeinhtml.com/HowToCodeInHTML5AndCSS3.pdf&quot;&gt;How to Code in HTML5 and CSS3&lt;/a&gt; - Damian Wielgosik (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://joshondesign.com/p/books/canvasdeepdive/toc.html&quot;&gt;HTML Canvas Deep Dive&lt;/a&gt; - Josh Marinacci&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://www.htmldog.com&quot;&gt;HTML Dog Tutorials&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.oreilly.com/library/view/html5-canvas/9781449308032/ch01.html&quot;&gt;HTML5 Canvas&lt;/a&gt; - Steve Fulton &amp;amp; Jeff Fulton&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://goalkicker.com/HTML5CanvasBook/&quot;&gt;HTML5 Canvas Notes for Professionals&lt;/a&gt; - Compiled from StackOverflow documentation (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.oreilly.com/library/view/html5-for-publishers/9781449320065/pr02.html&quot;&gt;HTML5 for Publishers&lt;/a&gt; - Sanders Kleinfeld&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://html5forwebdesigners.com&quot;&gt;HTML5 For Web Designers&lt;/a&gt; - Jeremy Keith&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://goalkicker.com/HTML5Book/&quot;&gt;HTML5 Notes for Professionals&lt;/a&gt; - Compiled from StackOverflow documentation (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.ossblog.org/wp-content/uploads/2017/06/html5-quick-learning-quide.pdf&quot;&gt;HTML5 Quick Learning Guide&lt;/a&gt; - HTML5Templates (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://leanpub.com/html5shootemupinanafternoon/read&quot;&gt;HTML5 Shoot &apos;em Up in an Afternoon&lt;/a&gt; - Bryan Bibat (HTML)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.internetingishard.com&quot;&gt;Interneting is Hard (But it Doesn&apos;t Have to Be)&lt;/a&gt; - Oliver James&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://learn.shayhowe.com&quot;&gt;Learn to Code HTML &amp;amp; CSS&lt;/a&gt; - Shay Howe&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://svgpocketguide.com&quot;&gt;Pocket Guide to Writing SVG&lt;/a&gt; - Joni Trythall&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://web.archive.org/web/20181215200026/http://apress.jensimmons.com/v5/pro-html5-programming/ch0.html&quot;&gt;Pro HTML5 Programming&lt;/a&gt; - Jen Simmons, Chris O&apos;Connor, Dylan Wooters, Peter Lubbers&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://resilientwebdesign.com/#Resilientweb%20design&quot;&gt;Resilient Web Design&lt;/a&gt; - Jeremy Keith&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://rtlstyling.com&quot;&gt;RTL Styling 101&lt;/a&gt; - Ahmad Shadeed&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://flaviocopes.com/page/html-handbook/&quot;&gt;The HTML Handbook&lt;/a&gt; - Flavio Copes (PDF, EPUB, Kindle) &lt;em&gt;(email address requested)&lt;/em&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://chimera.labs.oreilly.com/books/1234000001552&quot;&gt;Web Audio API&lt;/a&gt; - Boris Smus&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://leanpub.com/web-visual-effects-with-css3/read&quot;&gt;Web Visual Effects with CSS3&lt;/a&gt; - Thomas Mak&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Articles&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://dev.to/maxprilutskiy/html5-elements-you-didnt-know-you-need-gan&quot;&gt;&quot;HTML5 Elements You Didn&apos;t Know You Need&quot;&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.htmhell.dev/adventcalendar/2025/27/&quot;&gt;Replacing JS with just HTML&lt;/a&gt; (Accordions / Expanding Content Panels; Input with Autofilter Suggestions Dropdown; Modals / Popovers; Offscreen Nav / Content)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.smashingmagazine.com/2025/12/masonry-things-you-wont-need-library-anymore/&quot;&gt;Masonry: Things You Won’t Need A Library For Anymore&lt;/a&gt;: 
  &lt;ul&gt; 
   &lt;li&gt;&lt;strong&gt;Popovers And Dialogs&lt;/strong&gt;: The &lt;a href=&quot;https://developer.mozilla.org/docs/Web/API/Popover_API&quot;&gt;Popover API&lt;/a&gt;, the &lt;a href=&quot;https://developer.mozilla.org/docs/Web/HTML/Reference/Elements/dialog&quot;&gt;&lt;code&gt;&amp;lt;dialog&amp;gt;&lt;/code&gt; HTML element&lt;/a&gt;, and the &lt;a href=&quot;https://developer.mozilla.org/docs/Web/CSS/Reference/Selectors/::backdrop&quot;&gt;&lt;code&gt;::backdrop&lt;/code&gt; pseudo-element&lt;/a&gt; can help you get rid of dependencies on popup, tooltip, and dialog libraries. They handle accessibility and focus management for you, out of the box, are highly customizable by using CSS, and can easily be animated.&lt;/li&gt; 
   &lt;li&gt;&lt;strong&gt;Accordions&lt;/strong&gt;: The &lt;a href=&quot;https://developer.mozilla.org/docs/Web/HTML/Reference/Elements/details&quot;&gt;&lt;code&gt;&amp;lt;details&amp;gt;&lt;/code&gt; element&lt;/a&gt;, its &lt;a href=&quot;https://developer.mozilla.org/docs/Web/HTML/Reference/Elements/details#name&quot;&gt;&lt;code&gt;name&lt;/code&gt; attribute&lt;/a&gt; for mutually exclusive elements, and the &lt;a href=&quot;https://developer.mozilla.org/docs/Web/CSS/Reference/Selectors/::details-content&quot;&gt;&lt;code&gt;::details-content&lt;/code&gt; pseudo-element&lt;/a&gt; remove the need for accordion components.&lt;/li&gt; 
   &lt;li&gt;&lt;strong&gt;CSS Syntax&lt;/strong&gt;: Cascade layers, for a more organized CSS codebase, CSS nesting, for more compact CSS, new color functions, relative colors, and color-mix, new Maths functions like abs(), sign(), pow() and others help reduce dependencies on CSS pre-processors, utility libraries like Bootstrap and Tailwind, or even runtime CSS-in-JS libraries. The game changer :has(), one of the most requested features for a long time, removes the need for more complicated JS-based solutions.&lt;/li&gt; 
   &lt;li&gt;&lt;strong&gt;JS Utilities&lt;/strong&gt;: Modern Array methods like &lt;code&gt;findLast()&lt;/code&gt;, or &lt;code&gt;at()&lt;/code&gt;, as well as Set methods like &lt;code&gt;difference()&lt;/code&gt;, &lt;code&gt;intersection()&lt;/code&gt;, &lt;code&gt;union()&lt;/code&gt; and others can reduce dependencies on libraries like Lodash.&lt;/li&gt; 
   &lt;li&gt;&lt;strong&gt;Container Queries&lt;/strong&gt;: &lt;a href=&quot;https://developer.mozilla.org/docs/Web/CSS/CSS_containment/Container_queries&quot;&gt;Container queries&lt;/a&gt; make UI components respond to things other than the viewport size, and therefore make them more reusable across different contexts. No need to use a JS-heavy UI library for this anymore, and no need to use a polyfill either.&lt;/li&gt; 
   &lt;li&gt;&lt;strong&gt;Layout&lt;/strong&gt;: &lt;a href=&quot;https://developer.mozilla.org/docs/Web/CSS/CSS_grid_layout&quot;&gt;Grid&lt;/a&gt;, &lt;a href=&quot;https://developer.mozilla.org/docs/Web/CSS/CSS_grid_layout/Subgrid&quot;&gt;subgrid&lt;/a&gt;, &lt;a href=&quot;https://developer.mozilla.org/docs/Learn_web_development/Core/CSS_layout/Flexbox&quot;&gt;flexbox&lt;/a&gt;, or &lt;a href=&quot;https://developer.mozilla.org/docs/Web/CSS/Reference/Properties/columns&quot;&gt;multi-column&lt;/a&gt; have been around for a long time now, but looking at the results of the State of CSS surveys, it’s clear that developers tend to be very cautious with adopting new things, and wait for a very long time before they do.&lt;/li&gt; 
  &lt;/ul&gt; &lt;p&gt;Things you might not need anymore in the near future:&lt;/p&gt; 
  &lt;ul&gt; 
   &lt;li&gt;&lt;strong&gt;Anchor Positioning&lt;/strong&gt;: CSS anchor positioning handles the positioning of popovers and tooltips relative to other elements, and takes care of keeping them in view, even when moving, scrolling, or resizing the page. This is a great complement to the Popover API mentioned before, which will make it even easier to migrate away from more performance-intensive JS solutions.&lt;/li&gt; 
   &lt;li&gt;&lt;strong&gt;Navigation API&lt;/strong&gt;: The Navigation API can be used to handle navigation in single-page apps and might be a great complement, or even a replacement, to React Router, Next.js routing, or Angular routing tasks.&lt;/li&gt; 
   &lt;li&gt;&lt;strong&gt;View Transitions API&lt;/strong&gt;: The View Transitions API can animate between the different states of a page. On a single-page application, this makes smooth transitions between states very easy, and can help you get rid of animation libraries such as Anime.js, GSAP, or Motion.dev. Even better, the API can also be used with multiple-page applications.&lt;/li&gt; 
   &lt;li&gt;&lt;strong&gt;Scroll-driven Animations&lt;/strong&gt;: Scroll-driven animations run on the user’s scroll position, rather than over time, making them a great solution for storytelling and product tours.&lt;/li&gt; 
   &lt;li&gt;&lt;strong&gt;Customizable Selects&lt;/strong&gt;: A customizable select is a normal &lt;code&gt;&amp;lt;select&amp;gt;&lt;/code&gt; element that lets you fully customize its appearance and content, while ensuring accessibility and performance benefits.&lt;/li&gt; 
   &lt;li&gt;&lt;strong&gt;CSS Masonry&lt;/strong&gt;: &lt;a href=&quot;https://developer.chrome.com/blog/masonry-update&quot;&gt;CSS Masonry&lt;/a&gt; is another upcoming web platform feature that I want to spend more time on. With CSS Masonry, you can achieve layouts that are very hard, or even impossible, with flex, grid, or other built-in CSS layout primitives. Developers often resort to using third-party libraries to achieve Masonry layouts, such as the Masonry JS library. &quot;Masonry is a type of layout that was made popular by Pinterest years ago. It creates independent tracks of content within which items pack themselves up as close to the start of the track as they can.&quot;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Ionic</title>
      <link>https://tedneward.github.io/Research/presentation/ionic/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/ionic/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://ionicframework.com/&quot;&gt;Website&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Used to build on top of &lt;a href=&quot;../cordova&quot;&gt;Cordova&lt;/a&gt; but now uses its own runtime which is backwards-compatible.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>jQuery, jQuery Mobile</title>
      <link>https://tedneward.github.io/Research/presentation/jquery/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/jquery/index.html</guid>
      	<description>
	&lt;h1&gt;jQuery&lt;/h1&gt; 
&lt;p&gt;&lt;a href=&quot;https://jquery.com/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/jquery/jquery&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://terminal.jcubic.pl/&quot;&gt;jQuery Terminal&lt;/a&gt;: creating command line interpreters in your Web applications.&lt;/p&gt; 
&lt;h1&gt;jQuery UI&lt;/h1&gt; 
&lt;p&gt;A curated set of user interface interactions, effects, widgets, and themes built on top of the jQuery JavaScript Library.&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://jqueryui.com/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/jquery/jquery-ui&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;h1&gt;jQuery Mobile -- No longer supported&lt;/h1&gt; 
&lt;p&gt;&lt;a href=&quot;https://jquerymobile.com/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/jquery/jquery-mobile&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;http://jqfundamentals.com&quot;&gt;jQuery Fundamentals&lt;/a&gt; - Bocoup (HTML)&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>FTXUI</title>
      <link>https://tedneward.github.io/Research/presentation/console/ftxui/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/console/ftxui/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/ArthurSonzogni/FTXUI&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;h4&gt;Example:&lt;/h4&gt; 
&lt;p&gt;&lt;img src=&quot;https://private-user-images.githubusercontent.com/4759106/243190749-569bf043-4e85-4245-aad5-2324572135c4.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;    vbox({
      hbox({
        text(&quot;one&quot;) | border,
        text(&quot;two&quot;) | border | flex,
        text(&quot;three&quot;) | border | flex,
      }),

      gauge(0.25) | color(Color::Red),
      gauge(0.50) | color(Color::White),
      gauge(0.75) | color(Color::Blue),
    });
&lt;/code&gt;&lt;/pre&gt;
	</description>
    </item>
    <item>
      <title>Patat (Presentations Atop The ANSI Terminal)</title>
      <link>https://tedneward.github.io/Research/presentation/console/patat/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/console/patat/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/jaspervdj/patat&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Turbo Vision</title>
      <link>https://tedneward.github.io/Research/presentation/console/turbovision/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/console/turbovision/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/magiblot/tvision&quot;&gt;tvision&lt;/a&gt;: A modern port of Turbo Vision 2.0, the classical framework for text-based user interfaces. Now cross-platform and with Unicode support.&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://github.com/tomer/tvision/&quot;&gt;TVision-themed CSS&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>CreateJS</title>
      <link>https://tedneward.github.io/Research/presentation/createjs/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/createjs/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://createjs.com/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/CreateJS&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Consists of:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://createjs.com/easeljs&quot;&gt;EaselJS&lt;/a&gt;: A JavaScript library that makes working with the HTML5 Canvas element easy.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://createjs.com/tweenjs&quot;&gt;TweenJS&lt;/a&gt;: A JavaScript library for tweening and animating HTML5 and JavaScript properties.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://createjs.com/soundjs&quot;&gt;SoundJS&lt;/a&gt;: A JavaScript library that lets you easily and efficiently work with audio on the web.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://createjs.com/preloadjs&quot;&gt;PreloadJS&lt;/a&gt;: A JavaScript library that lets you manage and co-ordinate the loading of assets and data.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Reading&lt;/h2&gt; 
&lt;p&gt;&lt;a href=&quot;https://www.luxanimals.com/blog/article/combining_easel_box2d&quot;&gt;&quot;Combining Easel.js and Box2d in Canvas&quot;&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>CSS snippets</title>
      <link>https://tedneward.github.io/Research/presentation/css/snippets/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/css/snippets/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://codepen.io/jenanemone/pen/MWQbPeR&quot;&gt;CSS for an &quot;index card&quot; effect&lt;/a&gt;:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-html&quot;&gt;&amp;lt;div class=&quot;card-title&quot;&amp;gt;
      Milkshake
    &amp;lt;/div&amp;gt;
  &amp;lt;div class=&quot;card&quot;&amp;gt;
    
    &amp;lt;span class=&quot;card-text&quot;&amp;gt;
      &amp;lt;ul&amp;gt;
        &amp;lt;li&amp;gt;1c 2% milk&amp;lt;/li&amp;gt;
        &amp;lt;li&amp;gt;1/8c cream&amp;lt;/li&amp;gt;
        &amp;lt;li&amp;gt;1c ice cream&amp;lt;/li&amp;gt;
      &amp;lt;/ul&amp;gt;
      &amp;lt;p&amp;gt;Blend well, top with whipped cream or crushed candy, and serve cold.&amp;lt;/p&amp;gt;
    &amp;lt;/span&amp;gt;
  &amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt; 
&lt;pre&gt;&lt;code class=&quot;language-css&quot;&gt;/* Styling specific to an index card */
.card {
  background-color: white;
  background: repeating-linear-gradient(rgb(240,250,250), rgb(240,250,250) 25px, #9198e5 26px, #9198e5 27px);
  height: 300px;
  width: 500px;
  padding: 0;
}
.card-title {
  background-image: linear-gradient(rgb(240,250,250), rgb(240,250,250) 42px, pink 43px, pink 44px, rgb(240,250,250) 46px);
  height: 46px;
  width: 500px;
  padding-left: 25px;
  padding-top: 3px;
  color: black;
  line-height: 46px;
  font-size: 30px;
  font-weight: bold;
}
.card-text {
  display: flex;
  flex-direction: column;
  justify-content: flex-start;
  font-size: 18px;
  line-height: 27px;
  padding-top: 4px;
}
p {
  padding-left: 25px;
}
&lt;/code&gt;&lt;/pre&gt; 
&lt;hr&gt; 
&lt;p&gt;&lt;a href=&quot;https://markodenic.com/css-tips/&quot;&gt;CSS Tips&lt;/a&gt;:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt; &lt;p&gt;Typing Effect:&lt;br&gt; HTML:&lt;/p&gt; &lt;pre&gt;&lt;code&gt;&amp;lt;div class=&quot;wrapper&quot;&amp;gt;
  &amp;lt;div class=&quot;typing-demo&quot;&amp;gt;
    This is a typing demo.
  &amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt; &lt;p&gt;CSS:&lt;/p&gt; &lt;pre&gt;&lt;code&gt;.wrapper {
  height: 100vh;
  /*This part is important for centering*/
  display: grid;
  place-items: center;
}

.typing-demo {
  width: 22ch;
  animation: typing 2s steps(22), blink .5s step-end infinite alternate;
  white-space: nowrap;
  overflow: hidden;
  border-right: 3px solid;
  font-family: monospace;
  font-size: 2em;
}

@keyframes typing {
  from {
    width: 0
  }
}

@keyframes blink {
  50% {
    border-color: transparent
  }
}
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Drop shadow: When you work with transparent images you can use &lt;code&gt;drop-shadow()&lt;/code&gt; filter function to create a shadow on the image’s content, instead of &lt;code&gt;box-shadow&lt;/code&gt; property which creates a rectangular shadow behind an element’s entire box: filter: &lt;code&gt;drop-shadow(2px 4px 8px #585858)&lt;/code&gt;&lt;br&gt; HTML&lt;/p&gt; &lt;pre&gt;&lt;code&gt;&amp;lt;div class=&quot;wrapper&quot;&amp;gt;
  &amp;lt;div class=&quot;mr-2&quot;&amp;gt;
    &amp;lt;div class=&quot;mb-1 text-center&quot;&amp;gt;
      box-shadow
    &amp;lt;/div&amp;gt;

    &amp;lt;img class=&quot;box-shadow&quot; src=&quot;https://markodenic.com/man_working.png&quot; alt=&quot;Image with box-shadow&quot;&amp;gt;
  &amp;lt;/div&amp;gt;

  &amp;lt;div&amp;gt;
    &amp;lt;div class=&quot;mb-1 text-center&quot;&amp;gt;
      drop-shadow
    &amp;lt;/div&amp;gt;

    &amp;lt;img class=&quot;drop-shadow&quot; src=&quot;https://markodenic.com/man_working.png&quot; alt=&quot;Image with drop-shadow&quot;&amp;gt;
  &amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt; &lt;p&gt;CSS:&lt;/p&gt; &lt;pre&gt;&lt;code&gt;.wrapper {
  height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
}

.mr-2 {
  margin-right: 2em;
}

.mb-1 {
  margin-bottom: 1em;
}

.text-center {
  text-align: center;
}

.box-shadow {
  box-shadow: 2px 4px 8px #585858;
}

.drop-shadow {
  filter: drop-shadow(2px 4px 8px #585858);
}
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Smooth scrolling:&lt;br&gt; HTML:&lt;/p&gt; &lt;pre&gt;&lt;code&gt;&amp;lt;nav&amp;gt;
  Scroll to: 
  &amp;lt;a href=&quot;#sectionA&quot; class=&quot;link bg-red&quot;&amp;gt;A&amp;lt;/a&amp;gt;

  &amp;lt;a href=&quot;#sectionB&quot; class=&quot;link bg-blue&quot;&amp;gt;B&amp;lt;/a&amp;gt;

  &amp;lt;a href=&quot;#sectionC&quot; class=&quot;link bg-green&quot;&amp;gt;C&amp;lt;/a&amp;gt;
&amp;lt;/nav&amp;gt;

&amp;lt;div class=&quot;wrapper&quot;&amp;gt;
  &amp;lt;div id=&quot;sectionA&quot; class=&quot;section bg-red&quot;&amp;gt;A&amp;lt;/div&amp;gt;

  &amp;lt;div id=&quot;sectionB&quot; class=&quot;section bg-blue&quot;&amp;gt;B&amp;lt;/div&amp;gt;

  &amp;lt;div id=&quot;sectionC&quot; class=&quot;section bg-green&quot;&amp;gt;C&amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt; &lt;p&gt;CSS:&lt;/p&gt; &lt;pre&gt;&lt;code&gt;html {
  scroll-behavior: smooth;
}

nav {
  position: fixed;
  left: calc(50vw - 115px);
  top: 0;
  width: 200px;
  text-align: center;
  padding: 15px;
  background: #fff;
  box-shadow: 0 2px 5px 1px rgba(0, 0, 0, 0.2);
}

nav .link {
  padding: 5px;
  color: white;
}

.section {
  height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #fff;
  font-size: 5em;
  text-shadow:
    0px 2px 0px #b2a98f,
    0px 4px 3px rgba(0,0,0,0.15),
    0px 8px 1px rgba(0,0,0,0.1);
}

.bg-red {
  background: #de5448;
}

.bg-blue {
  background: #4267b2;
}

.bg-green {
  background: #4CAF50;
}
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
 &lt;li&gt;Center: Easily center anything, horizontally and vertically, with 3 lines of CSS.&lt;br&gt; CSS: &lt;pre&gt;&lt;code&gt;.center {
  display: flex;
  align-items: center;
  justify-content: center;       
}           
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
 &lt;li&gt;Cursors (as in, mouse cursor):&lt;br&gt; HTML: &lt;pre&gt;&lt;code&gt;&amp;lt;div class=&quot;wrapper&quot;&amp;gt;
  &amp;lt;div class=&quot;tile&quot;&amp;gt;
    Default
  &amp;lt;/div&amp;gt;

  &amp;lt;div class=&quot;tile tile--image-cursor&quot;&amp;gt;
    Image Cursor
  &amp;lt;/div&amp;gt;

  &amp;lt;div class=&quot;tile tile--emoji-cursor&quot;&amp;gt;
    Emoji Cursor
  &amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt; &lt;p&gt;CSS:&lt;/p&gt; &lt;pre&gt;&lt;code&gt;.wrapper {
  display: flex;
  height: 100vh;
  align-items: center;
  justify-content: center;
  background: #4776e6;
  background: -webkit-linear-gradient(to right, #4776e6, #8e54e9);
  background: linear-gradient(to right, #4776e6, #8e54e9);
  padding: 0 10px;
}

.tile {
    width: 200px;
    height: 200px;display: flex;
    align-items: center;
    justify-content: center;
    background-color: #de5448;
    margin-right: 10px;color: #fff;
    font-size: 1.4em;
    text-align: center;
  }

.tile--image-cursor {
  background-color: #1da1f2;
  cursor: url(https://picsum.photos/20/20), auto;
}

.tile--emoji-cursor {
  background-color: #4267b2;
  cursor: url(&quot;data:image/svg+xml;utf8,&amp;lt;svg xmlns=&apos;http://www.w3.org/2000/svg&apos;  width=&apos;40&apos; height=&apos;48&apos; viewport=&apos;0 0 100 100&apos; style=&apos;fill:black;font-size:24px;&apos;&amp;gt;&amp;lt;text y=&apos;50%&apos;&amp;gt;🚀&amp;lt;/text&amp;gt;&amp;lt;/svg&amp;gt;&quot;), auto;
}
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
 &lt;li&gt;Truncate text&lt;/li&gt; 
 &lt;li&gt;Truncate the text to a specific number of lines&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;::selection&lt;/code&gt; CSS pseudo-element&lt;/li&gt; 
 &lt;li&gt;Anything resizable: Did you know that you can make any element resizable, just like &lt;code&gt;&amp;lt;textarea&amp;gt;&lt;/code&gt;?&lt;/li&gt; 
 &lt;li&gt;CSS modals: You can use the &lt;code&gt;:target&lt;/code&gt; pseudo-class to create modals with zero JavaScript.&lt;br&gt; HTML: &lt;pre&gt;&lt;code&gt;&amp;lt;div class=&quot;wrapper&quot;&amp;gt;
    &amp;lt;a href=&quot;#demo-modal&quot;&amp;gt;Open Demo Modal&amp;lt;/a&amp;gt;
&amp;lt;/div&amp;gt;

&amp;lt;div id=&quot;demo-modal&quot; class=&quot;modal&quot;&amp;gt;
    &amp;lt;div class=&quot;modal__content&quot;&amp;gt;
        &amp;lt;h1&amp;gt;CSS Only Modal&amp;lt;/h1&amp;gt;

        &amp;lt;p&amp;gt;
            You can use the :target pseudo-class to create a modals with Zero JavaScript. Enjoy!
        &amp;lt;/p&amp;gt;

        &amp;lt;div class=&quot;modal__footer&quot;&amp;gt;
            Made with &amp;lt;i class=&quot;fa fa-heart&quot;&amp;gt;&amp;lt;/i&amp;gt;, by &amp;lt;a href=&quot;https://twitter.com/denicmarko&quot; target=&quot;_blank&quot;&amp;gt;@denicmarko&amp;lt;/a&amp;gt;
        &amp;lt;/div&amp;gt;

        &amp;lt;a href=&quot;#&quot; class=&quot;modal__close&quot;&amp;gt;&amp;amp;times;&amp;lt;/a&amp;gt;
    &amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;    
&lt;/code&gt;&lt;/pre&gt; &lt;p&gt;CSS:&lt;/p&gt; &lt;pre&gt;&lt;code&gt;.wrapper {
  height: 100vh;
  /* This part is important for centering the content */
  display: flex;
  align-items: center;
  justify-content: center;
  /* End center */
  background: -webkit-linear-gradient(to right, #834d9b, #d04ed6);
  background: linear-gradient(to right, #834d9b, #d04ed6);
}

.wrapper a {
  display: inline-block;
  text-decoration: none;
  padding: 15px;
  background-color: #fff;
  border-radius: 3px;
  text-transform: uppercase;
  color: #585858;
  font-family: &apos;Roboto&apos;, sans-serif;
}

.modal {
  visibility: hidden;
  opacity: 0;
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(77, 77, 77, .7);
  transition: all .4s;
}

.modal:target {
  visibility: visible;
  opacity: 1;
}

.modal__content {
  border-radius: 4px;
  position: relative;
  width: 500px;
  max-width: 90%;
  background: #fff;
  padding: 1em 2em;
}

.modal__footer {
  text-align: right;
  a {
    color: #585858;
  }
  i {
    color: #d02d2c;
  }
}
.modal__close {
  position: absolute;
  top: 10px;
  right: 10px;
  color: #585858;
  text-decoration: none;
}    
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;calc()&lt;/code&gt;: The &lt;code&gt;calc()&lt;/code&gt; CSS function lets you perform calculations when specifying CSS property values.&lt;/li&gt; 
 &lt;li&gt;Style empty elements&lt;/li&gt; 
 &lt;li&gt;Create custom scrollbar&lt;/li&gt; 
 &lt;li&gt;position sticky&lt;/li&gt; 
 &lt;li&gt;CSS Scroll Snap&lt;/li&gt; 
 &lt;li&gt;Dynamic Tooltips&lt;/li&gt; 
 &lt;li&gt;caret-color&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;::in-range&lt;/code&gt; and &lt;code&gt;::out-of-range&lt;/code&gt; pseudo-classes&lt;/li&gt; 
 &lt;li&gt;Fancy text&lt;/li&gt; 
 &lt;li&gt;Flex gap&lt;/li&gt; 
 &lt;li&gt;&lt;code&gt;grayscale()&lt;/code&gt; function: Use the &lt;code&gt;grayscale()&lt;/code&gt; filter function to convert the input image to grayscale.&lt;/li&gt; 
 &lt;li&gt;Rounded, gradiant borders:&lt;br&gt; HTML: &lt;pre&gt;&lt;code&gt;&amp;lt;div class=&quot;box gradient-border&quot;&amp;gt;
  This is a div with rounded gradient border.
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt; &lt;p&gt;CSS:&lt;/p&gt; &lt;pre&gt;&lt;code&gt;.gradient-border {
  border: solid 5px transparent;
  border-radius: 10px;
  background-image: linear-gradient(white, white), 
    linear-gradient(315deg,#833ab4,#fd1d1d 50%,#fcb045);
  background-origin: border-box;
  background-clip: content-box, border-box;
}

/* Demo code, unrelated to the feature. */
.box {
  width: 350px;
  height: 100px;
  display: flex;
  align-items: center;
  justify-content: center;
  margin: 100px auto;
}
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>DerbyJS</title>
      <link>https://tedneward.github.io/Research/presentation/derbyjs/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/derbyjs/index.html</guid>
      	<description>
	&lt;p&gt;&quot;Derby includes a powerful data synchronization engine called Racer that automatically syncs data among browsers, servers, and a database. Models subscribe to changes on specific objects, enabling granular control of data propagation without defining channels. Racer supports offline usage and conflict resolution out of the box, which greatly simplifies writing multi-user applications.&lt;/p&gt; 
&lt;p&gt;&quot;Derby applications load immediately and can be indexed by search engines, because the same templates render on both server and client. In addition, templates define bindings, which instantly update the view when the model changes and vice versa. Derby makes it simple to write applications that load as fast as a search engine, are as interactive as a document editor, and work offline.&quot;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://derbyjs.com/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/derbyjs&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>DivKit</title>
      <link>https://tedneward.github.io/Research/presentation/divkit/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/divkit/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://divkit.tech/en/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/divkit/divkit&quot;&gt;Source&lt;/a&gt; | &lt;a href=&quot;https://divkit.tech/doc&quot;&gt;Docs&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;DivKit&lt;/strong&gt; 🐋 is an open source Server-Driven UI (SDUI) framework. It allows you to roll out server-sourced updates to different app versions. Also, it can be used for fast UI prototyping, allowing you to write a layout once and then ship it to iOS, Android, and Web platforms. DivKit is an excellent choice to start using server-driven UI in your project because it can be easily integrated as a simple view in any part of your app. At the starting point, you don’t need a server integration. You can include all JSON on the client-side to try it in a real-world application.&lt;/p&gt; 
&lt;p&gt;Also, we’ve made a &lt;a href=&quot;https://divkit.tech/playground&quot;&gt;sandbox&lt;/a&gt; for you to experiment with. You can try different samples in the web editor and see the results on the web or in the Android &lt;a href=&quot;https://play.google.com/store/apps/details?id=com.yandex.divkit.demo&quot;&gt;demo app&lt;/a&gt;, both of which are available on Google Play. We’ll publish the iOS demo app shortly. The UI in the demo can be updated live: the sandbox connects to the demo app via web sockets.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Drawflow</title>
      <link>https://tedneward.github.io/Research/presentation/drawflow/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/drawflow/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://jerosoler.github.io/Drawflow/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/jerosoler/Drawflow&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Elmish</title>
      <link>https://tedneward.github.io/Research/presentation/elmish/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/elmish/index.html</guid>
      	<description>
	&lt;p&gt;Bringing &lt;a href=&quot;../languages/elm&quot;&gt;Elm&lt;/a&gt;-like constructs to the &lt;a href=&quot;../languages/fable&quot;&gt;Fable&lt;/a&gt; world.&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://elmish.github.io/&quot;&gt;Website&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://www.compositional-it.com/news-blog/ui-programming-with-elmish-in-f/&quot;&gt;Blog post&lt;/a&gt; describing it.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Expo</title>
      <link>https://tedneward.github.io/Research/presentation/expo/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/expo/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://expo.dev/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/expo/expo&quot;&gt;Source&lt;/a&gt; | &lt;a href=&quot;https://docs.expo.dev/&quot;&gt;Docs&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>FluentUI</title>
      <link>https://tedneward.github.io/Research/presentation/fluentui/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/fluentui/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://storybooks.fluentui.dev/react/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/microsoft/fluentui&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Foundation</title>
      <link>https://tedneward.github.io/Research/presentation/foundation/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/foundation/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://get.foundation/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/foundation/&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Glance</title>
      <link>https://tedneward.github.io/Research/presentation/glance/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/glance/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/glanceapp/glance&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;h2&gt;Features&lt;/h2&gt; 
&lt;h3&gt;Various widgets&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;RSS feeds&lt;/li&gt; 
 &lt;li&gt;Subreddit posts&lt;/li&gt; 
 &lt;li&gt;Hacker News posts&lt;/li&gt; 
 &lt;li&gt;Weather forecasts&lt;/li&gt; 
 &lt;li&gt;YouTube channel uploads&lt;/li&gt; 
 &lt;li&gt;Twitch channels&lt;/li&gt; 
 &lt;li&gt;Market prices&lt;/li&gt; 
 &lt;li&gt;Docker containers status&lt;/li&gt; 
 &lt;li&gt;Server stats&lt;/li&gt; 
 &lt;li&gt;Custom widgets&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;and many more...&lt;/p&gt; 
&lt;h3&gt;Fast and lightweight&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;Low memory usage&lt;/li&gt; 
 &lt;li&gt;Few dependencies&lt;/li&gt; 
 &lt;li&gt;Minimal vanilla JS&lt;/li&gt; 
 &lt;li&gt;Single &amp;lt;20mb binary available for multiple OSs &amp;amp; architectures and just as small Docker container&lt;/li&gt; 
 &lt;li&gt;Uncached pages usually load within ~1s (depending on internet speed and number of widgets)&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Tons of customizability&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;Different layouts&lt;/li&gt; 
 &lt;li&gt;As many pages/tabs as you need&lt;/li&gt; 
 &lt;li&gt;Numerous configuration options for each widget&lt;/li&gt; 
 &lt;li&gt;Multiple styles for some widgets&lt;/li&gt; 
 &lt;li&gt;Custom CSS&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Optimized for mobile devices&lt;/h3&gt; 
&lt;p&gt;Because you&apos;ll want to take it with you on the go.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Graphviz</title>
      <link>https://tedneward.github.io/Research/presentation/graphviz/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/graphviz/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://graphviz.org/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://gitlab.com/graphviz/graphviz&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Hibiki</title>
      <link>https://tedneward.github.io/Research/presentation/hibiki/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/hibiki/index.html</guid>
      	<description>
	&lt;h2&gt;&lt;a href=&quot;https://hibikihtml.com/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/dashborg/hibiki&quot;&gt;GitHub&lt;/a&gt; | &lt;a href=&quot;https://playground.hibikihtml.com/tutorial/&quot;&gt;Tutorial&lt;/a&gt; | &lt;a href=&quot;https://playground.hibikihtml.com/&quot;&gt;Playground&lt;/a&gt; | &lt;a href=&quot;https://docs.hibikihtml.com/&quot;&gt;Docs&lt;/a&gt;&lt;/h2&gt; 
&lt;h2&gt;Getting Started&lt;/h2&gt; 
&lt;p&gt;Getting started is easy. There is no JavaScript stack to set up, no boilerplate/scaffolding, and&lt;br&gt; no build tools to download and run.&lt;br&gt; Just add one script tag to the top of your page or template:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;&amp;lt;script src=&quot;https://cdn.hibikihtml.com/hibiki/v0.3.2/hibiki-prod.min.js&quot;&amp;gt;&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Wrap any portion of your content with a &amp;lt;template hibiki&amp;gt; tag and you have your first&lt;br&gt; Hibiki HTML app. All plain HTML content is rendered as is, and because Hibiki HTML uses the browser&apos;s HTML parser,&lt;br&gt; it follows the same rules as standard browser HTML.&lt;br&gt; Note that all these code examples can be viewed and edited in the&lt;br&gt; &lt;a href=&quot;https://playground.hibikihtml.com&quot;&gt;Hibiki HTML Playground&lt;/a&gt;.&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;&amp;lt;template hibiki&amp;gt;
  &amp;lt;h1 class=&quot;title&quot;&amp;gt;&amp;amp;#x1f338; Hibiki HTML&amp;lt;/h1&amp;gt;
  &amp;lt;p&amp;gt;Hibiki HTML &amp;lt;i&amp;gt;is&amp;lt;/i&amp;gt; HTML&amp;lt;/p&amp;gt;
&amp;lt;/template&amp;gt;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;(Playground Link - &lt;a href=&quot;https://playground.hibikihtml.com/?codeid=readme-gs&quot;&gt;https://playground.hibikihtml.com/?codeid=readme-gs&lt;/a&gt;)&lt;/p&gt; 
&lt;h2&gt;Data / Rendering Dynamic Content&lt;/h2&gt; 
&lt;p&gt;Hibiki HTML applications have a built-in frontend data model. You can initialize it with&lt;br&gt; any JSON object using the &lt;code&gt;&amp;lt;hibiki-data&amp;gt;&lt;/code&gt; tag. To render text use&lt;br&gt; the &lt;code&gt;&amp;lt;h-text&amp;gt;&lt;/code&gt; tag or inline &lt;code&gt;{{ ... }}&lt;/code&gt; syntax. Attributes and style properties&lt;br&gt; are evaluated dynamically if they start with a &lt;code&gt;*&lt;/code&gt;.&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;&amp;lt;template hibiki&amp;gt;
  &amp;lt;hibiki-data&amp;gt;
    {&quot;color&quot;: &quot;blue&quot;, &quot;name&quot;: &quot;Mike&quot;}
  &amp;lt;/hibiki-data&amp;gt;
  &amp;lt;p&amp;gt;
    {{ $.name }}&apos;s favorite color is 
    &amp;lt;span style=&quot;font-weight: bold; color: *$.color&quot;&amp;gt;{{ $.color }}&amp;lt;/span&amp;gt;
  &amp;lt;/p&amp;gt;
&amp;lt;/template&amp;gt;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;(Playground Link - &lt;a href=&quot;https://playground.hibikihtml.com/?codeid=readme-data-1&quot;&gt;https://playground.hibikihtml.com/?codeid=readme-data-1&lt;/a&gt;)&lt;br&gt; Hibiki HTML supports a full expression language, including all of the standard conditional and arithmetic&lt;br&gt; operators. Additional classes can be turned on/off using the shorthand&lt;br&gt; attribute syntax &lt;code&gt;class.[class-name]=&quot;true/false expression&quot;&lt;/code&gt;.&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;&amp;lt;template hibiki&amp;gt;
  &amp;lt;hibiki-data&amp;gt;
    {&quot;numlights&quot;: 4, &quot;selected&quot;: true, &quot;index&quot;: 5, &quot;isprimary&quot;: true}
  &amp;lt;/hibiki-data&amp;gt;
  &amp;lt;div class=&quot;box&quot; style=&quot;font-weight: *($.selected ? &apos;bold&apos; : &apos;normal&apos;)&quot;&amp;gt;
    Bold Text (if selected)
  &amp;lt;/div&amp;gt;
  &amp;lt;div class=&quot;box&quot;&amp;gt;Index: &amp;lt;h-text bind=&quot;$.index + 1&quot;&amp;gt;&amp;lt;/h-text&amp;gt;&amp;lt;/div&amp;gt;
  &amp;lt;div class=&quot;box&quot;&amp;gt;
    There are {{$.numlights}} light{{$.numlights &amp;gt; 1 ? &apos;s&apos; : &apos;&apos;}}
  &amp;lt;/div&amp;gt;
  &amp;lt;div class=&quot;box&quot;&amp;gt;
    &amp;lt;button class=&quot;button&quot; class.is-primary=&quot;*$.isprimary&quot;&amp;gt;Primary Button&amp;lt;/button&amp;gt;
  &amp;lt;/div&amp;gt;
&amp;lt;/template&amp;gt;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;(Playground Link - &lt;a href=&quot;https://playground.hibikihtml.com/?codeid=readme-data-2&quot;&gt;https://playground.hibikihtml.com/?codeid=readme-data-2&lt;/a&gt;)&lt;br&gt; You can conditionally include elements using the &lt;code&gt;if&lt;/code&gt; attribute. Looping&lt;br&gt; is handled by the &lt;code&gt;foreach&lt;/code&gt; attribute. You can loop over arrays or&lt;br&gt; objects. The foreach attribute uses a special syntax of &lt;code&gt;@item in $.array&lt;/code&gt;,&lt;br&gt; where every iteration &lt;code&gt;@item&lt;/code&gt; will be assigned to an element of the array or object.&lt;br&gt; If you provide a second variable it will capture the array index or element key:&lt;br&gt; &lt;code&gt;(@item, @key) in $.object&lt;/code&gt; or &lt;code&gt;(@item, @idx) in $.array&lt;/code&gt;.&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;&amp;lt;template hibiki&amp;gt;
  &amp;lt;hibiki-data&amp;gt;
    {&quot;fruits&quot;: [{&quot;name&quot;: &quot;apple&quot;, &quot;emoji&quot;: &quot;&amp;amp;#127822;&quot;},
                {&quot;name&quot;: &quot;banana&quot;, &quot;emoji&quot;: &quot;&amp;amp;#127820;&quot;}, 
                {&quot;name&quot;: &quot;blueberry&quot;, &quot;emoji&quot;: &quot;&amp;amp;#129744;&quot;}], 
     &quot;selected&quot;: &quot;banana&quot;}
  &amp;lt;/hibiki-data&amp;gt;
  &amp;lt;div class=&quot;content box&quot;&amp;gt;
    &amp;lt;ul&amp;gt;
      &amp;lt;li foreach=&quot;@fruit in $.fruits&quot;&amp;gt;
        {{ @fruit.name }} {{ @fruit.emoji }}
        &amp;lt;span if=&quot;@fruit.name == $.selected&quot;&amp;gt;(selected)&amp;lt;/span&amp;gt;
      &amp;lt;/li&amp;gt;
    &amp;lt;/ul&amp;gt;
  &amp;lt;/div&amp;gt;
&amp;lt;/template&amp;gt;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;(Playground Link - &lt;a href=&quot;https://playground.hibikihtml.com/?codeid=readme-data-3&quot;&gt;https://playground.hibikihtml.com/?codeid=readme-data-3&lt;/a&gt;)&lt;/p&gt; 
&lt;h2&gt;Handlers&lt;/h2&gt; 
&lt;p&gt;To update data (and dynamically change content), Hibiki HTML supports &lt;em&gt;handlers&lt;/em&gt;. Basic handlers respond to&lt;br&gt; events like &lt;em&gt;click&lt;/em&gt;, &lt;em&gt;mount&lt;/em&gt;, &lt;em&gt;submit&lt;/em&gt;, &lt;em&gt;change&lt;/em&gt;, etc.&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;&amp;lt;template hibiki&amp;gt;
  &amp;lt;hibiki-data&amp;gt;{&quot;color&quot;: &quot;blue&quot;}&amp;lt;/hibiki-data&amp;gt;
  &amp;lt;div class=&quot;box&quot; style=&quot;background-color: *$.color; color: white&quot;&amp;gt;
    The color is {{$.color}}
  &amp;lt;/div&amp;gt;
  &amp;lt;button class=&quot;button&quot; click.handler=&quot;$.color = &apos;green&apos;&quot;&amp;gt;Change Color&amp;lt;/button&amp;gt;
&amp;lt;/template&amp;gt;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;(Playground Link - &lt;a href=&quot;https://playground.hibikihtml.com/?codeid=readme-handlers-1&quot;&gt;https://playground.hibikihtml.com/?codeid=readme-handlers-1&lt;/a&gt;)&lt;br&gt; You can make remote AJAX calls for JSON data using a remote handler. In this example&lt;br&gt; the call to &lt;a href=&quot;https://testapi.hibikihtml.com/api/get-color-1&quot;&gt;https://testapi.hibikihtml.com/api/get-color-1&lt;/a&gt; will return the JSON&lt;br&gt; response &lt;code&gt;{&quot;color&quot;: &quot;purple&quot;}&lt;/code&gt;. We assign it to a &lt;em&gt;context variable&lt;/em&gt; &lt;code&gt;@resp&lt;/code&gt; and&lt;br&gt; then assign &lt;code&gt;$.color = @resp.color&lt;/code&gt;.&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;&amp;lt;template hibiki&amp;gt;
  &amp;lt;hibiki-data&amp;gt;{&quot;color&quot;: &quot;blue&quot;}&amp;lt;/hibiki-data&amp;gt;
  &amp;lt;div class=&quot;box&quot; style=&quot;background-color: *$.color; color: white&quot;&amp;gt;
    The color is {{$.color}}
  &amp;lt;/div&amp;gt;
  &amp;lt;button class=&quot;button&quot; click.handler=&quot;$.color = &apos;green&apos;&quot;&amp;gt;Change Color&amp;lt;/button&amp;gt;
  &amp;lt;button class=&quot;button&quot;
    click.handler=&quot;@resp = GET https://testapi.hibikihtml.com/api/get-color-1; $.color = @resp.color;&quot;&amp;gt;
    GET /api/get-color-1
  &amp;lt;/button&amp;gt;
&amp;lt;/template&amp;gt;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;(Playground Link - &lt;a href=&quot;https://playground.hibikihtml.com/?codeid=readme-handlers-2&quot;&gt;https://playground.hibikihtml.com/?codeid=readme-handlers-2&lt;/a&gt;)&lt;br&gt; You can make GET, POST, PUT, PATCH, or DELETE requests by changing the verb in front of the URL. You can&lt;br&gt; pass query arguments (or JSON data bodies) by passing arguments to your handler by using &lt;code&gt;(arg1=val1, arg2=val2...)&lt;/code&gt; (complex arguments will be JSON encoded), and you can define local handlers using the &lt;code&gt;define-handler&lt;/code&gt; tag for convenience and reuse.&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;&amp;lt;template hibiki&amp;gt;
  &amp;lt;hibiki-data&amp;gt;{&quot;color&quot;: &quot;blue&quot;}&amp;lt;/hibiki-data&amp;gt;
  &amp;lt;define-handler name=&quot;//@local/get-color&quot;&amp;gt;
    @resp = GET https://testapi.hibikihtml.com/api/get-color-1(name=&quot;Michelle&quot;);
    $.color = @resp.color;
  &amp;lt;/define-handler&amp;gt;
  &amp;lt;div class=&quot;box&quot; style=&quot;background-color: *$.color; color: white&quot;&amp;gt;
    The color is {{$.color}}
  &amp;lt;/div&amp;gt;
  &amp;lt;button class=&quot;button&quot; click.handler=&quot;$.color = &apos;green&apos;&quot;&amp;gt;Change Color&amp;lt;/button&amp;gt;
  &amp;lt;button class=&quot;button&quot; click.handler=&quot;//@local/get-color&quot;&amp;gt;
    Get Michelle&apos;s Color
  &amp;lt;/button&amp;gt;
&amp;lt;/template&amp;gt;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;(Playground Link - &lt;a href=&quot;https://playground.hibikihtml.com/?codeid=readme-handlers-3&quot;&gt;https://playground.hibikihtml.com/?codeid=readme-handlers-3&lt;/a&gt;)&lt;br&gt; Connecting to an existing API? Don&apos;t worry, Hibiki HTML handlers support advanced options&lt;br&gt; like CORS, CSRF, parameter encodings, BLOB results, and multipart file uploads.&lt;/p&gt; 
&lt;h2&gt;Hibiki Actions&lt;/h2&gt; 
&lt;p&gt;The magic of Hibiki HTML is that every handler is really just a series of actions. &lt;em&gt;Hibiki Actions&lt;/em&gt;&lt;br&gt; are primitives like &lt;em&gt;setdata&lt;/em&gt;, &lt;em&gt;if&lt;/em&gt;, &lt;em&gt;callhandler&lt;/em&gt;, &lt;em&gt;fireevent&lt;/em&gt;, &lt;em&gt;invalidate&lt;/em&gt;, &lt;em&gt;html&lt;/em&gt;, etc. Every action&lt;br&gt; that can you can write in a handler, also has a JSON representation.&lt;br&gt; This means we can write a &lt;em&gt;backend&lt;/em&gt; handler that returns a JSON response that scripts&lt;br&gt; and updates the frontend! Here&apos;s an example JSON response that is equivalent to running&lt;br&gt; &lt;code&gt;$.color = &apos;DeepSkyBlue&apos;&lt;/code&gt; on the frontend:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;{&quot;hibikiactions&quot;: [
    {&quot;actiontype&quot;: &quot;setdata&quot;, &quot;setpath&quot;: &quot;$.color&quot;, &quot;data&quot;: &quot;DeepSkyBlue&quot;}
]}
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;I&apos;ve set up &lt;a href=&quot;https://testapi.hibikihtml.com/api/set-color-action&quot;&gt;https://testapi.hibikihtml.com/api/set-color-action&lt;/a&gt; to return just that. Now&lt;br&gt; if we have our click handler call that URL, we&apos;ll see the color change automatically.&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;&amp;lt;template hibiki&amp;gt;
  &amp;lt;hibiki-data&amp;gt;{&quot;color&quot;: &quot;red&quot;}&amp;lt;/hibiki-data&amp;gt;
  &amp;lt;div class=&quot;box&quot; style=&quot;background-color: *$.color; color: white&quot;&amp;gt;
    The color is {{$.color}}
  &amp;lt;/div&amp;gt;
  &amp;lt;button class=&quot;button&quot; click.handler=&quot;$.color = &apos;green&apos;&quot;&amp;gt;Change Color&amp;lt;/button&amp;gt;
  &amp;lt;button class=&quot;button&quot; click.handler=&quot;GET https://testapi.hibikihtml.com/api/set-color-action;&quot;&amp;gt;
    Backend Set Color Action
  &amp;lt;/button&amp;gt;
&amp;lt;/template&amp;gt;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;(Playground Link - &lt;a href=&quot;https://playground.hibikihtml.com/?codeid=readme-actions-1&quot;&gt;https://playground.hibikihtml.com/?codeid=readme-actions-1&lt;/a&gt;)&lt;br&gt; Backend handlers are &lt;em&gt;very&lt;/em&gt; powerful. You can set return values, return data and BLOBs (like images) in&lt;br&gt; one request, mix frontend and backend data with expressions, conditionally execute actions, and more.&lt;br&gt; You can also use backend handlers to create multi-page Hibiki HTML applications by returning a&lt;br&gt; new HTML template to be rendered.&lt;/p&gt; 
&lt;h2&gt;Components and Libraries&lt;/h2&gt; 
&lt;p&gt;Hibiki HTML makes it easy to use, share, and bundle components for easy reuse. The ecosystem is just getting&lt;br&gt; started, but you can write native Hibiki HTML components, link to 3rd party JavaScript (D3, CodeMirror, etc.),&lt;br&gt; and import ReactJS components.&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;&amp;lt;template hibiki&amp;gt;
  &amp;lt;define-component name=&quot;colorbox&quot;&amp;gt;
    &amp;lt;div class=&quot;box&quot; style=&quot;background-color: *$args.color; color: white&quot;&amp;gt;
      The color is {{$args.color}}
    &amp;lt;/div&amp;gt;
  &amp;lt;/define-component&amp;gt;
  
  &amp;lt;local-colorbox color=&quot;green&quot;&amp;gt;&amp;lt;/local-colorbox&amp;gt;
  &amp;lt;local-colorbox color=&quot;blue&quot;&amp;gt;&amp;lt;/local-colorbox&amp;gt;
  &amp;lt;local-colorbox color=&quot;purple&quot;&amp;gt;&amp;lt;/local-colorbox&amp;gt;
&amp;lt;/template&amp;gt;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;(Playground Link - &lt;a href=&quot;https://playground.hibikihtml.com/?codeid=readme-comps-1&quot;&gt;https://playground.hibikihtml.com/?codeid=readme-comps-1&lt;/a&gt;)&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>HTMX</title>
      <link>https://tedneward.github.io/Research/presentation/htmlx/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/htmlx/index.html</guid>
      	<description>
	&lt;p&gt;htmx allows you to access AJAX, CSS Transitions, WebSockets and Server Sent Events directly in HTML, using attributes, so you can build modern user interfaces with the simplicity and power of hypertext.&lt;/p&gt; 
&lt;p&gt;htmx is the successor to &lt;a href=&quot;http://intercoolerjs.org/&quot;&gt;intercooler.js&lt;/a&gt;.&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://htmx.org/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/bigskysoftware/htmx&quot;&gt;Source&lt;/a&gt; | &lt;a href=&quot;https://htmx.org/essays/&quot;&gt;Essays&lt;/a&gt;&lt;/p&gt; 
&lt;h3&gt;AJAX&lt;/h3&gt; 
&lt;p&gt;The core of htmx is a set of attributes that allow you to issue AJAX requests directly from HTML:&lt;/p&gt; 
&lt;table&gt; 
 &lt;thead&gt; 
  &lt;tr&gt;
   &lt;th&gt;Attribute &lt;/th&gt;
   &lt;th&gt; Description&lt;/th&gt;
  &lt;/tr&gt; 
 &lt;/thead&gt; 
 &lt;tbody&gt; 
  &lt;tr&gt;
   &lt;td&gt;hx-get &lt;/td&gt;
   &lt;td&gt; Issues a GET request to the given URL&lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt;hx-post &lt;/td&gt;
   &lt;td&gt; Issues a POST request to the given URL&lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt;hx-put &lt;/td&gt;
   &lt;td&gt; Issues a PUT request to the given URL&lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt;hx-patch &lt;/td&gt;
   &lt;td&gt; Issues a PATCH request to the given URL&lt;/td&gt;
  &lt;/tr&gt; 
  &lt;tr&gt;
   &lt;td&gt;hx-delete &lt;/td&gt;
   &lt;td&gt; Issues a DELETE request to the given URL&lt;/td&gt;
  &lt;/tr&gt; 
 &lt;/tbody&gt; 
&lt;/table&gt; 
&lt;p&gt;Each of these attributes takes a URL to issue an AJAX request to. The element will issue a request of the specified type to the given URL when the element is triggered:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-html&quot;&gt;  &amp;lt;div hx-put=&quot;/messages&quot;&amp;gt;
    Put To Messages
  &amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;This tells the browser:&lt;/p&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;When a user clicks on this div, issue a PUT request to the URL /messages and load the response into the div&lt;/p&gt; 
&lt;/blockquote&gt;
	</description>
    </item>
    <item>
      <title>Apache Isis</title>
      <link>https://tedneward.github.io/Research/presentation/isis/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/isis/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;http://isis.apache.org/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/apache/isis.git&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;hr&gt; 
&lt;p&gt;Generally the preferred way to get started is with a starter template&lt;/p&gt; 
&lt;p&gt;&quot;helloworld&quot; starter app instructions:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;curl https://codeload.github.com/apache/isis-app-helloworld/zip/2.0.0-M3 | jar xv
cd isis-app-helloworld-2.0.0-M3

mvn clean install
mvn spring-boot:run
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;&quot;simpleapp&quot; more structured start app instructions:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;curl https://codeload.github.com/apache/isis-app-simpleapp/zip/2.0.0-M3 | jar xv
cd isis-app-simpleapp-2.0.0-M3

mvn clean install
mvn -pl webapp spring-boot:run
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;An example/demo app is available via Docker:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;docker pull apacheisis/demo-springboot:latest
docker run \
        --name demo \
        --detach \
        -p8080:8080 \
        apacheisis/demo-springboot:latest
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;... and then accessible at &lt;a href=&quot;http://localhost:8080/wicket/&quot;&gt;http://localhost:8080/wicket/&lt;/a&gt; ; login with &quot;sven&quot;/&quot;pass&quot;.&lt;/p&gt; 
&lt;hr&gt; 
&lt;p&gt;See also: &lt;a href=&quot;/distribution/restfulobjects.html&quot;&gt;Restful Objects&lt;/a&gt;&lt;/p&gt; 
&lt;hr&gt; 
&lt;h2&gt;Documentation&lt;/h2&gt; 
&lt;p&gt;&lt;a href=&quot;http://isis.apache.org/setupguide/2.0.0-M3/about.html&quot;&gt;Setup Guide&lt;/a&gt; &lt;a href=&quot;http://isis.apache.org/userguide/2.0.0-M3/about.html&quot;&gt;User Guide&lt;/a&gt; | &lt;a href=&quot;http://isis.apache.org/refguide/2.0.0-M3/about.html&quot;&gt;Reference Guide&lt;/a&gt; | &lt;a href=&quot;http://isis.apache.org/testing/2.0.0-M3/about.html&quot;&gt;Testing&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>json-render</title>
      <link>https://tedneward.github.io/Research/presentation/json-render/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/json-render/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://json-render.dev/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/vercel-labs/json-render&quot;&gt;Source&lt;/a&gt; | &lt;a href=&quot;https://json-render.dev/docs&quot;&gt;Docs&lt;/a&gt;&lt;/p&gt; 
&lt;h2&gt;Reading&lt;/h2&gt; 
&lt;h3&gt;Articles&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://thenewstack.io/vercels-json-render-a-step-toward-generative-ui/&quot;&gt;https://thenewstack.io/vercels-json-render-a-step-toward-generative-ui/&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Jexer</title>
      <link>https://tedneward.github.io/Research/presentation/console/jexer/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/console/jexer/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://jexer.sourceforge.io/index.html&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://gitlab.com/AutumnMeowMeow/jexer&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Maven:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;    &amp;lt;dependency&amp;gt;
      &amp;lt;groupId&amp;gt;com.gitlab.klamonte&amp;lt;/groupId&amp;gt;
      &amp;lt;artifactId&amp;gt;jexer&amp;lt;/artifactId&amp;gt;
      &amp;lt;version&amp;gt;1.6.0&amp;lt;/version&amp;gt;
    &amp;lt;/dependency&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
	</description>
    </item>
    <item>
      <title>Spectre Console</title>
      <link>https://tedneward.github.io/Research/presentation/console/spectre-console/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/console/spectre-console/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/spectreconsole&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Almost anything a console can do, Spectre.Console can provide. Wow.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>vtmc (Video Terminal Master of Ceremonies)</title>
      <link>https://tedneward.github.io/Research/presentation/console/vtmc/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/console/vtmc/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/jclulow/vtmc&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Bootstrap</title>
      <link>https://tedneward.github.io/Research/presentation/css/bootstrap/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/css/bootstrap/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;http://www.getbootstrap.com/&quot;&gt;Website&lt;/a&gt;&lt;/p&gt; 
&lt;h2&gt;Related resources&lt;/h2&gt; 
&lt;p&gt;&lt;a href=&quot;https://bootsnipp.com/#google_vignette&quot;&gt;Bootsnipp&lt;/a&gt;: Design elements, playground, and code snippets for Bootstrap&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://bootswatch.com/&quot;&gt;Bootswatch&lt;/a&gt;: Free themes&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://bootswatchr.com/&quot;&gt;BootsWatchr&lt;/a&gt;: Getting to know Bootstrap Grid System&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://shapebootstrap.net/&quot;&gt;ShapeBootstrap&lt;/a&gt;: Your favorite web design school&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://startbootstrap.com/#google_vignette&quot;&gt;StartBootstrap&lt;/a&gt;: Themes, templates, UI tools&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://stylebootstrap.info/#&quot;&gt;StyleBootstrap&lt;/a&gt;: Themes, templates, styles, generator, customize&lt;/p&gt; 
&lt;h2&gt;Articles&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.smashingmagazine.com/2013/03/customizing-bootstrap/&quot;&gt;How to Customize Bootstrap&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.queness.com/post/13029/extend-twitter-bootstrap-javascript-plugins&quot;&gt;Extend Boostrap JS plugins&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.queness.com/post/11632/18-useful-twitter-boostrap-goodies-you-should-know&quot;&gt;18 Useful Bootstrap Goodies You Should Know&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Books&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.syncfusion.com/resources/techportal/details/ebooks/twitterbootstrap3&quot;&gt;Twitter Bootstrap 3 Succinctly&lt;/a&gt; - Peter Shaw&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.syncfusion.com/ebooks/twitterbootstrap4-succinctly&quot;&gt;Twitter Bootstrap 4 Succinctly&lt;/a&gt; - Peter Shaw&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.syncfusion.com/resources/techportal/details/ebooks/twitterbootstrap&quot;&gt;Twitter Bootstrap Succinctly&lt;/a&gt; - Peter Shaw&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>CSS Specifications</title>
      <link>https://tedneward.github.io/Research/presentation/css/specs/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/css/specs/index.html</guid>
      	<description>
	&lt;h2&gt;Specs&lt;/h2&gt; 
&lt;p&gt;&lt;a href=&quot;https://www.w3.org/TR/CSS/&quot;&gt;CSS Snapshot&lt;/a&gt; (list of links to all current specs) | &lt;a href=&quot;https://www.w3.org/TR/CSS/#terms&quot;&gt;Index to all terms/Glossary&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;As of 2021, Cascading Style Sheets (CSS) is defined by the following specifications.&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://www.w3.org/TR/CSS2/&quot;&gt;CSS Level 2&lt;/a&gt;, latest revision (including errata) &lt;strong&gt;[CSS2]&lt;/strong&gt;: This defines the core of CSS, parts of which are overridden by later specifications. We recommend in particular reading Chapter 2, which introduces some of the basic concepts of CSS and its design principles.&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://www.w3.org/TR/css-syntax-3/&quot;&gt;CSS Syntax Level 3&lt;/a&gt; &lt;strong&gt;[CSS-SYNTAX-3]&lt;/strong&gt;: Replaces CSS2§4.1, CSS2§4.2, CSS2§4.4, and CSS2§G, redefining how CSS is parsed.&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://www.w3.org/TR/css-style-attr/&quot;&gt;CSS Style Attributes&lt;/a&gt; &lt;strong&gt;[CSS-STYLE-ATTR]&lt;/strong&gt;: Defines how CSS declarations can be embedded in markup attributes.&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://www.w3.org/TR/css3-mediaqueries/&quot;&gt;Media Queries Level 3&lt;/a&gt; &lt;strong&gt;[CSS3-MEDIAQUERIES]&lt;/strong&gt;: Replaces CSS2§7.3 and expands on the syntax for media-specific styles.&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://www.w3.org/TR/css-conditional-3/&quot;&gt;CSS Conditional Rules Level 3&lt;/a&gt; &lt;strong&gt;[CSS-CONDITIONAL-3]&lt;/strong&gt;: Extends and supersedes CSS2§7.2, updating the definition of @media rules to allow nesting and introducing the @supports rule for feature-support queries.&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://www.w3.org/TR/selectors-3/&quot;&gt;Selectors Level 3&lt;/a&gt; &lt;strong&gt;[SELECTORS-3]&lt;/strong&gt;: Replaces CSS2§5 and CSS2§6.4.3, defining an extended range of selectors.&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://www.w3.org/TR/css-namespaces/&quot;&gt;CSS Namespaces&lt;/a&gt; &lt;strong&gt;[CSS3-NAMESPACE]&lt;/strong&gt;: Introduces an @namespace rule to allow namespace-prefixed selectors.&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://www.w3.org/TR/css-cascade-4/&quot;&gt;CSS Cascading and Inheritance Level 4&lt;/a&gt; &lt;strong&gt;[CSS-CASCADE-4]&lt;/strong&gt;: Extends and supersedes CSS2§1.4.3 and CSS2§6, as well as [CSS-CASCADE-3]. Describes how to collate style rules and assign values to all properties on all elements. By way of cascading and inheritance, values are propagated for all properties on all elements.&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://www.w3.org/TR/css-values-3/&quot;&gt;CSS Values and Units Level 3&lt;/a&gt; &lt;strong&gt;[CSS-VALUES-3]&lt;/strong&gt;: Extends and supersedes CSS2§1.4.2.1, CSS2§4.3, and CSS2§A.2.1–3, defining CSS’s property definition syntax and expanding its set of units.&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://www.w3.org/TR/css-variables-1/&quot;&gt;CSS Custom Properties for Cascading Variables Module Level 1&lt;/a&gt; &lt;strong&gt;[CSS-VARIABLES-1]&lt;/strong&gt;: Introduces cascading variables as a new primitive value type that is accepted by all CSS properties, and custom properties for defining them.&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://www.w3.org/TR/css-box-3/&quot;&gt;CSS Box Model Level 3&lt;/a&gt; &lt;strong&gt;[CSS-BOX-3]&lt;/strong&gt;: Replaces CSS2§8.1, §8.2, §8.3 (but not §8.3.1), and §8.4.&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://www.w3.org/TR/css-color-3/&quot;&gt;CSS Color Level 3&lt;/a&gt; &lt;strong&gt;[CSS-COLOR-3]&lt;/strong&gt;: Extends and supersedes CSS2§4.3.6, CSS2§14.1, and CSS2§18.2, introducing an extended range of color values. Also introduces the opacity property.&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://www.w3.org/TR/css-backgrounds-3/&quot;&gt;CSS Backgrounds and Borders Level 3&lt;/a&gt; &lt;strong&gt;[CSS-BACKGROUNDS-3]&lt;/strong&gt;: Extends and supersedes CSS2§8.5 and CSS2§14.2, providing more control of backgrounds and borders, including layered background images, image borders, and drop shadows.&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://www.w3.org/TR/css-images-3/&quot;&gt;CSS Images Level 3&lt;/a&gt; &lt;strong&gt;[CSS-IMAGES-3]&lt;/strong&gt;: Redefines and incorporates the external 2D image value type, introduces native 2D gradients, and adds additional controls for replaced element sizing and rendering.&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://www.w3.org/TR/css-fonts-3/&quot;&gt;CSS Fonts Level 3&lt;/a&gt; &lt;strong&gt;[CSS-FONTS-3]&lt;/strong&gt;: Extends and supersedes CSS2§15 and provides more control over font choice and feature selection.&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://www.w3.org/TR/css-writing-modes-3/&quot;&gt;CSS Writing Modes Level 3&lt;/a&gt; &lt;strong&gt;[CSS-WRITING-MODES-3]&lt;/strong&gt;: Defines CSS support for various international writing modes, such as left-to-right (e.g. Latin or Indic), right-to-left (e.g. Hebrew or Arabic), bidirectional (e.g. mixed Latin and Arabic) and vertical (e.g. Asian scripts). Replaces and extends CSS2§8.6 and §9.10.&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://www.w3.org/TR/css-multicol-1/&quot;&gt;CSS Multi-column Layout Level 1&lt;/a&gt; &lt;strong&gt;[CSS-MULTICOL-1]&lt;/strong&gt;: Introduces multi-column flows to CSS layout.&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://www.w3.org/TR/css-flexbox-1/&quot;&gt;CSS Flexible Box Module Level 1&lt;/a&gt; &lt;strong&gt;[CSS-FLEXBOX-1]&lt;/strong&gt;: Introduces a flexible linear layout model for CSS.&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://www.w3.org/TR/css-ui-3/&quot;&gt;CSS User Interface Module Level 3&lt;/a&gt; &lt;strong&gt;[CSS-UI-3]&lt;/strong&gt;: Extends and supersedes CSS2§18.1 and CSS2§18.4, defining cursor, outline, and several new CSS features that also enhance the user interface.&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://www.w3.org/TR/css-contain-1/&quot;&gt;CSS Containment Module Level 1&lt;/a&gt; &lt;strong&gt;[CSS-CONTAIN-1]&lt;/strong&gt;: Introduces the contain property, which enforces the independent CSS processing of an element’s subtree in order to enable heavy optimizations by user agents when used well.&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://www.w3.org/TR/css-transforms-1/&quot;&gt;CSS Transforms Level 1&lt;/a&gt; &lt;strong&gt;[CSS-TRANSFORMS-1]&lt;/strong&gt;: Introduces coordinate-based graphical transformations to CSS.&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://www.w3.org/TR/compositing-1/&quot;&gt;CSS Compositing and Blending Level 1&lt;/a&gt; &lt;strong&gt;[COMPOSITING]&lt;/strong&gt;: Defines the compositing and blending of overlaid content and introduces features to control their modes.&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://www.w3.org/TR/css-easing-1/&quot;&gt;CSS Easing Functions Level 1&lt;/a&gt; &lt;strong&gt;[CSS-EASING-1]&lt;/strong&gt;: Describes a way for authors to define a transformation that controls the rate of change of some value. Applied to animations, such transformations can be used to produce animations that mimic physical phenomena such as momentum or to cause the animation to move in discrete steps producing robot-like movement.&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://www.w3.org/TR/css-counter-styles-3/&quot;&gt;CSS Counter Styles Level 3&lt;/a&gt; &lt;strong&gt;[CSS-COUNTER-STYLES-3]&lt;/strong&gt;: Introduces the @counter-style rule, which allows authors to define their own custom counter styles for use with CSS list-marker and generated-content counters [CSS-LISTS-3]. It also predefines a set of common counter styles, including the ones present in CSS2 and CSS2.1.&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://www.w3.org/Style/CSS/specs.en.html&quot;&gt;List of all current-work CSS specifications&lt;/a&gt;&lt;/p&gt; 
&lt;h4&gt;Older specs&lt;/h4&gt; 
&lt;p&gt;&lt;a href=&quot;https://www.w3.org/TR/CSS1/&quot;&gt;CSS Level 1&lt;/a&gt; (1996, revised 2008; superseded in 2016)&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>DFlex</title>
      <link>https://tedneward.github.io/Research/presentation/dflex/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/dflex/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.dflex.dev/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/dflex-js/dflex&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>DocBook</title>
      <link>https://tedneward.github.io/Research/presentation/docbook/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/docbook/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://docbook.org/&quot;&gt;Website&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>DZSlides</title>
      <link>https://tedneward.github.io/Research/presentation/dzslides/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/dzslides/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;http://paulrouget.com/dzslides&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/paulrouget/dzslides&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Ember</title>
      <link>https://tedneward.github.io/Research/presentation/emberjs/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/emberjs/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://emberjs.com/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/emberjs/ember.js&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Fabulous</title>
      <link>https://tedneward.github.io/Research/presentation/fabulous/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/fabulous/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://fsprojects.github.io/Fabulous/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/fsprojects/Fabulous&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;em&gt;F# Functional App Development, using declarative dynamic UI&lt;/em&gt;&lt;/p&gt; 
&lt;h2&gt;Documentation&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://fsprojects.github.io/Fabulous/Fabulous.XamarinForms/index.html#getting-started&quot;&gt;Getting started&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://fsprojects.github.io/Fabulous/&quot;&gt;Fabulous documentation&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;About Fabulous&lt;/h2&gt; 
&lt;p&gt;Fabulous aims to provide all the tools to let you create your own mobile and desktop apps using only F# and the &lt;a href=&quot;https://guide.elm-lang.org/architecture/&quot;&gt;Model-View-Update architecture&lt;/a&gt; (shorten to MVU), with a great F# DSL for building dynamic UIs.&lt;br&gt; The combination of F# and MVU makes for a great development experience.&lt;/p&gt; 
&lt;p&gt;Note that Fabulous itself does not provide UI controls, so you&apos;ll need to combine it with another framework like Xamarin.Forms.&lt;/p&gt; 
&lt;h3&gt;Fabulous for Xamarin.Forms&lt;/h3&gt; 
&lt;p&gt;Fabulous for Xamarin.Forms combines both frameworks with a tailored DSL to let you take advantage of everything Xamarin.Forms has to offer while keeping all the benefits of Fabulous.&lt;/p&gt; 
&lt;p&gt;With Fabulous for Xamarin.Forms, you will be able to write complete applications in F# like this:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-fsharp&quot;&gt;type Model = { Text: string }
type Msg = ButtonClicked

let init () = { Text = &quot;Hello Fabulous!&quot; }

let update msg model =
    match msg with
    | ButtonClicked -&amp;gt; { model with Text = &quot;Thanks for using Fabulous!&quot; }

let view model dispatch =
    View.ContentPage(
        View.StackLayout(
            children = [
                View.Image(source = Image.fromPath &quot;fabulous.png&quot;)
                View.Label(text = model.Text)
                View.Button(text = &quot;Click me&quot;, command = fun () -&amp;gt; dispatch ButtonClicked)
            ]
        )
    )
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;&lt;a href=&quot;https://github.com/fsprojects/Fabulous/tree/master/Fabulous.XamarinForms&quot;&gt;Learn more about Fabulous for Xamarin.Forms&lt;/a&gt;&lt;/p&gt; 
&lt;h3&gt;Can I use Fabulous with other UI frameworks?&lt;/h3&gt; 
&lt;p&gt;Fabulous is not tied to Xamarin.Forms.&lt;br&gt; If you want to use your favorite UI framework instead, it&apos;s possible.&lt;/p&gt; 
&lt;p&gt;To help you with that, Fabulous comes with its own code generator, called Fabulous.CodeGen, to automate the creation of a DSL specific to your UI framework.&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;Fabulous.CodeGen/README.md&quot;&gt;Learn more about Fabulous.CodeGen&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Flyde</title>
      <link>https://tedneward.github.io/Research/presentation/flyde/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/flyde/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.flyde.dev/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/flydelabs/flyde&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Flyde is a holistic solution for prototyping, integrating, evaluating and iterating on AI-heavy backend logic. It&apos;s a visual extension of TypeScript that runs in-codebase, providing the missing link between developers and non-developers working on backend AI workflows.&lt;/p&gt; 
&lt;p&gt;Flyde allows you to create visual flows for backend services like AI agents, prompt chains, API orchestration, and agentic workflows - directly integrated with your existing codebase. It includes a VSCode extension and seamlessly integrates with existing TypeScript/JavaScript code.&lt;/p&gt; 
&lt;h4&gt;Who is Flyde for?&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt; &lt;p&gt;Product Teams &amp;amp; Developers: Flyde bridges the gap between technical and non-technical team members. Product managers, designers, and backend developers can collaborate on the same visual flows, making complex backend logic transparent and enabling everyone to contribute meaningfully to the development process.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Developers Building AI-Powered Backends: If you&apos;re dealing with complex prompt chains, AI agents, or multi-step backend AI workflows, Flyde provides a more manageable way to build, debug, and maintain these systems while keeping everything in your codebase.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Teams Seeking Visual Clarity: Whether you&apos;re prototyping new backend features, managing complex business logic, API orchestration, or simply looking for a better way to document and understand your backend application flow, Flyde&apos;s visual approach helps you see the big picture while maintaining the power of code.&lt;/p&gt; &lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>FOX Toolkit</title>
      <link>https://tedneward.github.io/Research/presentation/fox/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/fox/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;http://www.fox-toolkit.org/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;http://www.fox-toolkit.org/download.html&quot;&gt;Downloads&lt;/a&gt; (source zips available)&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Glimesh</title>
      <link>https://tedneward.github.io/Research/presentation/glimesh/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/glimesh/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://glimesh.tv/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/glimesh/glimesh.tv&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>GTK+ (GIMP Toolkit)</title>
      <link>https://tedneward.github.io/Research/presentation/gtk/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/gtk/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.gtk.org/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://gitlab.gnome.org/GNOME/gtk/&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.gtkmm.org/en/&quot;&gt;gtkmm&lt;/a&gt;: the official C++ interface for the popular GUI library GTK+. Highlights include typesafe callbacks, and a comprehensive set of widgets that are easily extensible via inheritance. You can create user interfaces either in code or with the &lt;a href=&quot;https://glade.gnome.org/&quot;&gt;Glade User Interface designer&lt;/a&gt;, using Gtk::Builder. There&apos;s extensive documentation, including API reference and a tutorial.&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Hilla</title>
      <link>https://tedneward.github.io/Research/presentation/hilla/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/hilla/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://hilla.dev/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/vaadin/hilla&quot;&gt;Source&lt;/a&gt; (part of &lt;a href=&quot;../vaadin&quot;&gt;Vaadin&lt;/a&gt;)&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Hugo</title>
      <link>https://tedneward.github.io/Research/presentation/hugo/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/hugo/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://gohugo.io/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/gohugoio/hugo&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>JAMStack</title>
      <link>https://tedneward.github.io/Research/presentation/jamstack/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/jamstack/index.html</guid>
      	<description>
	&lt;h1&gt;Rationale&lt;/h1&gt; 
&lt;p&gt;&lt;strong&gt;Better Performance&lt;/strong&gt;&lt;br&gt; Why wait for pages to build on the fly when you can generate them at deploy time? When it comes to minimizing the time to first byte, nothing beats pre-built files served over a CDN.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Higher Security&lt;/strong&gt;&lt;br&gt; With server-side processes abstracted into microservice APIs, surface areas for attacks are reduced. You can also leverage the domain expertise of specialist third-party services.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Cheaper, Easier Scaling&lt;/strong&gt;&lt;br&gt; When your deployment amounts to a stack of files that can be served anywhere, scaling is a matter of serving those files in more places. CDNs are perfect for this, and often include scaling in all of their plans.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Better Developer Experience&lt;/strong&gt;&lt;br&gt; Loose coupling and separation of controls allow for more targeted development and debugging, and the expanding selection of CMS options for site generators remove the need to maintain a separate stack for content and marketing.&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://jamstack.org/&quot;&gt;Website&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Juce</title>
      <link>https://tedneward.github.io/Research/presentation/juce/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/juce/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://juce.com/&quot;&gt;Website&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Pros: battle tested / production ready, fancy&lt;/p&gt; 
&lt;p&gt;Cons: more of an audio framework with UIs, heavy framework (a-la Qt)&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Kotter</title>
      <link>https://tedneward.github.io/Research/presentation/console/kotter/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/console/kotter/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/varabyte/kotter&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Terminal.GUI</title>
      <link>https://tedneward.github.io/Research/presentation/console/terminalgui/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/console/terminalgui/index.html</guid>
      	<description>
	&lt;p&gt;Terminal.GUI.NET: &lt;a href=&quot;https://github.com/migueldeicaza/gui.cs&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;TerminalKit for Swift: &lt;a href=&quot;https://github.com/migueldeicaza/TermKit&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Apache Cordova</title>
      <link>https://tedneward.github.io/Research/presentation/cordova/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/cordova/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://cordova.apache.org/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/apache?utf8=%E2%9C%93&amp;amp;q=cordova-&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;hr&gt; 
&lt;p&gt;&lt;a href=&quot;https://volt.build/&quot;&gt;Volt&lt;/a&gt; is a build system for Cordova&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Cascading StyleSheets (CSS)</title>
      <link>https://tedneward.github.io/Research/presentation/css/index/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/css/index/index.html</guid>
      	<description>
	&lt;h2&gt;Useful locations&lt;/h2&gt; 
&lt;p&gt;Cheat sheets/references: &lt;a href=&quot;https://htmlcheatsheet.com/css/&quot;&gt;Interactive cheat sheet&lt;/a&gt; | &lt;a href=&quot;https://adam-marsden.co.uk/css-cheat-sheet&quot;&gt;Another&lt;/a&gt;&lt;/p&gt; 
&lt;h2&gt;Most useful debugging trick for CSS ever&lt;/h2&gt; 
&lt;p&gt;&lt;code&gt;selector { outline: 1px solid red; }&lt;/code&gt;&lt;/p&gt; 
&lt;h2&gt;CSS Levels&lt;/h2&gt; 
&lt;p&gt;From &lt;a href=&quot;https://www.w3.org/TR/CSS/&quot;&gt;the CSS Snapshot doc&lt;/a&gt;:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;CSS Level 1&lt;/strong&gt;: The CSS Working Group considers the CSS1 specification to be obsolete. CSS Level 1 is defined as all the features defined in the CSS1 specification (properties, values, at-rules, etc), but using the syntax and definitions in the CSS2.1 specification. CSS Style Attributes defines its inclusion in element-specific style attributes.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;CSS Level 2&lt;/strong&gt;: Although the CSS2 specification is technically a W3C Recommendation, it passed into the Recommendation stage before the W3C had defined the Candidate Recommendation stage. Over time implementation experience and further review has brought to light many problems in the CSS2 specification, so instead of expanding an already unwieldy errata list, the CSS Working Group chose to define CSS Level 2 Revision 1 (CSS2.1). In case of any conflict between the two specs CSS2.1 contains the definitive definition. Once CSS2.1 became Candidate Recommendation--effectively though not officially the same level of stability as CSS2--obsoleted the CSS2 Recommendation. Features in CSS2 that were dropped from CSS2.1 should be considered to be at the Candidate Recommendation stage, but note that many of these have been or will be pulled into a CSS Level 3 working draft, in which case that specification will, once it reaches CR, obsolete the definitions in CSS2. The CSS2.1 specification defines CSS Level 2 and the CSS Style Attributes specification defines its inclusion in element-specific style attributes.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;CSS Level 3&lt;/strong&gt;: builds on CSS Level 2 module by module, using the CSS2.1 specification as its core. Each module adds functionality and/or replaces part of the CSS2.1 specification. The CSS Working Group intends that the new CSS modules will not contradict the CSS2.1 specification: only that they will add functionality and refine definitions. As each module is completed, it will be plugged in to the existing system of CSS2.1 plus previously-completed modules. From this level on modules are levelled independently: for example Selectors Level 4 may well be completed before CSS Line Module Level 3. Modules with no CSS Level 2 equivalent start at Level 1; modules that update features that existed in CSS Level 2 start at Level 3.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;CSS Level 4 and beyond&lt;/strong&gt;: There is no CSS Level 4. Independent modules can reach level 4 or beyond, but CSS the language no longer has levels. (&quot;CSS Level 3&quot; as a term is used only to differentiate it from the previous monolithic versions.)&lt;/p&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Tips, Tricks, etc&lt;/h2&gt; 
&lt;p&gt;&lt;a href=&quot;https://www.joshwcomeau.com/css/understanding-layout-algorithms&quot;&gt;&quot;Understanding layout algorithms&quot;&lt;/a&gt;: &quot;The key realization I had is that CSS is so much more than a collection of properties. It&apos;s a constellation of inter-connected layout algorithms. Each algorithm is a complex system with its own rules and secret mechanisms. It&apos;s not enough to learn what specific properties do. We need to learn how the layout algorithms work, and how they use the properties we provide to them.&quot;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://flexboxfroggy.com/&quot;&gt;Flexbox Froggy&lt;/a&gt;: A cute Frogger-themed series of exercises practicing with CSS Flexbox styling.&lt;/p&gt; 
&lt;h2&gt;Features&lt;/h2&gt; 
&lt;h3&gt;CSS Masonry&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.smashingmagazine.com/2025/12/masonry-things-you-wont-need-library-anymore/&quot;&gt;&quot;Masonry: Things Won&apos;t Need a Library For Anymore&quot;&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Reading&lt;/h2&gt; 
&lt;h3&gt;Books&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;http://learn.shayhowe.com/html-css/&quot;&gt;A beginner&apos;s guide to HTML&amp;amp;CSS&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://marksheet.io&quot;&gt;A free guide to learn HTML and CSS&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://adaptivewebdesign.info/1st-edition/&quot;&gt;Adaptive Web Design&lt;/a&gt; - Aaron Gustafson&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/airbnb/css&quot;&gt;Airbnb CSS / Sass Styleguide&lt;/a&gt; - Airbnb&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://airbnb.io/javascript/css-in-javascript/&quot;&gt;Airbnb CSS-in-JavaScript Style Guide&lt;/a&gt; - Airbnb&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://learn.shayhowe.com/advanced-html-css/&quot;&gt;An advanced guide to HTML&amp;amp;CSS&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://atomicdesign.bradfrost.com&quot;&gt;Atomic Design&lt;/a&gt; - Brad Frost&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://web.archive.org/web/20160505010319/http://learnjs.io/canvassing/read/&quot;&gt;Canvassing&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://mdo.github.io/code-guide/&quot;&gt;Code Guide: Standards for developing flexible, durable, and sustainable HTML and CSS&lt;/a&gt; - Mark Otto&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/cssanimation/css-animation-101&quot;&gt;CSS Animation 101&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://goalkicker.com/CSSBook&quot;&gt;CSS Notes for Professionals&lt;/a&gt; - Compiled from StackOverflow Documentation (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://domenlightenment.com&quot;&gt;DOM Enlightenment&lt;/a&gt; - Cody Lindley (HTML)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://dash.generalassemb.ly&quot;&gt;GA Dash&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://google.github.io/styleguide/htmlcssguide.html&quot;&gt;Google&apos;s HTML/CSS Style Guide&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.digitalocean.com/community/books/how-to-build-a-website-with-html-ebook&quot;&gt;How To Build a Website with HTML&lt;/a&gt; - Erin Glass (PDF, EPUB)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://web.archive.org/web/20180816174417/http://howtocodeinhtml.com/HowToCodeInHTML5AndCSS3.pdf&quot;&gt;How to Code in HTML5 and CSS3&lt;/a&gt; - Damian Wielgosik (PDF)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.internetingishard.com&quot;&gt;Interneting is Hard (But it Doesn&apos;t Have to Be)&lt;/a&gt; - Oliver James&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://learnlayout.com&quot;&gt;Learn CSS Layout&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://book.mixu.net/css/&quot;&gt;Learn CSS Layout the pedantic way&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://learn.shayhowe.com&quot;&gt;Learn to Code HTML &amp;amp; CSS&lt;/a&gt; - Shay Howe&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://adamschwartz.co/magic-of-css/&quot;&gt;Magic of CSS&lt;/a&gt; - Adam Schwartz (HTML) (:construction: &lt;em&gt;in process&lt;/em&gt;)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://maintainablecss.com&quot;&gt;MaintainableCSS&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://svgpocketguide.com&quot;&gt;Pocket Guide to Writing SVG&lt;/a&gt; - Joni Trythall&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://resilientwebdesign.com/#Resilientweb%20design&quot;&gt;Resilient Web Design&lt;/a&gt; - Jeremy Keith&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://rtlstyling.com&quot;&gt;RTL Styling 101&lt;/a&gt; - Ahmad Shadeed&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://web.archive.org/web/20191116073929/http://smacss.com/&quot;&gt;Scalable and Modular Architecture for CSS&lt;/a&gt; - Jonathan Snook&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://flaviocopes.com/page/css-handbook/&quot;&gt;The CSS Handbook&lt;/a&gt; - Flavio Copes (PDF, EPUB, Kindle) &lt;em&gt;(email address requested)&lt;/em&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://ohansemmanuel.github.io/uf_download.html&quot;&gt;Understanding Flexbox: Everything you need to know&lt;/a&gt; - Ohans Emmanuel&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.syncfusion.com/ebooks/w3_css_succinctly&quot;&gt;W3.CSS Succinctly&lt;/a&gt; - Joseph D. Booth&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://chimera.labs.oreilly.com/books/1234000001552&quot;&gt;Web Audio API&lt;/a&gt; - Boris Smus&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://leanpub.com/web-visual-effects-with-css3/read&quot;&gt;Web Visual Effects with CSS3&lt;/a&gt; - Thomas Mak&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Articles&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.howtogeek.com/add-a-smooth-typewriter-animation-to-your-website-without-any-javascript/&quot;&gt;https://www.howtogeek.com/add-a-smooth-typewriter-animation-to-your-website-without-any-javascript/&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://tympanus.net/codrops/2025/11/10/crafting-generative-css-worlds/&quot;&gt;Crafting Generative CSS Worlds: Learn how stacked grids and 3D transforms can bring heightmaps to life using nothing but the power of CSS.&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>CycleJS</title>
      <link>https://tedneward.github.io/Research/presentation/cyclejs/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/cyclejs/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://cycle.js.org/&quot;&gt;Website&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Dillinger</title>
      <link>https://tedneward.github.io/Research/presentation/dillinger/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/dillinger/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://dillinger.io/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/joemccann/dillinger.git&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Docmost</title>
      <link>https://tedneward.github.io/Research/presentation/docmost/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/docmost/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://docmost.com/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/docmost/docmost&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>ElectronJS</title>
      <link>https://tedneward.github.io/Research/presentation/electron/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/electron/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.electronjs.org/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://www.electronjs.org/docs&quot;&gt;Docs&lt;/a&gt; | &lt;a href=&quot;https://github.com/electron&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://github.com/electron/electron-quick-start&quot;&gt;Quick start app&lt;/a&gt;, commonly used as the start scaffolding for a new project.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>EPIC stack</title>
      <link>https://tedneward.github.io/Research/presentation/epicstack/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/epicstack/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.epicweb.dev/epic-stack&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/epicweb-dev/epic-stack&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;The primary goal of the Epic Stack is to help your team get over analysis paralysis by giving you solid opinions for technologies to use to build your web application. The Epic Stack is really two things:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;A project starter&lt;/li&gt; 
 &lt;li&gt;A reference implementation&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;For those of you starting a new project, you can use the &lt;code&gt;create-remix CLI&lt;/code&gt; custom stacks feature to bootstrap your app with &lt;code&gt;npx create-remix@latest --typescript --install --template epicweb-dev/epic-stack&lt;/code&gt; and you’ll be set.&lt;/p&gt; 
&lt;p&gt;With that context, here are a few things you get today:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Remix is the Web Framework of choice&lt;/li&gt; 
 &lt;li&gt;Fly app deployment with Docker&lt;/li&gt; 
 &lt;li&gt;Multi-region, distributed, production-ready SQLite Database with LiteFS.&lt;/li&gt; 
 &lt;li&gt;Healthcheck endpoint for Fly backups region fallbacks&lt;/li&gt; 
 &lt;li&gt;Grafana Dashboards of the running app&lt;/li&gt; 
 &lt;li&gt;GitHub Actions with testing and deploy on merge for both production and staging environments&lt;/li&gt; 
 &lt;li&gt;Email/Password Authentication with cookie-based sessions&lt;/li&gt; 
 &lt;li&gt;Transaction email with Mailgun and forgot password/password reset support.&lt;/li&gt; 
 &lt;li&gt;Progressively Enhanced and fully type safe forms with Conform&lt;/li&gt; 
 &lt;li&gt;Database ORM with Prisma&lt;/li&gt; 
 &lt;li&gt;Role-based User Permissions.&lt;/li&gt; 
 &lt;li&gt;Custom built image hosting&lt;/li&gt; 
 &lt;li&gt;Caching via cachified: Both in-memory and SQLite-based (with better-sqlite3)&lt;/li&gt; 
 &lt;li&gt;Styling with Tailwind&lt;/li&gt; 
 &lt;li&gt;An excellent, customizable component library with Radix UI&lt;/li&gt; 
 &lt;li&gt;End-to-end testing with Playwright&lt;/li&gt; 
 &lt;li&gt;Local third party request mocking with MSW&lt;/li&gt; 
 &lt;li&gt;Unit testing with Vitest and Testing Library with pre-configured Test Database&lt;/li&gt; 
 &lt;li&gt;Code formatting with Prettier&lt;/li&gt; 
 &lt;li&gt;Linting with ESLint&lt;/li&gt; 
 &lt;li&gt;Static Types with TypeScript&lt;/li&gt; 
 &lt;li&gt;Runtime schema validation with zod&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Fenster</title>
      <link>https://tedneward.github.io/Research/presentation/fenster/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/fenster/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/zserge/fenster&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Fonoster</title>
      <link>https://tedneward.github.io/Research/presentation/fonoster/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/fonoster/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://fonoster.com/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/fonoster/fonoster&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Fractalide</title>
      <link>https://tedneward.github.io/Research/presentation/fractalide/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/fractalide/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/fractalide/fractalide&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Gluon</title>
      <link>https://tedneward.github.io/Research/presentation/gluon/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/gluon/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://gluonhq.com/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/gluonhq&quot;&gt;Source&lt;/a&gt; | &lt;a href=&quot;https://docs.gluonhq.com/#_introduction&quot;&gt;Docs&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Gluon provides an easy and modern approach for developing Java Client applications. These applications can run on the JVM or can be converted to a platform specific native-images which have lighting fast startup and takes a fraction of space. Moreover, applications can also be targeted to Android, iOS, and embedded apart from all the desktop environments.&lt;/p&gt; 
&lt;p&gt;Gluon provides all the tools necessary to build these applications including, but not limited to, build tools, IDE plugins, UI library, cloud connectivity, data-binding etc.&lt;/p&gt; 
&lt;h2&gt;Reading&lt;/h2&gt; 
&lt;h3&gt;Articles&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://foojay.io/today/creating-mobile-apps-with-javafx-part-1/&quot;&gt;https://foojay.io/today/creating-mobile-apps-with-javafx-part-1/&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://foojay.io/today/creating-mobile-apps-with-javafx-part-2/&quot;&gt;https://foojay.io/today/creating-mobile-apps-with-javafx-part-2/&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://foojay.io/today/creating-mobile-apps-with-javafx-part-3/&quot;&gt;https://foojay.io/today/creating-mobile-apps-with-javafx-part-3/&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>guizero</title>
      <link>https://tedneward.github.io/Research/presentation/guizero/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/guizero/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://lawsie.github.io/guizero/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/lawsie/guizero&quot;&gt;Source&lt;/a&gt; | &lt;a href=&quot;&quot;&gt;Book&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;The aim of guizero is to make the process of creating simple GUIs quick, accessible and understandable for new learners.&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Works with standard Python Tkinter GUI library (and no need to install other libraries)&lt;/li&gt; 
 &lt;li&gt;Abstracts away details new learners find difficult to understand (such as Tkinter StringVar() objects)&lt;/li&gt; 
 &lt;li&gt;Accessible widget naming system to help new learners to build up a mental model&lt;/li&gt; 
 &lt;li&gt;Flexible enough to be used for projects up to A-Level standard, yet accessible to primary school children&lt;/li&gt; 
 &lt;li&gt;Comprehensive and accessible documentation with examples&lt;/li&gt; 
 &lt;li&gt;Generates helpful additional error messages&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Examples&lt;/h2&gt; 
&lt;p&gt;Hello, world&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;from guizero import App, Text, PushButton
app = App(title=&quot;guizero&quot;)
intro = Text(app, text=&quot;Have a go with guizero and see what you can create.&quot;)
ok = PushButton(app, text=&quot;Ok&quot;)

app.display()
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Get some text&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;from guizero import App, TextBox

app = App()
name = TextBox(app, text=&quot;Enter your name&quot;)

app.display()
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Use a PushButton to display a message when the button is pressed.&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;from guizero import App, TextBox, PushButton, Text

def update_text():
    label.value = name.value

app = App()
label = Text(app, text=&quot;What&apos;s your name?&quot;)
name = TextBox(app)
button = PushButton(app, command=update_text)

app.display()
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Use a Picture object to display an image.&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;from guizero import App, Picture
app = App()
pic = Picture(app, image=&quot;myimage.gif&quot;)
app.display()
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Create a picture PushButton with an image like this:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;from guizero import App, PushButton
def do_nothing():
    print(&quot;A picture button was pressed&quot;)

app = App()
button = PushButton(app, image=&quot;button.gif&quot;, command=do_nothing)
app.display()
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;The image button.gif should be stored in the folder as your program. Alternatively you can provide the path to your image.&lt;/p&gt; 
&lt;p&gt;Have 2 buttons, start and stop with them changing the enabled state of each other.&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;from guizero import App, PushButton

def start():
    start_button.disable()
    stop_button.enable()

def stop():
    start_button.enable()
    stop_button.disable()

app = App()
start_button = PushButton(app, command=start, text=&quot;start&quot;)
stop_button = PushButton(app, command=stop, text=&quot;stop&quot;, enabled=False)
app.display()
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Your app doesn&apos;t have to use the standard colors and text, let your user pick the background and text color from 2 combo&apos;s.&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;
from guizero import App, Combo, Text

def update_bg():
    app.bg = bg_combo.value

def update_text():
    app.text_color = text_combo.value

colors = [&quot;black&quot;, &quot;white&quot;, &quot;red&quot;, &quot;green&quot;, &quot;blue&quot;]

app = App()
app.bg = &quot;black&quot;
app.text_color = &quot;white&quot;

title1 = Text(app, text=&quot;Background color&quot;)
bg_combo = Combo(app, options=colors, selected=app.bg, command=update_bg)

title2 = Text(app, text=&quot;Text color&quot;)
text_combo = Combo(app, options=colors, selected=app.text_color, command=update_text)

app.display()
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Display an image on the screen with 2 sliders, 1 for height and 1 for width.&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;from guizero import App, Slider, Picture

def resize():
    picture.width = width.value
    picture.height = height.value

app = App(layout=&quot;grid&quot;)

picture = Picture(app, image=&quot;image.gif&quot;, grid=[0,1])

width = Slider(app, command=resize, grid=[0,0], start=1, end=picture.width)
width.width = picture.width
width.value = picture.width

height = Slider(app, command=resize, horizontal=False, grid=[1,1], start=1, end=picture.height)
height.height = picture.height
height.value = picture.height

app.display()
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;To be able to react when a user double click&apos;s you will need to use events.&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;from guizero import App, Text

def double_click():
    double_click_me.value = &quot;Thanks&quot;

app = App()

double_click_me = Text(app, text=&quot;Double click me&quot;)
double_click_me.when_double_clicked = double_click

app.display()
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;You can use repeat to periodically update your application. For example, a timer which updates every 1 second (1000 ms).&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;from guizero import App, Text

# Update the counter
def counter():
    text.value = int(text.value) + 1

app = App(&quot;Hello world&quot;)
text = Text(app, text=&quot;1&quot;)

# Schedule call to counter() every 1000ms
text.repeat(1000, counter)  

app.display()
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;You can use a yesno box to check whether someone really wants to exit your app. If they click yes, the app is closed, if not, nothing happens and they can continue with what they were doing.&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;from guizero import App, Text

# Ask the user if they really want to close the window
def do_this_when_closed():
    if app.yesno(&quot;Close&quot;, &quot;Do you want to quit?&quot;):
        app.destroy()

app = App()

title = Text(app, text=&quot;blank app&quot;)

# When the user tries to close the window, run the function do_this_when_closed()
app.when_closed = do_this_when_closed

app.display()
&lt;/code&gt;&lt;/pre&gt;
	</description>
    </item>
    <item>
      <title>HMPL</title>
      <link>https://tedneward.github.io/Research/presentation/hmpl/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/hmpl/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://hmpl-lang.dev/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/hmpl-language/hmpl&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Alternative to HTMX and Alpine.js.&lt;/p&gt; 
&lt;h4&gt;Example&lt;/h4&gt; 
&lt;pre&gt;&lt;code&gt;&amp;lt;div&amp;gt;
  {{#request src=&quot;/api/my-component.html&quot;}}
    {{#indicator trigger=&quot;pending&quot;}}
      &amp;lt;p&amp;gt;Loading...&amp;lt;/p&amp;gt;
    {{/indicator}}
  {{/request}}
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Basic usage:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;import hmpl from &quot;hmpl-js&quot;;

const templateFn = hmpl.compile(
  `&amp;lt;div&amp;gt;
      &amp;lt;button data-action=&quot;increment&quot; id=&quot;btn&quot;&amp;gt;Click!&amp;lt;/button&amp;gt;
      &amp;lt;div&amp;gt;Clicks: {{#request src=&quot;/api/clicks&quot; after=&quot;click:#btn&quot;}}{{/request}}&amp;lt;/div&amp;gt;
  &amp;lt;/div&amp;gt;`
);

const clicker = templateFn(({ request: { event } }) =&amp;gt; ({
  body: JSON.stringify({ action: event.target.getAttribute(&quot;data-action&quot;) })
})).response;

document.querySelector(&quot;#app&quot;).append(clicker);
&lt;/code&gt;&lt;/pre&gt;
	</description>
    </item>
    <item>
      <title>IMGUI</title>
      <link>https://tedneward.github.io/Research/presentation/imgui/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/imgui/index.html</guid>
      	<description>
	&lt;p&gt;Library&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Jitsi</title>
      <link>https://tedneward.github.io/Research/presentation/jitsi/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/jitsi/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://jitsi.org/meet&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/jitsi/jitsi-meet&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Browsers (Web)</title>
      <link>https://tedneward.github.io/Research/platforms/web/index/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">platforms/web/index/index.html</guid>
      	<description>
	&lt;p&gt;The Web browsers (&lt;a href=&quot;/platforms/chrome&quot;&gt;Chrome&lt;/a&gt;, &lt;a href=&quot;/platforms/safari&quot;&gt;Safari&lt;/a&gt;, IE, &lt;a href=&quot;/platforms/firefox&quot;&gt;Firefox&lt;/a&gt;, etc) form a platform in of themselves, given how much is targeted specifically to them. That said, there is a great deal of overlap between the browser ecosystem and the &lt;a href=&quot;/platforms/nodejs&quot;&gt;NodeJS&lt;/a&gt; platform, owing to the ECMAScript-based nature of each.&lt;/p&gt; 
&lt;p&gt;Other browsers:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://browser.kagi.com/&quot;&gt;Orion&lt;/a&gt; (macOS, iOS/iPadOS)&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Browser insights&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://taligarsiel.com/Projects/howbrowserswork1.htm&quot;&gt;&quot;How browsers work&quot;&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Web APIs&lt;/h2&gt; 
&lt;p&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API&quot;&gt;MDN list&lt;/a&gt;:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/Background_Tasks_API&quot;&gt;Background tasks&lt;/a&gt;: provides the ability to queue tasks to be executed automatically by the user agent when it determines that there is free time to do so.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/Background_Fetch_API&quot;&gt;Background Fetch API&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/Web_Bluetooth_API&quot;&gt;Bluetooth&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/Broadcast_Channel_API&quot;&gt;Broadcast Channel&lt;/a&gt;: broadcast messages across windows/frames/etc&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API&quot;&gt;Canvas&lt;/a&gt;: a means for drawing 2D graphics via JavaScript and the HTML &lt;code&gt;&amp;lt;canvas&amp;gt;&lt;/code&gt; element.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/Channel_Messaging_API&quot;&gt;Channel Messaging API&lt;/a&gt;: allows two separate scripts running in different browsing contexts attached to the same document (e.g., two IFrames, or the main document and an IFrame, two documents via a SharedWorker, or two workers) to communicate directly, passing messages between one another through two-way channels (or pipes) with a port at each end.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/Console_API&quot;&gt;Console&lt;/a&gt;: functionality to allow developers to perform debugging tasks, such as logging messages or the values of variables at set points in your code, or timing how long an operation takes to complete.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/Credential_Management_API&quot;&gt;Credential Management API&lt;/a&gt;: enables a website to create, store, and retrieve credentials. A credential is an item which enables a system to make an authentication decision: for example, to decide whether to sign a user into an account.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model&quot;&gt;DOM&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API&quot;&gt;Fetch&lt;/a&gt;: generalized replacement for XMLHttpRequest&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/Fullscreen_API&quot;&gt;Fullscreen&lt;/a&gt;: adds methods to present a specific Element (and its descendants) in full-screen mode, and to exit full-screen mode once it is no longer needed.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/Geolocation_API&quot;&gt;Geolocation&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/HTML_Drag_and_Drop_API&quot;&gt;HTML Drag and Drop&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;/storage/indexeddb.html&quot;&gt;IndexedDB&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API&quot;&gt;Intersection Observer&lt;/a&gt;: provides a way to asynchronously observe changes in the intersection of a target element with an ancestor element or with a top-level document&apos;s viewport.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/Navigation_timing_API&quot;&gt;Navigation Timing&lt;/a&gt;: measure the performance of a web site.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/Page_Visibility_API&quot;&gt;Page Visibility&lt;/a&gt;: determine whether a page is actually visible to the user&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/Push_API&quot;&gt;Push API&lt;/a&gt;: gives web applications the ability to receive messages pushed to them from a server, whether or not the web app is in the foreground, or even currently loaded, on a user agent. This lets developers deliver asynchronous notifications and updates to users that opt in&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events&quot;&gt;Server Sent Events&lt;/a&gt;: It&apos;s possible for a server to send new data to a web page at any time, by pushing messages to the web page. These incoming messages can be treated as Events + data inside the web page.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API&quot;&gt;Service Workers&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/Storage_API&quot;&gt;Storage&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/Storage_Access_API&quot;&gt;Storage Access&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/Touch_events&quot;&gt;Touch Events&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/URL_API&quot;&gt;URL&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/Notifications_API&quot;&gt;Web Notifications&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/Web_Storage_API&quot;&gt;Web Storage&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;../webworkers&quot;&gt;Web Workers&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API&quot;&gt;WebGL&lt;/a&gt; (This should be its own page)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/WebRTC_API&quot;&gt;WebRTC&lt;/a&gt; (This should be its own page)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/Websockets_API&quot;&gt;Websockets API&lt;/a&gt; and &lt;a href=&quot;/distribution/websockets.html&quot;&gt;here&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;Reamining list:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Barcode Detection API&lt;/li&gt; 
 &lt;li&gt;Battery API&lt;/li&gt; 
 &lt;li&gt;Beacon&lt;/li&gt; 
 &lt;li&gt;CSS Counter Styles&lt;/li&gt; 
 &lt;li&gt;CSS Font Loading API&lt;/li&gt; 
 &lt;li&gt;CSS Painting API&lt;/li&gt; 
 &lt;li&gt;CSS Typed Object Model API&lt;/li&gt; 
 &lt;li&gt;CSSOM&lt;/li&gt; 
 &lt;li&gt;Clipboard API&lt;/li&gt; 
 &lt;li&gt;Contact Picker API&lt;/li&gt; 
 &lt;li&gt;Content Index API&lt;/li&gt; 
 &lt;li&gt;Encoding API&lt;/li&gt; 
 &lt;li&gt;Encrypted Media Extensions&lt;/li&gt; 
 &lt;li&gt;EyeDropper API&lt;/li&gt; 
 &lt;li&gt;File System Access API&lt;/li&gt; 
 &lt;li&gt;File and Directory Entries API&lt;/li&gt; 
 &lt;li&gt;Gamepad API&lt;/li&gt; 
 &lt;li&gt;HTML DOM&lt;/li&gt; 
 &lt;li&gt;HTML Sanitizer API&lt;/li&gt; 
 &lt;li&gt;High Resolution Time&lt;/li&gt; 
 &lt;li&gt;History API&lt;/li&gt; 
 &lt;li&gt;Image Capture API&lt;/li&gt; 
 &lt;li&gt;Layout Instability API&lt;/li&gt; 
 &lt;li&gt;Long Tasks API&lt;/li&gt; 
 &lt;li&gt;Media Capabilities API&lt;/li&gt; 
 &lt;li&gt;Media Capture and Streams&lt;/li&gt; 
 &lt;li&gt;Media Session API&lt;/li&gt; 
 &lt;li&gt;Media Source Extensions&lt;/li&gt; 
 &lt;li&gt;MediaStream Recording&lt;/li&gt; 
 &lt;li&gt;Network Information API&lt;/li&gt; 
 &lt;li&gt;Payment Request API&lt;/li&gt; 
 &lt;li&gt;Performance API&lt;/li&gt; 
 &lt;li&gt;Performance Timeline API&lt;/li&gt; 
 &lt;li&gt;Periodic Background Sync&lt;/li&gt; 
 &lt;li&gt;Permissions API&lt;/li&gt; 
 &lt;li&gt;Picture-in-Picture API&lt;/li&gt; 
 &lt;li&gt;Pointer Events&lt;/li&gt; 
 &lt;li&gt;Pointer Lock API&lt;/li&gt; 
 &lt;li&gt;Presentation API&lt;/li&gt; 
 &lt;li&gt;Proximity Events&lt;/li&gt; 
 &lt;li&gt;Resize Observer API&lt;/li&gt; 
 &lt;li&gt;Resource Timing API&lt;/li&gt; 
 &lt;li&gt;Screen Capture API&lt;/li&gt; 
 &lt;li&gt;Screen Orientation API&lt;/li&gt; 
 &lt;li&gt;Screen Wake Lock API&lt;/li&gt; 
 &lt;li&gt;Sensor API&lt;/li&gt; 
 &lt;li&gt;Streams&lt;/li&gt; 
 &lt;li&gt;URL Pattern API&lt;/li&gt; 
 &lt;li&gt;Vibration API&lt;/li&gt; 
 &lt;li&gt;Visual Viewport&lt;/li&gt; 
 &lt;li&gt;Web Animations&lt;/li&gt; 
 &lt;li&gt;Web Audio API&lt;/li&gt; 
 &lt;li&gt;Web Authentication API&lt;/li&gt; 
 &lt;li&gt;Web Crypto API&lt;/li&gt; 
 &lt;li&gt;Web MIDI API&lt;/li&gt; 
 &lt;li&gt;Web Share API&lt;/li&gt; 
 &lt;li&gt;Web Speech API&lt;/li&gt; 
 &lt;li&gt;WebCodecs API&lt;/li&gt; 
 &lt;li&gt;WebHID API&lt;/li&gt; 
 &lt;li&gt;WebVR API&lt;/li&gt; 
 &lt;li&gt;WebVTT&lt;/li&gt; 
 &lt;li&gt;WebXR Device API&lt;/li&gt; 
 &lt;li&gt;Window Controls Overlay API&lt;/li&gt; 
 &lt;li&gt;XMLHttpRequest&lt;/li&gt; 
&lt;/ul&gt; 
&lt;hr&gt; 
&lt;h2&gt;Web/browser session replay&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://openreplay.com/&quot;&gt;OpenReplay&lt;/a&gt;: &lt;a href=&quot;https://github.com/openreplay/openreplay&quot;&gt;Source&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://logrocket.com/&quot;&gt;LogRocket&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.fullstory.com/&quot;&gt;FullStory&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Webflow</title>
      <link>https://tedneward.github.io/Research/platforms/webflow/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">platforms/webflow/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://webflow.com/&quot;&gt;Website&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Provides hosting, visual designer.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Windows (OS)</title>
      <link>https://tedneward.github.io/Research/platforms/windows/development/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">platforms/windows/development/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.randallhyde.com/AssemblyLanguage/Win32Asm/index.html&quot;&gt;Win32 Assembly Language&lt;/a&gt;&lt;/p&gt; 
&lt;hr&gt; 
&lt;p&gt;Brief bit of Windows lore: &lt;a href=&quot;https://reddit.com/r/programming/comments/gnazif/ray_tracing_in_notepadexe_at_30_fps/fr8uy2l&quot;&gt;Using Notepad as a debug console for Windows programs&lt;/a&gt;:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-c&quot;&gt;static void nlog(char *str, ...)
{
	HWND notepad, edit;
	va_list ap;
	char buf[256];

	va_start(ap, str);
	vsprintf(buf, str, ap);
	va_end(ap);
	strcat(buf, &quot;\r\n&quot;);
	notepad = FindWindow(NULL, &quot;Untitled - Notepad&quot;);
	edit = FindWindowEx(notepad, NULL, &quot;EDIT&quot;, NULL);
	SendMessage(edit, EM_REPLACESEL, TRUE, (LPARAM)buf);
}
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;... which is kinda a cool trick.&lt;/p&gt; 
&lt;hr&gt;
	</description>
    </item>
    <item>
      <title>Winslopr</title>
      <link>https://tedneward.github.io/Research/platforms/windows/winslopr/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">platforms/windows/winslopr/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/builtbybel/Winslopr&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;59 community-sourced annoyances. Filterable. With fixes.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Xv6</title>
      <link>https://tedneward.github.io/Research/platforms/xv6/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">platforms/xv6/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://pdos.csail.mit.edu/6.828/2021/xv6.html&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/mit-pdos/xv6-riscv.git&quot;&gt;Source&lt;/a&gt; | &lt;a href=&quot;https://pdos.csail.mit.edu/6.828/2021/xv6/book-riscv-rev2.pdf&quot;&gt;Book&lt;/a&gt; (&lt;a href=&quot;https://github.com/mit-pdos/xv6-riscv-book.git&quot;&gt;Source&lt;/a&gt;)&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Accessibility resources</title>
      <link>https://tedneward.github.io/Research/presentation/accessibility/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/accessibility/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://wearecolorblind.com/&quot;&gt;WeAreColorBlind&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>AlpineJS</title>
      <link>https://tedneward.github.io/Research/presentation/alpinejs/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/alpinejs/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://alpinejs.dev/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/alpinejs/alpine&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;&amp;lt;script src=&quot;//unpkg.com/alpinejs&quot; defer&amp;gt;&amp;lt;/script&amp;gt;
 
&amp;lt;div x-data=&quot;{ open: false }&quot;&amp;gt;
    &amp;lt;button @click=&quot;open = true&quot;&amp;gt;Expand&amp;lt;/button&amp;gt;
 
    &amp;lt;span x-show=&quot;open&quot;&amp;gt;
        Content...
    &amp;lt;/span&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;15 Attributes, 6 Properties, 2 Methods.&lt;/p&gt; 
&lt;h1&gt;Docs: Start Here&lt;/h1&gt; 
&lt;p&gt;Create a blank HTML file somewhere on your computer with a name like: &lt;code&gt;i-love-alpine.html&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;Using a text editor, fill the file with these contents:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-alpine&quot;&gt;&amp;lt;html&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;script defer src=&quot;https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js&quot;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
    &amp;lt;h1 x-data=&quot;{ message: &apos;I ❤️ Alpine&apos; }&quot; x-text=&quot;message&quot;&amp;gt;&amp;lt;/h1&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Open your file in a web browser, if you see &lt;code&gt;I ❤️ Alpine&lt;/code&gt;, you&apos;re ready to rumble!&lt;/p&gt; 
&lt;p&gt;Now that you&apos;re all set up to play around, let&apos;s look at three practical examples as a foundation for teaching you the basics of Alpine. By the end of this exercise, you should be more than equipped to start building stuff on your own. Let&apos;s goooooo.&lt;/p&gt; 
&lt;h2&gt;Building a counter&lt;/h2&gt; 
&lt;p&gt;Let&apos;s start with a simple &quot;counter&quot; component to demonstrate the basics of state and event listening in Alpine, two core features.&lt;/p&gt; 
&lt;p&gt;Insert the following into the &lt;code&gt;&amp;lt;body&amp;gt;&lt;/code&gt; tag:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-alpine&quot;&gt;&amp;lt;div x-data=&quot;{ count: 0 }&quot;&amp;gt;
    &amp;lt;button x-on:click=&quot;count++&quot;&amp;gt;Increment&amp;lt;/button&amp;gt;

    &amp;lt;span x-text=&quot;count&quot;&amp;gt;&amp;lt;/span&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Now, you can see with 3 bits of Alpine sprinkled into this HTML, we&apos;ve created an interactive &quot;counter&quot; component.&lt;/p&gt; 
&lt;p&gt;Let&apos;s walk through what&apos;s happening briefly:&lt;/p&gt; 
&lt;h3&gt;Declaring data&lt;/h3&gt; 
&lt;pre&gt;&lt;code class=&quot;language-alpine&quot;&gt;&amp;lt;div x-data=&quot;{ count: 0 }&quot;&amp;gt;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Everything in Alpine starts with an &lt;code&gt;x-data&lt;/code&gt; directive. Inside of &lt;code&gt;x-data&lt;/code&gt;, in plain JavaScript, you declare an object of data that Alpine will track.&lt;/p&gt; 
&lt;p&gt;Every property inside this object will be made available to other directives inside this HTML element. In addition, when one of these properties changes, everything that relies on it will change as well.&lt;/p&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;&lt;code&gt;x-data&lt;/code&gt; is required on a parent element for most Alpine directives to work.&lt;/p&gt; 
&lt;/blockquote&gt; 
&lt;h3&gt;Listening for events&lt;/h3&gt; 
&lt;pre&gt;&lt;code class=&quot;language-alpine&quot;&gt;&amp;lt;button x-on:click=&quot;count++&quot;&amp;gt;Increment&amp;lt;/button&amp;gt;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;&lt;code&gt;x-on&lt;/code&gt; is a directive you can use to listen for any event on an element. We&apos;re listening for a &lt;code&gt;click&lt;/code&gt; event in this case, so ours looks like &lt;code&gt;x-on:click&lt;/code&gt;.&lt;/p&gt; 
&lt;p&gt;You can listen for other events as you&apos;d imagine. For example, listening for a &lt;code&gt;mouseenter&lt;/code&gt; event would look like this: &lt;code&gt;x-on:mouseenter&lt;/code&gt;.&lt;/p&gt; 
&lt;p&gt;When a &lt;code&gt;click&lt;/code&gt; event happens, Alpine will call the associated JavaScript expression, &lt;code&gt;count++&lt;/code&gt; in our case. As you can see, we have direct access to data declared in the &lt;code&gt;x-data&lt;/code&gt; expression.&lt;/p&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;You will often see &lt;code&gt;@&lt;/code&gt; instead of &lt;code&gt;x-on:&lt;/code&gt;. This is a shorter, friendlier syntax that many prefer. From now on, this documentation will likely use &lt;code&gt;@&lt;/code&gt; instead of &lt;code&gt;x-on:&lt;/code&gt;.&lt;/p&gt; 
&lt;/blockquote&gt; 
&lt;h3&gt;Reacting to changes&lt;/h3&gt; 
&lt;pre&gt;&lt;code class=&quot;language-alpine&quot;&gt;&amp;lt;span x-text=&quot;count&quot;&amp;gt;&amp;lt;/span&amp;gt;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;&lt;code&gt;x-text&lt;/code&gt; is an Alpine directive you can use to set the text content of an element to the result of a JavaScript expression.&lt;/p&gt; 
&lt;p&gt;In this case, we&apos;re telling Alpine to always make sure that the contents of this &lt;code&gt;span&lt;/code&gt; tag reflect the value of the &lt;code&gt;count&lt;/code&gt; property.&lt;/p&gt; 
&lt;p&gt;In case it&apos;s not clear, &lt;code&gt;x-text&lt;/code&gt;, like most directives accepts a plain JavaScript expression as an argument. So for example, you could instead set its contents to: &lt;code&gt;x-text=&quot;count * 2&quot;&lt;/code&gt; and the text content of the &lt;code&gt;span&lt;/code&gt; will now always be 2 times the value of &lt;code&gt;count&lt;/code&gt;.&lt;/p&gt; 
&lt;h2&gt;Building a dropdown&lt;/h2&gt; 
&lt;p&gt;Now that we&apos;ve seen some basic functionality, let&apos;s keep going and look at an important directive in Alpine: &lt;code&gt;x-show&lt;/code&gt;, by building a contrived &quot;dropdown&quot; component.&lt;/p&gt; 
&lt;p&gt;Insert the following code into the &lt;code&gt;&amp;lt;body&amp;gt;&lt;/code&gt; tag:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-alpine&quot;&gt;&amp;lt;div x-data=&quot;{ open: false }&quot;&amp;gt;
    &amp;lt;button @click=&quot;open = ! open&quot;&amp;gt;Toggle&amp;lt;/button&amp;gt;

    &amp;lt;div x-show=&quot;open&quot; @click.outside=&quot;open = false&quot;&amp;gt;Contents...&amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;If you load this component, you should see that the &quot;Contents...&quot; are hidden by default. You can toggle showing them on the page by clicking the &quot;Toggle&quot; button.&lt;/p&gt; 
&lt;p&gt;The &lt;code&gt;x-data&lt;/code&gt; and &lt;code&gt;x-on&lt;/code&gt; directives should be familiar to you from the previous example, so we&apos;ll skip those explanations.&lt;/p&gt; 
&lt;h3&gt;Toggling elements&lt;/h3&gt; 
&lt;pre&gt;&lt;code class=&quot;language-alpine&quot;&gt;&amp;lt;div x-show=&quot;open&quot; ...&amp;gt;Contents...&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;&lt;code&gt;x-show&lt;/code&gt; is an extremely powerful directive in Alpine that can be used to show and hide a block of HTML on a page based on the result of a JavaScript expression, in our case: &lt;code&gt;open&lt;/code&gt;.&lt;/p&gt; 
&lt;p&gt;&lt;a name=&quot;listening-for-a-click-outside&quot;&gt;&lt;/a&gt;&lt;/p&gt; 
&lt;h3&gt;Listening for a click outside&lt;/h3&gt; 
&lt;pre&gt;&lt;code class=&quot;language-alpine&quot;&gt;&amp;lt;div ... @click.outside=&quot;open = false&quot;&amp;gt;Contents...&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;You&apos;ll notice something new in this example: &lt;code&gt;.outside&lt;/code&gt;. Many directives in Alpine accept &quot;modifiers&quot; that are chained onto the end of the directive and are separated by periods.&lt;/p&gt; 
&lt;p&gt;In this case, &lt;code&gt;.outside&lt;/code&gt; tells Alpine to instead of listening for a click INSIDE the &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt;, to listen for the click only if it happens OUTSIDE the &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt;.&lt;/p&gt; 
&lt;p&gt;This is a convenience helper built into Alpine because this is a common need and implementing it by hand is annoying and complex.&lt;/p&gt; 
&lt;h2&gt;Building a search input&lt;/h2&gt; 
&lt;p&gt;Let&apos;s now build a more complex component and introduce a handful of other directives and patterns.&lt;/p&gt; 
&lt;p&gt;Insert the following code into the &lt;code&gt;&amp;lt;body&amp;gt;&lt;/code&gt; tag:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-alpine&quot;&gt;&amp;lt;div
    x-data=&quot;{
        search: &apos;&apos;,

        items: [&apos;foo&apos;, &apos;bar&apos;, &apos;baz&apos;],

        get filteredItems() {
            return this.items.filter(
                i =&amp;gt; i.startsWith(this.search)
            )
        }
    }&quot;
&amp;gt;
    &amp;lt;input x-model=&quot;search&quot; placeholder=&quot;Search...&quot;&amp;gt;

    &amp;lt;ul&amp;gt;
        &amp;lt;template x-for=&quot;item in filteredItems&quot; :key=&quot;item&quot;&amp;gt;
            &amp;lt;li x-text=&quot;item&quot;&amp;gt;&amp;lt;/li&amp;gt;
        &amp;lt;/template&amp;gt;
    &amp;lt;/ul&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;By default, all of the &quot;items&quot; (foo, bar, and baz) will be shown on the page, but you can filter them by typing into the text input. As you type, the list of items will change to reflect what you&apos;re searching for.&lt;/p&gt; 
&lt;p&gt;Now there&apos;s quite a bit happening here, so let&apos;s go through this snippet piece by piece.&lt;/p&gt; 
&lt;p&gt;&lt;a name=&quot;multi-line-formatting&quot;&gt;&lt;/a&gt;&lt;/p&gt; 
&lt;h3&gt;Multi line formatting&lt;/h3&gt; 
&lt;p&gt;The first thing I&apos;d like to point out is that &lt;code&gt;x-data&lt;/code&gt; now has a lot more going on in it than before. To make it easier to write and read, we&apos;ve split it up into multiple lines in our HTML. This is completely optional and we&apos;ll talk more in a bit about how to avoid this problem altogether, but for now, we&apos;ll keep all of this JavaScript directly in the HTML.&lt;/p&gt; 
&lt;h3&gt;Binding to inputs&lt;/h3&gt; 
&lt;pre&gt;&lt;code class=&quot;language-alpine&quot;&gt;&amp;lt;input x-model=&quot;search&quot; placeholder=&quot;Search...&quot;&amp;gt;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;You&apos;ll notice a new directive we haven&apos;t seen yet: &lt;code&gt;x-model&lt;/code&gt;.&lt;/p&gt; 
&lt;p&gt;&lt;code&gt;x-model&lt;/code&gt; is used to &quot;bind&quot; the value of an input element with a data property: &quot;search&quot; from &lt;code&gt;x-data=&quot;{ search: &apos;&apos;, ... }&quot;&lt;/code&gt; in our case.&lt;/p&gt; 
&lt;p&gt;This means that anytime the value of the input changes, the value of &quot;search&quot; will change to reflect that.&lt;/p&gt; 
&lt;p&gt;&lt;code&gt;x-model&lt;/code&gt; is capable of much more than this simple example.&lt;/p&gt; 
&lt;p&gt;&lt;a name=&quot;computed-properties-using-getters&quot;&gt;&lt;/a&gt;&lt;/p&gt; 
&lt;h3&gt;Computed properties using getters&lt;/h3&gt; 
&lt;p&gt;The next bit I&apos;d like to draw your attention to is the &lt;code&gt;items&lt;/code&gt; and &lt;code&gt;filteredItems&lt;/code&gt; properties from the &lt;code&gt;x-data&lt;/code&gt; directive.&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-js&quot;&gt;{
    ...
    items: [&apos;foo&apos;, &apos;bar&apos;, &apos;baz&apos;],

    get filteredItems() {
        return this.items.filter(
            i =&amp;gt; i.startsWith(this.search)
        )
    }
}
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;The &lt;code&gt;items&lt;/code&gt; property should be self-explanatory. Here we are setting the value of &lt;code&gt;items&lt;/code&gt; to a JavaScript array of 3 different items (foo, bar, and baz).&lt;/p&gt; 
&lt;p&gt;The interesting part of this snippet is the &lt;code&gt;filteredItems&lt;/code&gt; property.&lt;/p&gt; 
&lt;p&gt;Denoted by the &lt;code&gt;get&lt;/code&gt; prefix for this property, &lt;code&gt;filteredItems&lt;/code&gt; is a &quot;getter&quot; property in this object. This means we can access &lt;code&gt;filteredItems&lt;/code&gt; as if it was a normal property in our data object, but when we do, JavaScript will evaluate the provided function under the hood and return the result.&lt;/p&gt; 
&lt;p&gt;It&apos;s completely acceptable to forgo the &lt;code&gt;get&lt;/code&gt; and just make this a method that you can call from the template, but some prefer the nicer syntax of the getter.&lt;/p&gt; 
&lt;p&gt;Now let&apos;s look inside the &lt;code&gt;filteredItems&lt;/code&gt; getter and make sure we understand what&apos;s going on there:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-js&quot;&gt;return this.items.filter(
    i =&amp;gt; i.startsWith(this.search)
)
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;This is all plain JavaScript. We are first getting the array of items (foo, bar, and baz) and filtering them using the provided callback: &lt;code&gt;i =&amp;gt; i.startsWith(this.search)&lt;/code&gt;.&lt;/p&gt; 
&lt;p&gt;By passing in this callback to &lt;code&gt;filter&lt;/code&gt;, we are telling JavaScript to only return the items that start with the string: &lt;code&gt;this.search&lt;/code&gt;, which like we saw with &lt;code&gt;x-model&lt;/code&gt; will always reflect the value of the input.&lt;/p&gt; 
&lt;p&gt;You may notice that up until now, we haven&apos;t had to use &lt;code&gt;this.&lt;/code&gt; to reference properties. However, because we are working directly inside the &lt;code&gt;x-data&lt;/code&gt; object, we must reference any properties using &lt;code&gt;this.[property]&lt;/code&gt; instead of simply &lt;code&gt;[property]&lt;/code&gt;.&lt;/p&gt; 
&lt;p&gt;Because Alpine is a &quot;reactive&quot; framework. Any time the value of &lt;code&gt;this.search&lt;/code&gt; changes, parts of the template that use &lt;code&gt;filteredItems&lt;/code&gt; will automatically be updated.&lt;/p&gt; 
&lt;p&gt;&lt;a name=&quot;looping-elements&quot;&gt;&lt;/a&gt;&lt;/p&gt; 
&lt;h3&gt;Looping elements&lt;/h3&gt; 
&lt;p&gt;Now that we understand the data part of our component, let&apos;s understand what&apos;s happening in the template that allows us to loop through &lt;code&gt;filteredItems&lt;/code&gt; on the page.&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-alpine&quot;&gt;&amp;lt;ul&amp;gt;
    &amp;lt;template x-for=&quot;item in filteredItems&quot;&amp;gt;
        &amp;lt;li x-text=&quot;item&quot;&amp;gt;&amp;lt;/li&amp;gt;
    &amp;lt;/template&amp;gt;
&amp;lt;/ul&amp;gt;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;The first thing to notice here is the &lt;code&gt;x-for&lt;/code&gt; directive. &lt;code&gt;x-for&lt;/code&gt; expressions take the following form: &lt;code&gt;[item] in [items]&lt;/code&gt; where [items] is any array of data, and [item] is the name of the variable that will be assigned to an iteration inside the loop.&lt;/p&gt; 
&lt;p&gt;Also notice that &lt;code&gt;x-for&lt;/code&gt; is declared on a &lt;code&gt;&amp;lt;template&amp;gt;&lt;/code&gt; element and not directly on the &lt;code&gt;&amp;lt;li&amp;gt;&lt;/code&gt;. This is a requirement of using &lt;code&gt;x-for&lt;/code&gt;. It allows Alpine to leverage the existing behavior of &lt;code&gt;&amp;lt;template&amp;gt;&lt;/code&gt; tags in the browser to its advantage.&lt;/p&gt; 
&lt;p&gt;Now any element inside the &lt;code&gt;&amp;lt;template&amp;gt;&lt;/code&gt; tag will be repeated for every item inside &lt;code&gt;filteredItems&lt;/code&gt; and all expressions evaluated inside the loop will have direct access to the iteration variable (&lt;code&gt;item&lt;/code&gt; in this case).&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>appery.io</title>
      <link>https://tedneward.github.io/Research/presentation/apperyio/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/apperyio/index.html</guid>
      	<description>
	&lt;p&gt;&quot;Appery.io is a low-code app development platform that makes it easy to create hybrid mobile apps, web apps and PWAs.&quot;&lt;/p&gt; 
&lt;p&gt;&quot;Use integrated backend services such as cloud database, server-side scripting, authentication, push notifications and more. Instantly import and use these services in the app builder. We offer scalable, reliable and secure infrastructure. Focus on implementing your idea and we will take care of the rest.&quot;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://appery.io/&quot;&gt;Website&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Avalonia</title>
      <link>https://tedneward.github.io/Research/presentation/avalonia/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/avalonia/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://avaloniaui.net/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/AvaloniaUI/Avalonia&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;h2&gt;Articles&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://thenewstack.io/avalonia-an-open-source-option-for-cross-platform-ui-work/&quot;&gt;&quot;Avalonia: An Open-Source Option for Cross-Platform UI Work&quot;&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Blazor</title>
      <link>https://tedneward.github.io/Research/presentation/blazor/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/blazor/index.html</guid>
      	<description>
	&lt;h2&gt;Books&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.telerik.com/campaigns/blazor/wp-beginners-guide-ebook&quot;&gt;Blazor: A Beginner&apos;s Guide&lt;/a&gt; - Ed Charbeneau (PDF) (email address &lt;em&gt;requested&lt;/em&gt;, not required)&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://dotnet.microsoft.com/download/e-book/blazor-for-web-forms-devs/pdf&quot;&gt;Blazor for ASP.NET Web Forms Developers&lt;/a&gt; - Daniel Roth, Jeff Fritz, Taylor Southwick (PDF)&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>CEGUI (Crazy Eddie&apos;s GUI System)</title>
      <link>https://tedneward.github.io/Research/presentation/cegui/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/cegui/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;http://cegui.org.uk/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/cegui/cegui&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>DFlat</title>
      <link>https://tedneward.github.io/Research/presentation/console/dflat/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/console/dflat/index.html</guid>
      	<description>
	&lt;p&gt;Several sources:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/alexfru/dflat20&quot;&gt;Source&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/the-grue/DFlat&quot;&gt;Source&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;He also built a C interpreter using it:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/the-grue/Quincy&quot;&gt;Source&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Chromium OS</title>
      <link>https://tedneward.github.io/Research/platforms/web/chromium-os/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">platforms/web/chromium-os/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.chromium.org/chromium-os/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://www.chromium.org/chromium-os/quick-start-guide/&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Safari (Browser)</title>
      <link>https://tedneward.github.io/Research/platforms/web/safari/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">platforms/web/safari/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://developer.apple.com/safari/resources/&quot;&gt;Website&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Webiny</title>
      <link>https://tedneward.github.io/Research/platforms/webiny/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">platforms/webiny/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.webiny.com/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/webiny/webiny-js&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Windows (OS)</title>
      <link>https://tedneward.github.io/Research/platforms/windows/index/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">platforms/windows/index/index.html</guid>
      	<description>
	&lt;h2&gt;Reading&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.zdnet.com/article/how-to-upgrade-your-incompatible-windows-10-pc-to-windows-11-now/&quot;&gt;&quot;How to upgrade your Incompatible Windows 10 PC to Windows 11 Now&quot;&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.makeuseof.com/windows-11-create-bootable-usb-drive/&quot;&gt;&quot;Create a bootable Windows USB&quot;&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;WSL&lt;/h2&gt; 
&lt;p&gt;&lt;a href=&quot;https://x410.dev/&quot;&gt;XWindows for WSL subsystem&lt;/a&gt;: Commercial&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://www.jeremymorgan.com/tutorials/linux/customize-wsl-terminal/&quot;&gt;How to customize WSL Terminal&lt;/a&gt;&lt;/p&gt; 
&lt;h2&gt;Development&lt;/h2&gt; 
&lt;p&gt;&lt;a href=&quot;http://dada.perl.it/shootout/&quot;&gt;The Great Win32 Computer Language Shootout&lt;/a&gt;&lt;/p&gt; 
&lt;h2&gt;Package Managers&lt;/h2&gt; 
&lt;p&gt;UniGetUI:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.xda-developers.com/unigetui-hands-on-ultimate-package-manager/&quot;&gt;&quot;UniGetUI is the ultimate package manager for Windows PCs&quot;&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;winget:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.xda-developers.com/how-use-winget-windows-11/&quot;&gt;&quot;How to use winget&quot;&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Wine</title>
      <link>https://tedneward.github.io/Research/platforms/wine/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">platforms/wine/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.winehq.org/&quot;&gt;Website&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Wine (originally an acronym for &quot;Wine Is Not an Emulator&quot;) is a compatibility layer capable of running Windows applications on several POSIX-compliant operating systems, such as Linux, macOS, &amp;amp; BSD. Instead of simulating internal Windows logic like a virtual machine or emulator, Wine translates Windows API calls into POSIX calls on-the-fly, eliminating the performance and memory penalties of other methods and allowing you to cleanly integrate Windows applications into your desktop.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Yaade</title>
      <link>https://tedneward.github.io/Research/platforms/yaade/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">platforms/yaade/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/EsperoTech/yaade&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Compare to &lt;a href=&quot;/platforms/hoppscotch&quot;&gt;Hoppscotch&lt;/a&gt;.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Ace Editor</title>
      <link>https://tedneward.github.io/Research/presentation/ace/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/ace/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://ace.c9.io/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/ajaxorg/ace&quot;&gt;Source&lt;/a&gt; | &lt;a href=&quot;https://ace.c9.io/build/kitchen-sink.html&quot;&gt;Kitchen sink demo&lt;/a&gt;&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Syntax highlighting for over 110 languages (TextMate/Sublime Text.tmlanguage files can be imported)&lt;/li&gt; 
 &lt;li&gt;Over 20 themes (TextMate/Sublime Text .tmtheme files can be imported)&lt;/li&gt; 
 &lt;li&gt;Automatic indent and outdent&lt;/li&gt; 
 &lt;li&gt;An optional command line&lt;/li&gt; 
 &lt;li&gt;Handles huge documents (four million lines seems to be the limit!)&lt;/li&gt; 
 &lt;li&gt;Fully customizable key bindings including vim and Emacs modes&lt;/li&gt; 
 &lt;li&gt;Search and replace with regular expressions&lt;/li&gt; 
 &lt;li&gt;Highlight matching parentheses&lt;/li&gt; 
 &lt;li&gt;Toggle between soft tabs and real tabs&lt;/li&gt; 
 &lt;li&gt;Displays hidden characters&lt;/li&gt; 
 &lt;li&gt;Drag and drop text using the mouse&lt;/li&gt; 
 &lt;li&gt;Line wrapping&lt;/li&gt; 
 &lt;li&gt;Code folding&lt;/li&gt; 
 &lt;li&gt;Multiple cursors and selections&lt;/li&gt; 
 &lt;li&gt;Live syntax checker (currently JavaScript/CoffeeScript/CSS/XQuery)&lt;/li&gt; 
 &lt;li&gt;Cut, copy, and paste functionality&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Angular</title>
      <link>https://tedneward.github.io/Research/presentation/angular/index/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/angular/index/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://angular.dev/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/angular/angular.js&quot;&gt;Source&lt;/a&gt; | &lt;a href=&quot;https://angular.io/docs&quot;&gt;Docs&lt;/a&gt; | &lt;a href=&quot;https://angular.io/tutorial&quot;&gt;Tutorial&lt;/a&gt;&lt;/p&gt; 
&lt;h2&gt;Reading&lt;/h2&gt; 
&lt;h2&gt;Resources&lt;/h2&gt; 
&lt;p&gt;&lt;a href=&quot;https://www.forms-angular.org/#/&quot;&gt;forms-angular&lt;/a&gt; &lt;a href=&quot;https://github.com/forms-angular/forms-angular&quot;&gt;Source&lt;/a&gt;: Form generator for Angular/MEAN&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Arc (browser)</title>
      <link>https://tedneward.github.io/Research/presentation/arc/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/arc/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://arc.net/&quot;&gt;Website&lt;/a&gt; | Appears to be closed-source?&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Backbone</title>
      <link>https://tedneward.github.io/Research/presentation/backbone/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/backbone/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://backbonejs.org/&quot;&gt;Website&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Caffeine</title>
      <link>https://tedneward.github.io/Research/presentation/caffeine/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/caffeine/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://caffeine.js.org/&quot;&gt;Website&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>CFML (nee Cold Fusion Markup Language)</title>
      <link>https://tedneward.github.io/Research/presentation/cfml/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/cfml/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.adobe.com/products/coldfusion-family.html&quot;&gt;Adobe ColdFusion&lt;/a&gt; | &lt;a href=&quot;https://helpx.adobe.com/coldfusion/developing-applications/the-cfml-programming-language.html&quot;&gt;Adobe CFML reference&lt;/a&gt;&lt;/p&gt; 
&lt;h1&gt;Implementations&lt;/h1&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.lucee.org/&quot;&gt;Lucee&lt;/a&gt; (&lt;a href=&quot;https://github.com/lucee&quot;&gt;Source&lt;/a&gt;): a high performance, open source, ColdFusion / CFML server engine, written in Java.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/OpenBD&quot;&gt;OpenBD&lt;/a&gt;: The original open source Java powered GPL CFML runtime engine. (Archived)&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Chromium</title>
      <link>https://tedneward.github.io/Research/platforms/web/chromium/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">platforms/web/chromium/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.chromium.org/Home/&quot;&gt;Chromium&lt;/a&gt; | &lt;a href=&quot;https://chromium.googlesource.com/chromium/src.git&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>WebVM</title>
      <link>https://tedneward.github.io/Research/platforms/web/webvm/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">platforms/web/webvm/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://webvm.io/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/leaningtech/webvm&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Cairo Shell</title>
      <link>https://tedneward.github.io/Research/platforms/windows/cairoshell/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">platforms/windows/cairoshell/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://cairoshell.com/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/cairoshell/cairoshell&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Windows Internals</title>
      <link>https://tedneward.github.io/Research/platforms/windows/internals/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">platforms/windows/internals/index.html</guid>
      	<description>
	&lt;h2&gt;Reading&lt;/h2&gt; 
&lt;h3&gt;Books&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;Windows Internals, 7th Ed: &lt;a href=&quot;https://www.microsoftpressstore.com/store/windows-internals-part-1-system-architecture-processes-9780735684188&quot;&gt;Part 1&lt;/a&gt; and &lt;a href=&quot;https://www.microsoftpressstore.com/store/windows-internals-part-2-9780135462409&quot;&gt;Part 2&lt;/a&gt; | &lt;a href=&quot;https://github.com/zodiacon/WindowsInternals&quot;&gt;Source&lt;/a&gt; - The Bible on the Windows OS, hands down&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Articles&lt;/h3&gt; 
&lt;h3&gt;Websites&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://learn.microsoft.com/en-us/sysinternals/&quot;&gt;Sysinternals&lt;/a&gt; | &lt;a href=&quot;https://learn.microsoft.com/en-us/sysinternals/downloads/&quot;&gt;Downloads&lt;/a&gt;: AccessChk, AccessEnum, AdExplorer, AdInsight, AdRestore, Autologon, Autoruns, BgInfo, BlueScreen, CacheSet, ClockRes, Contig, Coreinfo, Ctrl2Cap, DebugView, Desktops, Disk2vhd, DiskExt, DiskMon, DiskView, Disk Usage (DU), EFSDump, FindLinks, Handle, Hex2dec, Junction, LDMDump, ListDLLs, LiveKd, LoadOrder, LogonSessions, MoveFile, NotMyFault, NTFSInfo, PendMoves, PipeList, PortMon, ProcDump, Process Explorer, Process Monitor, PsExec, PsFile, PsGetSid, PsInfo, PsKill, PsList, PsLoggedOn, PsLogList, PsPasswd, PsPing, PsService, PsShutdown, PsSuspend, PsTools, RAMMap, RDCMan, RegDelNull, RegHide, RegJump, Registry Usage (RU), SDelete, ShareEnum, ShellRunas, Sigcheck, Streams, Strings, Sync, Sysmon, TCPView, VMMap, VolumeID, WhoIs, WinObj, ZoomIt&lt;/li&gt; 
&lt;/ul&gt; 
&lt;hr&gt; 
&lt;h1&gt;Notes&lt;/h1&gt; 
&lt;h2&gt;Concepts and Tools&lt;/h2&gt; 
&lt;h2&gt;System Architecture&lt;/h2&gt; 
&lt;h2&gt;Processes and Jobs&lt;/h2&gt; 
&lt;h2&gt;Threads&lt;/h2&gt; 
&lt;h2&gt;Memory Management&lt;/h2&gt; 
&lt;h2&gt;I/O System&lt;/h2&gt; 
&lt;h2&gt;Security&lt;/h2&gt; 
&lt;h2&gt;System mechanisms&lt;/h2&gt; 
&lt;h2&gt;Virtualization technologies&lt;/h2&gt; 
&lt;h2&gt;Management, diagnostics, and tracing&lt;/h2&gt; 
&lt;h2&gt;Caching and file systems&lt;/h2&gt; 
&lt;h2&gt;Startup and shutdown&lt;/h2&gt;
	</description>
    </item>
    <item>
      <title>xlang</title>
      <link>https://tedneward.github.io/Research/platforms/xlang/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">platforms/xlang/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/microsoft/xlang&quot;&gt;Github&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Yao</title>
      <link>https://tedneward.github.io/Research/platforms/yao/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">platforms/yao/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://yaoapps.com/en-US&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/YaoApp/yao&quot;&gt;Source&lt;/a&gt; (Golang) | &lt;a href=&quot;https://yaoapps.com/en-US/doc/a.Introduction/a.Getting%20Started&quot;&gt;Docs&lt;/a&gt; | Demos: &lt;a href=&quot;https://demo-crm.yaoapps.com&quot;&gt;Customer Relationship Management System&lt;/a&gt;: A Customer Relationship Management System; &lt;a href=&quot;https://demo-wms.yaoapps.com&quot;&gt;Intelligent warehouse management system&lt;/a&gt;: An example of cloud + edge IoT application, an unattended intelligent warehouse management system that supports face recognition and RFID.&lt;/p&gt; 
&lt;h2&gt;Features&lt;/h2&gt; 
&lt;p&gt;No Code: Using JSON to create database model, write interface and describe interface is really codeless programming.&lt;/p&gt; 
&lt;p&gt;IoT: Yao supports running on ARM devices and can be used in IoT, edge computing, industrial Internet.&lt;/p&gt; 
&lt;p&gt;Business Intelligence: Easy-to-use BI components and functions, empowering business with more possibilities.&lt;/p&gt; 
&lt;p&gt;Processes: Yao has many built-in processes, and a series of processes that can be created by data flow, Javascirpt, and GRPC plugin.&lt;/p&gt; 
&lt;p&gt;Dataflow: Through data flow, developers can process data in any form and support JavaScript.&lt;/p&gt; 
&lt;p&gt;Plugins: The plug-in mechanism based on grpc supports function expansion using Nodejs, Python and other languages.&lt;/p&gt; 
&lt;p&gt;Dashboard: By writing JSON description interface layout to build various CRM, ERP, and other enterprise internal systems.&lt;/p&gt; 
&lt;p&gt;File System Routing: Every file in the apis folder will become an interface that can be called, this will be helpful for large scale project.&lt;/p&gt; 
&lt;p&gt;Query Engine: Built in query engine comparable to es, and JSON query is realized through DSL, which is simple and easy to use.&lt;/p&gt; 
&lt;p&gt;Performance: The performance is far better than that of Java and PHP. It is distributed and can be done with one line of command.&lt;/p&gt; 
&lt;p&gt;Enterprise Security: Permission classification, separation of administrator and employee accounts, API level permission control.&lt;/p&gt; 
&lt;p&gt;Natural Distribution: Generating binary files for various platforms, which is very convenient for users who need to go to the cloud.&lt;/p&gt; 
&lt;p&gt;&quot;Yao allows developers to create web services by processes. Yao is a low-code engine that creates a database model, writes API services, and describes dashboard interface just by JSON for web &amp;amp; hardware, no code, and 10x productivity. Yao is based on the flow-based programming idea, developed in the Go language, and supports multiple ways to expand the data stream processor. This makes Yao extremely versatile, which can replace programming languages ​​in most scenarios, and is 10 times more efficient than traditional programming languages ​​in terms of reusability and coding efficiency; application performance and resource ratio Better than PHP, JAVA and other languages.&lt;/p&gt; 
&lt;p&gt;&quot;Yao has a built-in data management system. By writing JSON to describe the interface layout, 90% of the common interface interaction functions can be realized. It is especially suitable for quickly making various management background, CRM, ERP and other internal enterprise systems. Special interactive functions can also be implemented by writing extension components or HTML pages. The built-in management system is not coupled with Yao, and any front-end technologies such as VUE and React can be used to implement the management interface.&quot;&lt;/p&gt; 
&lt;h4&gt;Install&lt;/h4&gt; 
&lt;p&gt;Run the script under terminal: (MacOS/Linux) &lt;code&gt;curl -fsSL https://website.yaoapps.com/install.sh | bash&lt;/code&gt;&lt;/p&gt; 
&lt;h4&gt;Step 1: Create a project&lt;/h4&gt; 
&lt;p&gt;Create a new project directory, enter the project directory, and run the yao init command to create a blank Yao application.&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;mkdir -p /data/crm # create project directory
cd /data/crm # Enter the project directory
yao init # run the initializer
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;After the command runs successfully, the app.json file , db, ui , data and other directories will be created&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;├── data # Used to store files generated by the application, such as pictures, PDFs, etc.
├── db # Used to store SQLite database files
│ └── yao.db
└── ui # The static file server file directory, where custom front-end products can be placed. The files in this directory can be accessed through http://host:port/filename .
└── app.json # Application configuration file, used to define the application name, etc.
&lt;/code&gt;&lt;/pre&gt; 
&lt;h4&gt;Step 2: Create the data table&lt;/h4&gt; 
&lt;p&gt;Use the yao migrate command to create the data table, open the command line terminal, run in the project root directory:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;yao migrate
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;initialization menu&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;yao run flows.setmenu
&lt;/code&gt;&lt;/pre&gt; 
&lt;h4&gt;Step 3: Start the service&lt;/h4&gt; 
&lt;p&gt;Open a command line terminal, run &lt;code&gt;yao start&lt;/code&gt; in the project root directory. Open a browser, visit &lt;a href=&quot;https://127.0.0.1:5099/xiang/login/admin&quot;&gt;https://127.0.0.1:5099/xiang/login/admin&lt;/a&gt;, Enter the default username: &lt;a href=&quot;mailto:xiang@iqka.com&quot;&gt;xiang@iqka.com&lt;/a&gt;, password: A123456p+&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Affine</title>
      <link>https://tedneward.github.io/Research/presentation/affine/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/affine/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://affine.pro/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/toeverything/AFFiNE&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>AnimeJS</title>
      <link>https://tedneward.github.io/Research/presentation/animejs/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/animejs/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://animejs.com/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/juliangarnier/anime&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Astro</title>
      <link>https://tedneward.github.io/Research/presentation/astro/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/astro/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://astro.build/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/withastro/astro&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Claims a &quot;new&quot; frontend architecture called &lt;a href=&quot;https://docs.astro.build/en/concepts/islands/&quot;&gt;Islands&lt;/a&gt;:&lt;/p&gt; 
&lt;p&gt;&quot;The term “component island” was first coined by Etsy’s frontend architect Katie Sylor-Miller in 2019. This idea was then expanded on and documented in this post by Preact creator Jason Miller on August 11, 2020.&lt;/p&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;The general idea of an “Islands” architecture is deceptively simple: render HTML pages on the server, and inject placeholders or slots around highly dynamic regions […] that can then be “hydrated” on the client into small self-contained widgets, reusing their server-rendered initial HTML.&lt;br&gt; — Jason Miller, Creator of Preact&lt;/p&gt; 
&lt;/blockquote&gt; 
&lt;p&gt;&quot;The technique that this architectural pattern builds on is also known as partial or selective hydration.&lt;/p&gt; 
&lt;p&gt;&quot;In contrast, most JavaScript-based web frameworks hydrate &amp;amp; render an entire website as one large JavaScript application (also known as a single-page application, or SPA). SPAs provide simplicity and power but suffer from page-load performance problems due to heavy client-side JavaScript usage.&lt;/p&gt; 
&lt;p&gt;&quot;SPAs have their place, even embedded inside an Astro page. But, SPAs lack the native ability to selectively and strategically hydrate, making them a heavy-handed choice for most projects on the web today.&lt;/p&gt; 
&lt;p&gt;&quot;Astro became popular as the first mainstream JavaScript web framework with selective hydration built-in, using that component islands pattern first coined by Sylor-Miller.&quot;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>BaklavaJS</title>
      <link>https://tedneward.github.io/Research/presentation/baklavajs/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/baklavajs/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://baklava.tech/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/newcat/baklavajs&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>CapacitorJS</title>
      <link>https://tedneward.github.io/Research/presentation/capacitorjs/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/capacitorjs/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://capacitorjs.com/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/ionic-team/capacitor&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;99% backward compatibility with Cordova.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Chart.js</title>
      <link>https://tedneward.github.io/Research/presentation/chartjs/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/chartjs/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.chartjs.org/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/chartjs/Chart.js&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Firefox (browser)</title>
      <link>https://tedneward.github.io/Research/platforms/web/firefox/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">platforms/web/firefox/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Tools&quot;&gt;Website&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Web Worker API</title>
      <link>https://tedneward.github.io/Research/platforms/web/webworkers/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">platforms/web/webworkers/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API&quot;&gt;MDN Specification&lt;/a&gt;&lt;/p&gt; 
&lt;h1&gt;Notes&lt;/h1&gt; 
&lt;ul&gt; 
 &lt;li&gt;Creating a worker is done by calling the &lt;code&gt;Worker(&quot;path/to/worker/script&quot;)&lt;/code&gt; constructor.&lt;/li&gt; 
 &lt;li&gt;Workers have no access to the page-specific objects/APIs (like &lt;code&gt;document&lt;/code&gt;, etc)&lt;/li&gt; 
 &lt;li&gt;We can send data back and forth between the main application and our worker script. Calling the &lt;code&gt;postMessage()&lt;/code&gt; function can send JSON, Strings, numbers, and/or arrays. &lt;pre&gt;&lt;code&gt;//main.js
worker.postMessage(&quot;hello world&quot;); // Send this to the worker script.

//worker.js
postMessage(&quot;hi from worker&quot;); // Send this back to the main script.
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;We need to add event listeners to both sides to receive the messages above. We can either use onmessage or addEventListener.&lt;/p&gt; &lt;pre&gt;&lt;code&gt;//worker.js
self.addEventListener(&apos;message&apos;, function(e) {
// Send the message back.
self.postMessage(&apos;You said: &apos; + e.data);
}, false);
&lt;/code&gt;&lt;/pre&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;Note that we use self for the worker to give a global reference to web workers because it is not a window object.&lt;/p&gt; 
&lt;p&gt;Event listener in the main script:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;    //main.js
    let worker = new Worker(&apos;worker.js&apos;);
    worker.addEventListener(&apos;message&apos;, function(e) {
    // Log the workers message.
    console.log(e.data);
    }, false);
&lt;/code&gt;&lt;/pre&gt; 
&lt;h1&gt;MDN Reference: Functions and classes available to Web Workers&lt;/h1&gt; 
&lt;p&gt;The following functions are available to workers:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;WorkerGlobalScope.atob()&lt;/li&gt; 
 &lt;li&gt;WorkerGlobalScope.btoa()&lt;/li&gt; 
 &lt;li&gt;WorkerGlobalScope.clearInterval()&lt;/li&gt; 
 &lt;li&gt;WorkerGlobalScope.clearTimeout()&lt;/li&gt; 
 &lt;li&gt;WorkerGlobalScope.createImageBitmap()&lt;/li&gt; 
 &lt;li&gt;WorkerGlobalScope.dump() Non-standard&lt;/li&gt; 
 &lt;li&gt;WorkerGlobalScope.fetch()&lt;/li&gt; 
 &lt;li&gt;WorkerGlobalScope.queueMicrotask()&lt;/li&gt; 
 &lt;li&gt;WorkerGlobalScope.reportError()&lt;/li&gt; 
 &lt;li&gt;WorkerGlobalScope.setInterval()&lt;/li&gt; 
 &lt;li&gt;WorkerGlobalScope.setTimeout()&lt;/li&gt; 
 &lt;li&gt;WorkerGlobalScope.structuredClone()&lt;/li&gt; 
 &lt;li&gt;DedicatedWorkerGlobalScope.postMessage() (dedicated workers only)&lt;/li&gt; 
 &lt;li&gt;DedicatedWorkerGlobalScope.requestAnimationFrame() (dedicated workers only)&lt;/li&gt; 
 &lt;li&gt;DedicatedWorkerGlobalScope.cancelAnimationFrame() (dedicated workers only)&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;The following functions are only available to workers:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;WorkerGlobalScope.importScripts()&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;The following Web APIs are available to workers:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Background Fetch API&lt;/li&gt; 
 &lt;li&gt;Background Synchronization API&lt;/li&gt; 
 &lt;li&gt;Barcode Detection API&lt;/li&gt; 
 &lt;li&gt;Broadcast Channel API&lt;/li&gt; 
 &lt;li&gt;Canvas API&lt;/li&gt; 
 &lt;li&gt;Channel Messaging API&lt;/li&gt; 
 &lt;li&gt;Compression Streams API&lt;/li&gt; 
 &lt;li&gt;Compute Pressure API&lt;/li&gt; 
 &lt;li&gt;Console API&lt;/li&gt; 
 &lt;li&gt;Content Index API&lt;/li&gt; 
 &lt;li&gt;Cookie Store API (service workers only)&lt;/li&gt; 
 &lt;li&gt;CSS Font Loading API&lt;/li&gt; 
 &lt;li&gt;Encoding API&lt;/li&gt; 
 &lt;li&gt;Fetch API&lt;/li&gt; 
 &lt;li&gt;File API&lt;/li&gt; 
 &lt;li&gt;File System API&lt;/li&gt; 
 &lt;li&gt;Idle Detection API&lt;/li&gt; 
 &lt;li&gt;IndexedDB API&lt;/li&gt; 
 &lt;li&gt;Media Capabilities API&lt;/li&gt; 
 &lt;li&gt;Media Source Extensions API (dedicated workers only)&lt;/li&gt; 
 &lt;li&gt;Network Information API&lt;/li&gt; 
 &lt;li&gt;Notifications API&lt;/li&gt; 
 &lt;li&gt;Payment Handler API&lt;/li&gt; 
 &lt;li&gt;Performance API&lt;/li&gt; 
 &lt;li&gt;Permissions API&lt;/li&gt; 
 &lt;li&gt;Prioritized Task Scheduling API&lt;/li&gt; 
 &lt;li&gt;Push API&lt;/li&gt; 
 &lt;li&gt;Reporting API&lt;/li&gt; 
 &lt;li&gt;Server-Sent Events&lt;/li&gt; 
 &lt;li&gt;Service Worker API&lt;/li&gt; 
 &lt;li&gt;Streams API&lt;/li&gt; 
 &lt;li&gt;Trusted Types API&lt;/li&gt; 
 &lt;li&gt;URL API&lt;/li&gt; 
 &lt;li&gt;URL Pattern API&lt;/li&gt; 
 &lt;li&gt;User-Agent Client Hints API&lt;/li&gt; 
 &lt;li&gt;Web Crypto API&lt;/li&gt; 
 &lt;li&gt;Web Locks API&lt;/li&gt; 
 &lt;li&gt;Web Serial API&lt;/li&gt; 
 &lt;li&gt;Web Periodic Background Synchronization API&lt;/li&gt; 
 &lt;li&gt;WebCodecs API&lt;/li&gt; 
 &lt;li&gt;WebGL API&lt;/li&gt; 
 &lt;li&gt;WebGPU API&lt;/li&gt; 
 &lt;li&gt;WebHID API (dedicated and service workers only)&lt;/li&gt; 
 &lt;li&gt;WebUSB API&lt;/li&gt; 
 &lt;li&gt;WebSockets API&lt;/li&gt; 
 &lt;li&gt;XMLHttpRequest API&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Windows Debugging</title>
      <link>https://tedneward.github.io/Research/platforms/windows/debugging/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">platforms/windows/debugging/index.html</guid>
      	<description>
	&lt;p&gt;Debug Tutorial on CodeProject:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.codeproject.com/Articles/6469/Debug-Tutorial-Part-1-Beginning-Debugging-Using-CD&quot;&gt;Part 1: CDB and NTSD&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.codeproject.com/Articles/6470/Debug-Tutorial-Part-2-The-Stack&quot;&gt;Part 2: the stack&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.codeproject.com/Articles/6489/Debug-Tutorial-Part-3-The-Heap&quot;&gt;Part 3: the heap&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.codeproject.com/Articles/6522/Debug-Tutorial-Part-4-Writing-WINDBG-Extensions&quot;&gt;Part 4: WINDBG extensions&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.codeproject.com/Articles/6988/Debug-Tutorial-Part-5-Handle-Leaks&quot;&gt;Part 5: Handle leaks&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.codeproject.com/Articles/7913/Debug-Tutorial-Part-6-Navigating-The-Kernel-Debugg&quot;&gt;Part 6: Kernel debugging&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.codeproject.com/Articles/7919/Debug-Tutorial-Part-7-Locks-and-Synchronization-Ob&quot;&gt;Part 7: Locks and sync&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;&lt;a href=&quot;https://www.codeproject.com/Articles/6084/Windows-Debuggers-Part-1-A-WinDbg-Tutorial&quot;&gt;Windows Debugger WinDbg Tutorial&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Seleen</title>
      <link>https://tedneward.github.io/Research/platforms/windows/seleen/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">platforms/windows/seleen/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://seelen.io/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/eythaann/seelen-ui&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>XOOM</title>
      <link>https://tedneward.github.io/Research/platforms/xoom/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">platforms/xoom/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://vlingo.io/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/vlingo&quot;&gt;Source&lt;/a&gt; | &lt;a href=&quot;https://docs.vlingo.io/&quot;&gt;Docs&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Collection of libraries and a source-code-generator (XOOM Designer).&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>960 Grid System</title>
      <link>https://tedneward.github.io/Research/presentation/960/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/960/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://960.gs/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;http://github.com/nathansmith/960-grid-system/&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>A-Frame</title>
      <link>https://tedneward.github.io/Research/presentation/aframe/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/aframe/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://aframe.io&quot;&gt;Website&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Ant Design</title>
      <link>https://tedneward.github.io/Research/presentation/antdesign/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/antdesign/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://ant.design/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/ant-design/ant-design/&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Appears to have components for &lt;a href=&quot;https://ng.ant.design/&quot;&gt;Angular&lt;/a&gt;, &lt;a href=&quot;https://ant.design/docs/react/introduce&quot;&gt;React&lt;/a&gt;, and &lt;a href=&quot;https://vue.ant.design/&quot;&gt;Vue&lt;/a&gt;.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Aurelia</title>
      <link>https://tedneward.github.io/Research/presentation/aurelia/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/aurelia/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://aurelia.io/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/aurelia&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>bce.design</title>
      <link>https://tedneward.github.io/Research/presentation/bce/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/bce/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://bce.design/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/adamBien/bce.design&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Quickstarter and sample application for building non-trivial web applications with minimal tooling, essential dependencies, high productivity, and no migrations.&lt;/p&gt; 
&lt;p&gt;Built on web standards and browser APIs - no framework lock-in, just native Web Components, ES modules, and modern JavaScript&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Cappuccino</title>
      <link>https://tedneward.github.io/Research/presentation/cappuccino/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/cappuccino/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.cappuccino.dev/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/cappuccino/cappuccino&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;Cappuccino, a open-source web application framework in Objective-J (a superset of JavaScript which is transpiled for deployment but can also run in the browser directly), enhances app development by faithfully implementing the NeXTSTEP/Apple Cocoa® APIs for browsers as web browser restrictions permit. Leveraging this well-established architecture, Cappuccino facilitates scalable application development for those usage cases requiring developer productivity, reliability and sophisticated interaction support. Resulting applications are served from any web server and deployed to any modern web browser - without plugins or extensions of any kind.&lt;/p&gt; 
&lt;/blockquote&gt;
	</description>
    </item>
    <item>
      <title>CodeMirror</title>
      <link>https://tedneward.github.io/Research/presentation/codemirror/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">presentation/codemirror/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://codemirror.net/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/codemirror/dev/&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>WebAssembly</title>
      <link>https://tedneward.github.io/Research/platforms/wasm/index/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">platforms/wasm/index/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://webassembly.org/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://bytecodealliance.org/&quot;&gt;Bytecode Alliance&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://webassembly.github.io/spec/&quot;&gt;Specifications page&lt;/a&gt; (&lt;a href=&quot;https://github.com/WebAssembly/spec/&quot;&gt;Source&lt;/a&gt;):&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://webassembly.github.io/spec/core/_download/WebAssembly.pdf&quot;&gt;Core&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://webassembly.github.io/spec/js-api/index.html&quot;&gt;JavaScript Embedding&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://webassembly.github.io/spec/web-api/index.html&quot;&gt;Web Embedding&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/WebAssembly/proposals&quot;&gt;Proposals&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://component-model.bytecodealliance.org/introduction.html&quot;&gt;Component model&lt;/a&gt; | &lt;a href=&quot;https://github.com/WebAssembly/component-model&quot;&gt;Source&lt;/a&gt; 
  &lt;ul&gt; 
   &lt;li&gt;IDL (WIT: Wasm Interface Type): &lt;a href=&quot;https://github.com/WebAssembly/component-model/blob/main/design/mvp/WIT.md&quot;&gt;https://github.com/WebAssembly/component-model/blob/main/design/mvp/WIT.md&lt;/a&gt; (reproduced below)&lt;/li&gt; 
   &lt;li&gt;text format: &lt;a href=&quot;https://github.com/WebAssembly/component-model/blob/main/design/mvp/Explainer.md&quot;&gt;https://github.com/WebAssembly/component-model/blob/main/design/mvp/Explainer.md&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;binary format: &lt;a href=&quot;https://github.com/WebAssembly/component-model/blob/main/design/mvp/Binary.md&quot;&gt;https://github.com/WebAssembly/component-model/blob/main/design/mvp/Binary.md&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;concurrency model: &lt;a href=&quot;https://github.com/WebAssembly/component-model/blob/main/design/mvp/Async.md&quot;&gt;https://github.com/WebAssembly/component-model/blob/main/design/mvp/Async.md&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;canonical ABI: &lt;a href=&quot;https://github.com/WebAssembly/component-model/blob/main/design/mvp/CanonicalABI.md&quot;&gt;https://github.com/WebAssembly/component-model/blob/main/design/mvp/CanonicalABI.md&lt;/a&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://wasi.dev/&quot;&gt;WebAssembly System Interface&lt;/a&gt; | &lt;a href=&quot;https://github.com/WebAssembly/WASI/tree/main&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/CommonWA/cwa-spec&quot;&gt;Common WebAssembly&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;Announcements &lt;a href=&quot;https://webassembly.org/news/2025-03-20-wasm-2.0/&quot;&gt;2.0&lt;/a&gt;, &lt;a href=&quot;https://webassembly.org/news/2025-09-17-wasm-3.0/&quot;&gt;3.0&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Features:&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt; &lt;p&gt;3.0&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;64-bit address space.&lt;/strong&gt; Memories and tables can now be declared to use i64 as their address type instead of just i32. That expands the available address space of Wasm applications from 4 gigabytes to (theoretically) 16 exabytes, to the extent that physical hardware allows. While the web will necessarily keep enforcing certain limits — on the web, a 64-bit memory is limited to 16 gigabytes — the new flexibility is especially interesting for non-web ecosystems using Wasm, as they can support much, much larger applications and data sets now.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Multiple memories.&lt;/strong&gt; Contrary to popular belief, Wasm applications were always able to use multiple memory objects — and hence multiple address spaces — simultaneously. However, previously that was only possible by declaring and accessing each of them in separate modules. This gap has been closed, a single module can now declare (define or import) multiple memories and directly access them, including directly copying data between them. This finally allows tools like wasm-merge, which perform “static linking” on two or more Wasm modules by merging them into one, to work for all Wasm modules. It also paves the way for new uses of separate address spaces, e.g., for security (separating private data), for buffering, or for instrumentation.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Garbage collection.&lt;/strong&gt; In addition to expanding the capabilities of raw linear memories, Wasm also adds support for a new (and separate) form of storage that is automatically managed by the Wasm runtime via a garbage collector. Staying true to the spirit of Wasm as a low-level language, Wasm GC is low-level as well: a compiler targeting Wasm can declare the memory layout of its runtime data structures in terms of struct and array types, plus unboxed tagged integers, whose allocation and lifetime is then handled by Wasm. But that’s it. Everything else, such as engineering suitable representations for source-language values, including implementation details like method tables, remains the responsibility of compilers targeting Wasm. There are no built-in object systems, nor closures or other higher-level constructs — which would inevitably be heavily biased towards specific languages. Instead, Wasm only provides the basic building blocks for representing such constructs and focuses purely on the memory management aspect.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Typed references.&lt;/strong&gt; The GC extension is built upon a substantial extension to the Wasm type system, which now supports much richer forms of references. Reference types can now describe the exact shape of the referenced heap value, avoiding additional runtime checks that would otherwise be needed to ensure safety. This more expressive typing mechanism, including subtyping and type recursion, is also available for function references, making it possible to perform safe indirect function calls without any runtime type or bounds check, through the new call_ref instruction.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Tail calls.&lt;/strong&gt; Tail calls are a variant of function calls that immediately exit the current function, and thereby avoid taking up additional stack space. Tail calls are an important mechanism that is used in various language implementations both in user-visible ways (e.g., in functional languages) and for internal techniques (e.g., to implement stubs). Wasm tail calls are fully general and work for callees both selected statically (by function index) and dynamically (by reference or table).&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Exception handling.&lt;/strong&gt; Exceptions provide a way to locally abort execution, and are a common feature in modern programming languages. Previously, there was no efficient way to compile exception handling to Wasm, and existing compilers typically resorted to convoluted ways of implementing them by escaping to the host language, e.g., JavaScript. This was neither portable nor efficient. Wasm 3.0 hence provides native exception handling within Wasm. Exceptions are defined by declaring exception tags with associated payload data. As one would expect, an exception can be thrown, and selectively be caught by a surrounding handler, based on its tag. Exception handlers are a new form of block instruction that includes a dispatch list of tag/label pairs or catch-all labels to define where to jump when an exception occurs.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Relaxed vector instructions.&lt;/strong&gt; Wasm 2.0 added a large set of vector (SIMD) instructions, but due to differences in hardware, some of these instructions have to do extra work on some platforms to achieve the specified semantics. In order to squeeze out maximum performance, Wasm 3.0 introduces “relaxed” variants of these instructions that are allowed to have implementation-dependent behavior in certain edge cases. This behavior must be selected from a pre-specified set of legal choices.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Deterministic profile.&lt;/strong&gt; To make up for the added semantic fuzziness of relaxed vector instructions, and in order to support settings that demand or need deterministic execution semantics (such as blockchains, or replayable systems), the Wasm standard now specifies a deterministic default behavior for every instruction with otherwise non-deterministic results — currently, this includes floating-point operators and their generated NaN values and the aforementioned relaxed vector instructions. Between platforms choosing to implement this deterministic execution profile, Wasm thereby is fully deterministic, reproducible, and portable.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Custom annotation syntax.&lt;/strong&gt; Finally, the Wasm text format has been enriched with generic syntax for placing annotations in Wasm source code. Analogous to custom sections in the binary format, these annotations are not assigned any meaning by the Wasm standard itself, and can be chosen to be ignored by implementations. However, they provide a way to represent the information stored in custom sections in human-readable and writable form, and concrete annotations can be specified by downstream standards.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;In addition to these core features, embeddings of Wasm into JavaScript benefit from a new extension to the JS API:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;strong&gt;JS string builtins.&lt;/strong&gt; JavaScript string values can already be passed to Wasm as externrefs. Functions from this new primitive library can be imported into a Wasm module to directly access and manipulate such external string values inside Wasm.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;With these new features, Wasm has much better support for compiling high-level programming languages. Enabled by this, we have seen various new languages popping up to target Wasm, such as &lt;a href=&quot;https://github.com/google/j2cl/blob/master/docs/getting-started-j2wasm.md&quot;&gt;Java&lt;/a&gt;, &lt;a href=&quot;https://dune.readthedocs.io/en/stable/wasmoo.html&quot;&gt;OCaml&lt;/a&gt;, &lt;a href=&quot;https://www.scala-js.org/doc/project/webassembly.html&quot;&gt;Scala&lt;/a&gt;, &lt;a href=&quot;https://kotlinlang.org/docs/wasm-overview.html&quot;&gt;Kotlin&lt;/a&gt;, &lt;a href=&quot;https://spritely.institute/hoot/&quot;&gt;Scheme&lt;/a&gt;, or &lt;a href=&quot;https://dart.dev/web/wasm&quot;&gt;Dart&lt;/a&gt;, all of which use the new GC feature. On top of all these goodies, Wasm 3.0 also is the first version of the standard that has been produced with the new &lt;a href=&quot;https://webassembly.org/news/2025-03-27-spectec/&quot;&gt;SpecTec&lt;/a&gt; tool chain. We believe that this makes for an even more reliable specification.&lt;/p&gt; 
&lt;h2&gt;Tools&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/WebAssembly/wabt&quot;&gt;WebAssembly Binary Toolkit (wabt)&lt;/a&gt; | &lt;a href=&quot;https://github.com/WebAssembly/binaryen&quot;&gt;binaryen&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/wasm3/wasm-debug&quot;&gt;Wasm Debugger&lt;/a&gt;: Direct, source-level WebAssembly debugger&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/bytecodealliance/wit-bindgen/tree/main/crates/wasmlink&quot;&gt;wasmlink&lt;/a&gt;: a CLI that allows us to statically link a module and its dependencies using &lt;a href=&quot;https://github.com/WebAssembly/module-linking&quot;&gt;module linking&lt;/a&gt; and the &lt;a href=&quot;https://github.com/WebAssembly/interface-types/pull/140&quot;&gt;Canonical Interface Types ABI&lt;/a&gt;.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Examples&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://emuchip.com/&quot;&gt;Chip-8 Emulator&lt;/a&gt; &lt;a href=&quot;https://github.com/Timmoth/EmuChip&quot;&gt;Source&lt;/a&gt;: A lightweight interpreted virtual machine originally designed for 8-bit microcomputers. It features a 4K memory space, 16 8-bit registers, a 64×32 monochrome display, a stack for subroutines, and simple timers for delay and sound. This emulator replicates the CHIP-8 architecture in software, written in C# and compiled into WebAssembly for execution directly in the browser.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/3dgen/cppwasm-book/tree/master/en&quot;&gt;WebAssembly friendly programming with C/C++&lt;/a&gt; - Ending, Chai Shushan, Yushih (HTML, &lt;a href=&quot;https://github.com/3dgen/cppwasm-book/tree/master/examples&quot;&gt;examples&lt;/a&gt;)&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Languages&lt;/h2&gt; 
&lt;p&gt;&lt;a href=&quot;https://github.com/appcypher/awesome-wasm-langs&quot;&gt;Awesome WASM languages&lt;/a&gt;:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt; &lt;p&gt;.NET&lt;/p&gt; 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/RyanLamansky/dotnet-webassembly&quot;&gt;.NET WebAssembly&lt;/a&gt;: Create, read, modify, write and execute WebAssembly (WASM) files from .NET-based applications.&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://andrewlock.net/running-dotnet-in-the-browser-without-blazor/&quot;&gt;&quot;Running .NET in the browser without Blazor&quot;&lt;/a&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/mono/mono/tree/master/sdks/wasm&quot;&gt;Mono&lt;/a&gt; - an open source implementation of Microsoft&apos;s .NET Framework based on the ECMA standards for C# and the Common Language Runtime. For a real-work example, see this repository which contains the &lt;a href=&quot;https://github.com/nventive/calculator&quot;&gt;Windows 10 calculator&lt;/a&gt;. The application is built using standard C++ 11 and C++/CX, with a calculation engine that dates back from 1995. Made by possible with mono via &lt;a href=&quot;https://platform.uno/a-piece-of-windows-10-is-now-running-on-webassembly-natively-on-ios-and-android/&quot;&gt;Uno Platform&lt;/a&gt;.&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://dotnet.microsoft.com/apps/aspnet/web-apps/blazor&quot;&gt;Blazor&lt;/a&gt; - a web UI framework using C#/Razor and HTML, running client-side via WebAssembly. Source is maintained on &lt;a href=&quot;https://github.com/dotnet/aspnetcore&quot;&gt;ASP.Net Core&lt;/a&gt; repo.&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://fsbolero.io/&quot;&gt;Bolero&lt;/a&gt; - Bolero brings Blazor to F# developers with an easy to use Model-View-Update architecture, HTML combinators, hot reloaded templates, type-safe endpoints, advanced routing and remoting capabilities, and more.&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/dotnet/runtimelab/tree/feature/NativeAOT-LLVM&quot;&gt;NativeAOT-LLVM&lt;/a&gt; - an experimental fork of the CoreCLR .NET runtime that compiles .NET applications into single-file executables, with the primary target being WASM&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;a href=&quot;/languages/ada&quot;&gt;Ada&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;/languages/wasm/assemblyscript&quot;&gt;AssemblyScript&lt;/a&gt;: An assembler for WebAssembly.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;/languages/wasm/astro&quot;&gt;Astro&lt;/a&gt;: a fun safe language for rapid prototyping and high performance applications.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;/languages/jvm/ballerina&quot;&gt;Ballerina&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;/languages/basic&quot;&gt;BASIC&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;/languages/berry&quot;&gt;Berry&lt;/a&gt;: an ultra-lightweight dynamically typed embedded scripting language. It&apos;s designed for lower-performance embedded devices, fast, multi-paradigm, simple, flexible, and has very small RAM footprint.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;/languages/esoteric/brainfuck&quot;&gt;Brainfuck&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;/languages/c&quot;&gt;C&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/kign/c4wa&quot;&gt;c4wa&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;/languages/clean&quot;&gt;Clean&lt;/a&gt; - a general purpose, state-of-the-art, pure and lazy functional programming language designed for making real-world applications.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;/languages/co&quot;&gt;Co&lt;/a&gt;: A programming language similar to Go and TypeScript. &lt;a href=&quot;https://github.com/rsms/co&quot;&gt;main repo&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;/languages/cobol&quot;&gt;COBOL&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;/languages/crystal&quot;&gt;Crystal&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;/languages/cyber&quot;&gt;Cyber&lt;/a&gt; - Fast, efficient, and concurrent scripting. Dynamic and gradual types; Concurrency with fibers; Multithreaded; Memory safe; FFI and Embeddable.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;/languages/d&quot;&gt;D&lt;/a&gt; - D is a general-purpose programming language with static typing, systems-level access, and C-like syntax.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;/languages/dart&quot;&gt;Dart&lt;/a&gt; - An approachable, portable, and productive language for high-quality apps on any platform&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;/languages/ecmascript&quot;&gt;Duktape&lt;/a&gt;: embeddable JS engine capable of being run in the browser via WebAssembly&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;/languages/eclair&quot;&gt;Eclair&lt;/a&gt;: Eclair is a minimal, fast Datalog implementation that compiles to LLVM IR and WASM.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;/languages/eel&quot;&gt;Eel&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;/languages/elixir&quot;&gt;Elixir&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;/languages/dotnet/fsharp&quot;&gt;F#&lt;/a&gt;: F# is a mature, open source, cross-platform, functional-first programming language. It empowers users and organizations to tackle complex computing problems with simple, maintainable and robust code. WebAssembly support is achieved through &lt;a href=&quot;https://fsbolero.io/&quot;&gt;Bolero&lt;/a&gt;, a set of free and open-source libraries and tools built on top of &lt;a href=&quot;https://dotnet.microsoft.com/apps/aspnet/web-apps/blazor&quot;&gt;Blazor&lt;/a&gt;.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;/languages/faust&quot;&gt;Faust&lt;/a&gt; - Faust (Functional Audio Stream) is a functional programming language specifically designed for real-time signal processing and synthesis. A distinctive characteristic of Faust is to be fully compiled.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;/languages/forest&quot;&gt;Forest&lt;/a&gt; - a functional programming language that compiles to WebAssembly. The main repo contains the compiler and core syntaxes, currently implemented in Haskell.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;/languages/forth&quot;&gt;Forth&lt;/a&gt; - an interactive, extensible, imperative, untyped, stack-based programming language.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;/languages/go&quot;&gt;Go&lt;/a&gt; - a statically typed compiled language in the tradition of C, with memory safety, garbage collection, structural typing, and CSP-style concurrent programming features added.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;/languages/grain&quot;&gt;Grain&lt;/a&gt; - a strongly-typed functional programming language built for the modern web.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;/languages/haskell&quot;&gt;Haskell&lt;/a&gt; - a standardized, general-purpose purely functional programming language, with non-strict semantics and strong static typing. It is named after logician Haskell Curry. The latest standard of Haskell is Haskell 2010. As of May 2016, a group is working on the next version, Haskell 2020.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;/languages/idris&quot;&gt;Idris&lt;/a&gt; - a general purpose pure functional programming language with dependent types. Dependent types allow types to be predicated on values, meaning that some aspects of a program’s behaviour can be specified precisely in the type. It is compiled, with eager evaluation. Its features are influenced by Haskell and ML.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;/languages/lisp/janet&quot;&gt;Janet&lt;/a&gt; - a good system scripting language, or a language to embed in other programs.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;/languages/jvm/java&quot;&gt;Java&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;/languages/ecmascript&quot;&gt;JavaScript&lt;/a&gt; - a high-level, interpreted programming language that conforms to the ECMAScript specification. It is a language that is also characterized as dynamic, weakly typed, prototype-based and multi-paradigm.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;/languages/julia&quot;&gt;Julia&lt;/a&gt; - Julia was designed from the beginning for high performance. Julia programs compile to efficient native code for multiple platforms via LLVM.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;/languages/kcl&quot;&gt;KCL&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;/languages/jvm/kotlin&quot;&gt;Kotlin&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;/languages/wasm/kou&quot;&gt;Kou&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;LabVIEW is a development environment for the G dataflow graphical programming language used for data acquisition, instrument control, and industrial automation. 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://www.ni.com/en/shop/electronic-test-instrumentation/programming-environments-for-electronic-test-and-instrumentation/what-is-g-web-development-software.html&quot;&gt;G Web Development Software&lt;/a&gt; - A standalone development environment implementing a subset of the G dataflow graphical programming language to create web-based user interfaces for test and measurement applications.&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/ni/vireosdk&quot;&gt;Vireo&lt;/a&gt; - An open-source runtime capable of running the virtual instrument assembly representation of the G dataflow graphical programming language created by G Web Development Software.&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;a href=&quot;/languages/lisp&quot;&gt;Lisp&lt;/a&gt; - Lisp (historically LISP) is a family of programming languages with a long history and a distinctive, fully parenthesized prefix notation.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;/languages/lobster&quot;&gt;Lobster&lt;/a&gt; - a statically typed language with flow-sensitive type inference and specialization, compile time reference counting (lifetime analysis) that looks a bit like Python. It was originally intended specifically for games.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;/languages/lox&quot;&gt;Lox&lt;/a&gt; - a language created by Bob Nystrom, used to teach compilers in the book Crafting Interpreters. It is dynamically typed, and supports classes, closures, and first-class functions.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;/languages/lua&quot;&gt;Lua&lt;/a&gt; - a lightweight, multi-paradigm programming language designed primarily for embedded systems and clients. Lua is cross-platform, since the interpreter is written in ANSI C, and has a relatively simple C API.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;/languages/lys&quot;&gt;Lys&lt;/a&gt; - a typed functional language that compiles directly to WebAssembly.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;/languages/moonbit&quot;&gt;Moonbit&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;/languages/nelua&quot;&gt;Nelua&lt;/a&gt; - Minimal, simple, efficient, statically typed, compiled, metaprogrammable, safe, and extensible systems programming language with a Lua flavor.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;/languages/nerd&quot;&gt;Nerd&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;/languages/never&quot;&gt;Never&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;/languages/nim&quot;&gt;Nim&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;/languages/ml/ocaml&quot;&gt;Ocaml&lt;/a&gt; - the main implementation of the programming language Caml, created by Xavier Leroy, Jérôme Vouillon, Damien Doligez, Didier Rémy, Ascánder Suárez and others in 1996. A member of the ML language family, OCaml extends the core Caml language with object-oriented programming constructs.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;/languages/pascal&quot;&gt;Pascal&lt;/a&gt; - Pascal is a general purpose imperative, procedural and object-oriented static typing programming language. The Free Pascal compiler targets many processor architectures, including wasm32; operating systems, including WASI; and embedded platforms.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;/languages/php&quot;&gt;PHP&lt;/a&gt; - PHP is a general-purpose scripting language that is especially suited to server-side web development, in which case PHP generally runs on a web server. Any PHP code in a requested file is executed by the PHP runtime, usually to create dynamic web page content or dynamic images used on websites or elsewhere.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;/languages/plorth&quot;&gt;Plorth&lt;/a&gt; - Plorth is stack based, concatenative, strongly typed functional scripting language which is easy to embed to applications written in C++. It&apos;s inspired by Forth and Factor programming languages.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;/languages/wasm/poetry&quot;&gt;Poetry&lt;/a&gt; - Poetry is a poetically dynamic and simple programming language that compiles to WebAssembly. It has a minimalisting syntax akin to CoffeeScript and gives you full control over wasm imports and exports.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;/languages/python&quot;&gt;Python&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;/languages/prolog&quot;&gt;Prolog&lt;/a&gt; - Prolog is a general-purpose logic programming language associated with artificial intelligence and computational linguistics. Prolog has its roots in first-order logic, a formal logic, and unlike many other programming languages, Prolog is intended primarily as a declarative programming language: the program logic is expressed in terms of relations, represented as facts and rules. A computation is initiated by running a query over these relations.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;/languages/r&quot;&gt;R&lt;/a&gt; - R is a language and environment for statistical computing and graphics.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;/languages/rebol&quot;&gt;Rebol&lt;/a&gt; - Homoiconic (&quot;data is code&quot; and vice-versa) dynamic programming language and data-format (representing data and metadata) language.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;/languages/rego&quot;&gt;Rego&lt;/a&gt; - Open Policy Agent (OPA) is an open source, general-purpose policy engine that unifies policy enforcement across the stack. Rego is a high-level declarative policy language purpose-built for expressing policies over complex hierarchical data structures.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;/languages/ring&quot;&gt;Ring&lt;/a&gt; - Ring is a Simple, Small, and Flexible practical general-purpose multi-paradigm language. The supported programming paradigms are Imperative, Procedural, Object-Oriented, Functional, Metaprogramming, Declarative programming using nested structures, and Natural programming.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;/languages/roc&quot;&gt;Roc&lt;/a&gt; - A fast, friendly, functional language. Compiles to machine code or WASM.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;/languages/ruby&quot;&gt;Ruby&lt;/a&gt; - Ruby is an open source interpreted high-level programming language for general-purpose programming. Created by Matz. Ruby has a design philosophy that emphasizes code readability, notably using as few sigils (special chars&lt;code&gt;:.{}%[]&amp;amp;=&amp;gt;;&lt;/code&gt;) as possible.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;/languages/rust&quot;&gt;Rust&lt;/a&gt; - Rust is a systems programming language sponsored by Mozilla Research, which describes it as a &quot;safe, concurrent, practical language,&quot;supporting functional and imperative-procedural paradigms. Rust is syntactically similar to C++, but its designers intend it to provide better memory safety while maintaining performance.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;/languages/scheme&quot;&gt;Scheme&lt;/a&gt; - Scheme is a programming language that supports multiple paradigms, including functional programming and imperative programming, and is one of the two main dialects of Lisp. Unlike Common Lisp, the other main dialect, Scheme follows a minimalist design philosophy specifying a small standard core with powerful tools for language extension.&lt;/li&gt; 
 &lt;li&gt;Speedy.js - Speedy.js is a compiler for a well considered, performance pitfalls free subset of JavaScript targeting WebAssembly. Because WebAssembly is statically-typed, the project uses TypeScript as type-checker and to resolve the types of the program symbols. ~&lt;a href=&quot;https://github.com/MichaReiser/speedy.js&quot;&gt;Source&lt;/a&gt;~ &lt;code&gt;Unmaintained&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;/languages/swift&quot;&gt;Swift&lt;/a&gt; - Swift is a general-purpose, multi-paradigm, compiled programming language developed by Apple Inc. for iOS, macOS, watchOS, tvOS, Linux, and z/OS.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;/languages/tcl&quot;&gt;Tcl&lt;/a&gt; - Tcl (Tool Command Language) is a very powerful but easy to learn dynamic programming language, mature but evolving, highly extensible and suitable for a very wide range of uses.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;/languages/wasm/theta&quot;&gt;Theta&lt;/a&gt; - Theta is a modern, general purpose, functional programming language with a strong type system and expressive syntax. It features a modular design and supports pattern matching, function overloading, and other goodies.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/01alchemist/TurboScript&quot;&gt;TurboScript&lt;/a&gt; - TurboScript is an experimental programming language for parallel programming for web which compiles to JavaScript (asm.js) and WebAssembly (targeting post-MVP). The syntax is similar to TypeScript and the compiler is open source and written in TypeScript. TurboScript has zero dependencies. &lt;code&gt;Unmaintained&lt;/code&gt; since 2018&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;/languages/v&quot;&gt;V&lt;/a&gt; - V is a statically typed compiled programming language designed for building maintainable software.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;/languages/virgil&quot;&gt;Virgil&lt;/a&gt; - A fast and lightweight safe, garbage-collected systems programming language. Its compiler produces optimized, standalone native executables, WebAssembly modules, or JARs for the JVM.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;/languages/wasm/wa&quot;&gt;Wa&lt;/a&gt; - Wa is a general-purpose programming language designed for developing robustness and maintainability WebAssembly software. Instead of requiring complex toolchains to set up, you can simply go install it - or run it in a browser.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/tmcw/wah&quot;&gt;Wah&lt;/a&gt; - Wah is a slightly higher level language that is a superset of WebAssembly. It aims to make WebAssembly&apos;s text format slightly more friendly to humans, without introducing new syntax or datatypes. &lt;code&gt;Unmaintained&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/ballercat/walt&quot;&gt;WAlt&lt;/a&gt; - WAlt is an alternative syntax for WebAssembly text format. It&apos;s an experiment for using JavaScript syntax to write to as &apos;close to the metal&apos; as possible. It&apos;s JavaScript with rules. .walt files compile directly to WebAssembly binary format. &lt;code&gt;Unmaintained&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/kanaka/wam&quot;&gt;Wam&lt;/a&gt; - WebAssembly Macro language: Wam syntax is a near superset of wast syntax that is more convenient for human developers to write directly. &lt;code&gt;Unmaintained&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;/languages/wasm/wase&quot;&gt;Wase&lt;/a&gt; - WASE: WebAssembly made easy. Wase is a language, which tries to make WASM easy to write. The language maps closely to WebAssembly, and compiles directly to Wasm bytecode. Has strong typing with type inference.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;/languages/wonkey&quot;&gt;Wonkey&lt;/a&gt; - Wonkey is an easy to learn, object-oriented, modern and cross-platform programming language for creating cross-platform video games, highly inspired by the &quot;BlitzBasic&quot; range of languages.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;/languages/c&quot;&gt;xcc&lt;/a&gt; - Toy C compiler for x86-64 and wasm - &lt;a href=&quot;https://github.com/tyfkda/xcc&quot;&gt;Source&lt;/a&gt;, &lt;a href=&quot;https://tyfkda.github.io/xcc/&quot;&gt;Online demo&lt;/a&gt;.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;/languages/zig&quot;&gt;Zig&lt;/a&gt; - Zig is a general-purpose programming language designed for robustness, optimality, and maintainability. &lt;a href=&quot;https://ziglang.org/documentation/master/#WebAssembly&quot;&gt;Documentation on WebAssembly&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Web analytics</title>
      <link>https://tedneward.github.io/Research/platforms/web/analytics/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">platforms/web/analytics/index.html</guid>
      	<description>
	&lt;h2&gt;Commercial/non-OSS tools&lt;/h2&gt; 
&lt;p&gt;&lt;a href=&quot;https://analytics.google.com/&quot;&gt;Google Analytics&lt;/a&gt;&lt;/p&gt; 
&lt;h2&gt;Open-source Alternatives&lt;/h2&gt; 
&lt;p&gt;&lt;a href=&quot;https://www.goatcounter.com/&quot;&gt;GoatCounter&lt;/a&gt;: &lt;a href=&quot;https://github.com/arp242/goatcounter&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://matomo.org/&quot;&gt;Matomo&lt;/a&gt;|&lt;a href=&quot;https://github.com/matomo-org/matomo&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://plausible.io/&quot;&gt;Plausible&lt;/a&gt;|&lt;a href=&quot;https://github.com/plausible/analytics&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://umami.is&quot;&gt;Umami&lt;/a&gt;|&lt;a href=&quot;https://github.com/mikecao/umami&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Web Assembly Tools</title>
      <link>https://tedneward.github.io/Research/platforms/wasm/tools/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">platforms/wasm/tools/index.html</guid>
      	<description>
	&lt;h2&gt;Inspecting&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://wasdk.github.io/wasmcodeexplorer/&quot;&gt;WebAssembly Code Explorer&lt;/a&gt;: A simple binary explorer with neat binary code highlighting.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://evmar.github.io/weave&quot;&gt;Weave&lt;/a&gt;: Another simple binary explorer.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/WebAssembly/binaryen&quot;&gt;wasm-opt&lt;/a&gt; (part of Binaryen): 
  &lt;ul&gt; 
   &lt;li&gt;Color output of s-expression format: &lt;code&gt;wasm-opt --print test.wasm&lt;/code&gt;&lt;/li&gt; 
   &lt;li&gt;Plot the callgraph using &lt;code&gt;Graphviz&lt;/code&gt;: &lt;code&gt;wasm-opt --print-call-graph test.wasm | dot -Tpng -o callgraph.png&lt;/code&gt;&lt;/li&gt; 
   &lt;li&gt;Dump DWARF debug info sections: &lt;code&gt;wasm-opt --dwarfdump test.wasm&lt;/code&gt;&lt;/li&gt; 
   &lt;li&gt;Print function metrics: &lt;code&gt;wasm-opt --func-metrics test.wasm&lt;/code&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://github.com/WebAssembly/wabt&quot;&gt;wasm-decompile&lt;/a&gt; (part of WABT) : &lt;code&gt;wasm-decompile&lt;/code&gt; decompiles a wasm binary into readable code. It generates output that tries to look like a &quot;very average programming language&quot; while still staying close to the wasm it represents.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://wwwg.github.io/web-wasmdec/&quot;&gt;wasmdec&lt;/a&gt; | &lt;a href=&quot;https://github.com/wwwg/wasmdec&quot;&gt;Source&lt;/a&gt;: Converts WebAssembly binaries to C. Similar to &lt;code&gt;wasm2c&lt;/code&gt;.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/WebAssembly/wasp&quot;&gt;wasp&lt;/a&gt;: Generate callgraphs, CFG and DFG graphs for wasm functions.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/WebAssembly/wabt&quot;&gt;wasm-objdump&lt;/a&gt; (part of WABT): Print low-level details about a &lt;code&gt;.wasm&lt;/code&gt; binary and each of its sections.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/fitzgen/wasm-nm&quot;&gt;wasm-nm&lt;/a&gt;: List the imported, exported, and private function symbols defined within a &lt;code&gt;.wasm&lt;/code&gt; binary.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Static analysis&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;strong&gt;Twiggy&lt;/strong&gt; | &lt;a href=&quot;https://github.com/rustwasm/twiggy&quot;&gt;repo&lt;/a&gt;: Code size profiler, analyzes a binary&apos;s call graph.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Manticore&lt;/strong&gt; | &lt;a href=&quot;https://github.com/trailofbits/manticore&quot;&gt;repo&lt;/a&gt;, &lt;a href=&quot;https://blog.trailofbits.com/2020/01/31/symbolically-executing-webassembly-in-manticore/&quot;&gt;article&lt;/a&gt;: Symbolic execution of WebAssembly binaries.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Octopus&lt;/strong&gt; | &lt;a href=&quot;https://github.com/pventuzelo/octopus&quot;&gt;repo&lt;/a&gt;: Security analysis framework for WebAssembly modules and Smart Contracts.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Wassail&lt;/strong&gt; | &lt;a href=&quot;https://github.com/acieroid/wassail&quot;&gt;repo&lt;/a&gt;: A toolkit to perform both lightweight and heavyweight static analysis of WebAssembly modules.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;wasm-opcodecnt&lt;/strong&gt; | part of &lt;a href=&quot;https://github.com/WebAssembly/wabt&quot;&gt;&lt;code&gt;WABT&lt;/code&gt;&lt;/a&gt;: Count wasm opcode usage statistics.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Manipulating (optimization, transformation, instrumentation)&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;strong&gt;wasm-opt&lt;/strong&gt; | part of &lt;a href=&quot;https://github.com/WebAssembly/binaryen&quot;&gt;&lt;code&gt;Binaryen&lt;/code&gt;&lt;/a&gt;:&lt;/li&gt; 
 &lt;li&gt;Transform binary for asynchronous execution (read more in &lt;a href=&quot;https://kripken.github.io/blog/wasm/2019/07/16/asyncify.html&quot;&gt;this article&lt;/a&gt;): &lt;code&gt;wasm-opt test.wasm --asyncify -O3 -o asyncified.wasm&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;Instrument binary for dynamic execution tracing: &lt;code&gt;wasm-opt test.wasm --instrument-memory --instrument-locals --log-execution -o instrumetred.wasm&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;wizer&lt;/strong&gt; | &lt;a href=&quot;https://github.com/bytecodealliance/wizer&quot;&gt;repo&lt;/a&gt;: Don&apos;t wait for your Wasm module to initialize itself, pre-initialize it! Wizer instantiates your WebAssembly module, executes its initialization function, and then snapshots the initialized state out into a new WebAssembly module.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;wasm2c&lt;/strong&gt; | part of &lt;a href=&quot;https://github.com/WebAssembly/wabt/blob/main/wasm2c/README.md&quot;&gt;&lt;code&gt;WABT&lt;/code&gt;&lt;/a&gt;: Takes a WebAssembly module and produces an equivalent (and runnable) C source and header.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;wasm-snip&lt;/strong&gt; | &lt;a href=&quot;https://github.com/rustwasm/wasm-snip&quot;&gt;repo&lt;/a&gt;: Replaces a WebAssembly function&apos;s body with an &lt;code&gt;unreachable&lt;/code&gt;.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;wasmonkey&lt;/strong&gt; | &lt;a href=&quot;https://github.com/jedisct1/wasmonkey&quot;&gt;repo&lt;/a&gt;: Magically turns exported WASM functions into imported functions.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;wasm-meter&lt;/strong&gt; | &lt;a href=&quot;https://www.npmjs.org/package/wasm-metering&quot;&gt;npm&lt;/a&gt;, &lt;a href=&quot;https://github.com/ewasm/wasm-metering&quot;&gt;repo&lt;/a&gt;: Injects metering into webassembly binaries. This counts computation time for a given program in units of &lt;code&gt;gas&lt;/code&gt; (and allows limiting it).&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;CROW&lt;/strong&gt; | &lt;a href=&quot;https://github.com/KTH/slumps/tree/master/crow&quot;&gt;repo&lt;/a&gt;: The Wasm superdiversifier. It takes C source code or LLVM bitcode as input and generates several functionally equivalent, but diverse Wasm binaries.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Dynamic analysis (tracing, profiling)&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;strong&gt;wasm3-strace&lt;/strong&gt; | &lt;a href=&quot;https://wapm.io/package/vshymanskyy/wasm3&quot;&gt;wapm&lt;/a&gt;, &lt;a href=&quot;https://github.com/wasm3/wasm3&quot;&gt;repo&lt;/a&gt;: Structured, seamless tracing of arbitrary WebAssembly/WASI execution.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Wasabi&lt;/strong&gt; | &lt;a href=&quot;http://wasabi.software-lab.org/&quot;&gt;home&lt;/a&gt;, &lt;a href=&quot;https://github.com/danleh/wasabi&quot;&gt;repo&lt;/a&gt;: &quot;WebAssembly analysis using binary instrumentation&quot;, a dynamic analysis framework.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;wasmsign2&lt;/strong&gt; | &lt;a href=&quot;https://github.com/wasm-signatures/wasmsign2&quot;&gt;repo&lt;/a&gt;: A tool to add and verify digital signatures to/from WASM binaries.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;swam&lt;/strong&gt; | &lt;a href=&quot;https://github.com/satabin/swam/&quot;&gt;repo&lt;/a&gt;: A WASM interpreter with advanced tracing capabilities.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Source-level debugging&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;strong&gt;wasminspect&lt;/strong&gt; | &lt;a href=&quot;https://github.com/kateinoigakukun/wasminspect&quot;&gt;repo&lt;/a&gt;: An interactive and self-contained debugger for WebAssembly/WASI.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Tool development&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;strong&gt;Tool Conventions&lt;/strong&gt; | &lt;a href=&quot;https://github.com/WebAssembly/tool-conventions&quot;&gt;docs&lt;/a&gt;: Documents describing conventions useful for coordinating interoperability between wasm-related tools.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;wasm2json, json2wasm&lt;/strong&gt; | &lt;a href=&quot;https://www.npmjs.com/package/wasm-json-toolkit&quot;&gt;npm&lt;/a&gt;, &lt;a href=&quot;https://github.com/ewasm/wasm-json-toolkit&quot;&gt;repo&lt;/a&gt;: A small toolkit for converting wasm binaries into json and back. Incredibly helpful for experimenting and creating your own transformations.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;walrus&lt;/strong&gt; | &lt;a href=&quot;https://github.com/rustwasm/walrus&quot;&gt;repo&lt;/a&gt;: Rust library for performing WebAssembly transformations in a robust and ergonomic fashion.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;wasp&lt;/strong&gt; | &lt;a href=&quot;https://github.com/WebAssembly/wasp&quot;&gt;repo&lt;/a&gt;: C++ library designed to make it easy to work with WebAssembly modules.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;Binaryen.js&lt;/strong&gt; | &lt;a href=&quot;https://github.com/AssemblyScript/binaryen.js&quot;&gt;repo&lt;/a&gt;: A port of Binaryen to the Web, allowing you to generate WebAssembly using JavaScript.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;wasm-tools&lt;/strong&gt; | &lt;a href=&quot;https://github.com/bytecodealliance/wasm-tools&quot;&gt;repo&lt;/a&gt;: Rust tooling for low-level manipulation of WebAssembly modules. &lt;p&gt;&lt;code&gt;wasm-smith&lt;/code&gt; test case generator is of particular interest.&lt;br&gt; &lt;code&gt;wasm-shrink&lt;/code&gt; shrinks a Wasm file while preserving an interesting property (such as triggering a bug).&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;wasm-debug&lt;/strong&gt; | &lt;a href=&quot;https://github.com/wasmerio/wasm-debug&quot;&gt;repo&lt;/a&gt;, &lt;a href=&quot;https://crates.io/crates/wasm-debug&quot;&gt;crate&lt;/a&gt;: A runtime-independent Rust library that provides functionality to read, transform, and write DWARF section.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;witx-codegen&lt;/strong&gt; | &lt;a href=&quot;https://github.com/jedisct1/witx-codegen&quot;&gt;repo&lt;/a&gt;: A code generator to access WebAssembly standard APIs from different programming languages. Can also generate documentation.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Reading&lt;/h2&gt; 
&lt;h3&gt;Articles/Blogs/Essays&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://kripken.github.io/blog/binaryen/2019/06/11/fuzz-reduce-productivity.html&quot;&gt;Fuzzers &amp;amp; Reducers as Productivity Tools&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;wasm2c: &lt;a href=&quot;https://kripken.github.io/blog/wasm/2020/07/27/wasmboxc.html&quot;&gt;wasmboxc&lt;/a&gt;, &lt;a href=&quot;https://petersalomonsen.com/articles/wasm2c/wasm2c.html&quot;&gt;wasm2c&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Debugging&lt;/h4&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://developers.google.com/web/updates/2020/12/webassembly&quot;&gt;https://developers.google.com/web/updates/2020/12/webassembly&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://hacks.mozilla.org/2019/09/debugging-webassembly-outside-of-the-browser/&quot;&gt;https://hacks.mozilla.org/2019/09/debugging-webassembly-outside-of-the-browser/&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://v8.dev/blog/wasm-decompile&quot;&gt;wasm-decompile&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Reference&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;strong&gt;WebAssembly Opcode Table&lt;/strong&gt; | &lt;a href=&quot;https://pengowray.github.io/wasm-ops/&quot;&gt;docs&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Wasm Interface Types (WIT)</title>
      <link>https://tedneward.github.io/Research/platforms/wasm/wit/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">platforms/wasm/wit/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://component-model.bytecodealliance.org/design/wit.html&quot;&gt;Bytecodealliance Specification&lt;/a&gt; (Proposal?)&lt;/p&gt; 
&lt;h1&gt;The &lt;code&gt;wit&lt;/code&gt; format&lt;/h1&gt; 
&lt;p&gt;The Wasm Interface Type (WIT) format is an &lt;a href=&quot;https://en.wikipedia.org/wiki/Interface_description_language&quot;&gt;IDL&lt;/a&gt; to provide tooling for the &lt;a href=&quot;https://github.com/webassembly/component-model&quot;&gt;WebAssembly Component Model&lt;/a&gt; in two primary ways:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt; &lt;p&gt;WIT is a developer-friendly format to describe the imports and exports to a component. It is easy to read and write and provides the foundational basis for producing components from guest languages as well as consuming components in host languages.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;WIT packages are the basis of sharing types and definitions in an ecosystem of components. Authors can import types from other WIT packages when generating a component, publish a WIT package representing a host embedding, or collaborate on a WIT definition of a shared set of APIs between platforms.&lt;/p&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;A WIT package is a collection of WIT &lt;a href=&quot;#wit-interfaces&quot;&gt;&lt;code&gt;interface&lt;/code&gt;s&lt;/a&gt; and &lt;a href=&quot;#wit-worlds&quot;&gt;&lt;code&gt;world&lt;/code&gt;s&lt;/a&gt; defined in files in the same directory that all use the file extension &lt;code&gt;wit&lt;/code&gt;, for example &lt;code&gt;foo.wit&lt;/code&gt;. Files are encoded as valid utf-8 bytes. Types can be imported between interfaces within a package using unqualified names and additionally from other packages through namespace-and-package-qualified names.&lt;/p&gt; 
&lt;p&gt;This document will go through the purpose of the syntactic constructs of a WIT document, a pseudo-formal &lt;a href=&quot;#lexical-structure&quot;&gt;grammar specification&lt;/a&gt;, and additionally a specification of the &lt;a href=&quot;#package-format&quot;&gt;package format&lt;/a&gt; of a WIT package suitable for distribution.&lt;/p&gt; 
&lt;h2&gt;Package Names&lt;/h2&gt; 
&lt;p&gt;All WIT packages are assigned a &lt;em&gt;package name&lt;/em&gt;. Package names look like &lt;code&gt;foo:bar@1.0.0&lt;/code&gt; and have three fields:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt; &lt;p&gt;A &lt;em&gt;namespace field&lt;/em&gt;, for example &lt;code&gt;foo&lt;/code&gt; in &lt;code&gt;foo:bar&lt;/code&gt;. This namespace is intended to disambiguate between registries, top-level organizations, etc. For example WASI interfaces use the &lt;code&gt;wasi&lt;/code&gt; namespace.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;A &lt;em&gt;package field&lt;/em&gt;, for example &lt;code&gt;clocks&lt;/code&gt; in &lt;code&gt;wasi:clocks&lt;/code&gt;. A &quot;package&quot; groups together a set of interfaces and worlds that would otherwise be named with a common prefix.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;An optional &lt;em&gt;version field&lt;/em&gt;, specified as &lt;a href=&quot;https://semver.org/&quot;&gt;full semver&lt;/a&gt;.&lt;/p&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;🪺 With &quot;nested namespaces and packages&quot;, package names are generalized to look like &lt;code&gt;foo:bar:baz/quux&lt;/code&gt;, where &lt;code&gt;bar&lt;/code&gt; is a nested namespace of &lt;code&gt;foo&lt;/code&gt; and &lt;code&gt;quux&lt;/code&gt; is a nested package of &lt;code&gt;baz&lt;/code&gt;. See the &lt;a href=&quot;#package-declaration&quot;&gt;package declaration&lt;/a&gt; section for more details.&lt;/p&gt; 
&lt;p&gt;Package names are specified at the top of a WIT file via a &lt;code&gt;package&lt;/code&gt; declaration:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-wit&quot;&gt;package wasi:clocks;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;or&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-wit&quot;&gt;package wasi:clocks@1.2.0;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;WIT packages can be defined in a collection of files. At least one of these files must specify a package name. Multiple files can specify the &lt;code&gt;package&lt;/code&gt;, though they must all agree on what the package name is.&lt;/p&gt; 
&lt;p&gt;Additionally, many packages can be declared consecutively in one or more files, if the following nested package notation is used:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-wit&quot;&gt;package local:a {
    interface foo {}
}

package local:b {
    interface bar {}
}
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;It is worth noting that defining nested packages does not remove the need for the &quot;root&quot; package declaration above. These nested package definitions simply provide the contents of other packages inline so that they don&apos;t have to be otherwise resolved via the filesystem or a registry.&lt;/p&gt; 
&lt;p&gt;Package names are used to generate the &lt;a href=&quot;Explainer.md#import-and-export-definitions&quot;&gt;names of imports and exports&lt;/a&gt; in the Component Model&apos;s representation of &lt;a href=&quot;#wit-interfaces&quot;&gt;&lt;code&gt;interface&lt;/code&gt;s&lt;/a&gt; and &lt;a href=&quot;#wit-worlds&quot;&gt;&lt;code&gt;world&lt;/code&gt;s&lt;/a&gt; as described &lt;a href=&quot;#package-format&quot;&gt;below&lt;/a&gt;.&lt;/p&gt; 
&lt;h2&gt;WIT Interfaces&lt;/h2&gt; 
&lt;p&gt;The concept of an &quot;interface&quot; is central in WIT as a collection of &lt;a href=&quot;#wit-functions&quot;&gt;functions&lt;/a&gt; and &lt;a href=&quot;#wit-types&quot;&gt;types&lt;/a&gt;. An interface can be thought of as an instance in the WebAssembly Component Model, for example a unit of functionality imported from the host or implemented by a component for consumption on a host. All functions and types belong to an interface.&lt;/p&gt; 
&lt;p&gt;An example of an interface is:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-wit&quot;&gt;package local:demo;

interface host {
    log: func(msg: string);
}
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;represents an interface called &lt;code&gt;host&lt;/code&gt; which provides one function, &lt;code&gt;log&lt;/code&gt;, which takes a single &lt;code&gt;string&lt;/code&gt; argument. If this were imported into a component then it would correspond to:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-wat&quot;&gt;(component
  (import &quot;local:demo/host&quot; (instance $host
    (export &quot;log&quot; (func (param &quot;msg&quot; string)))
  ))
  ;; ...
)
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;An &lt;code&gt;interface&lt;/code&gt; can contain &lt;a href=&quot;#wit-packages-and-use&quot;&gt;&lt;code&gt;use&lt;/code&gt;&lt;/a&gt; statements, &lt;a href=&quot;#wit-types&quot;&gt;type&lt;/a&gt; definitions, and &lt;a href=&quot;#wit-functions&quot;&gt;function&lt;/a&gt; definitions. For example:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-wit&quot;&gt;package wasi:filesystem;

interface types {
    use wasi:clocks/wall-clock.{datetime};

    record stat {
      ino: u64,
      size: u64,
      mtime: datetime,
      // ...
    }

    stat-file: func(path: string) -&amp;gt; result&amp;lt;stat&amp;gt;;
}
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;More information about &lt;a href=&quot;#wit-packages-and-use&quot;&gt;&lt;code&gt;use&lt;/code&gt;&lt;/a&gt; and &lt;a href=&quot;#wit-types&quot;&gt;types&lt;/a&gt; are described below, but this is an example of a collection of items within an &lt;code&gt;interface&lt;/code&gt;. All items defined in an &lt;code&gt;interface&lt;/code&gt;, including &lt;a href=&quot;#wit-packages-and-use&quot;&gt;&lt;code&gt;use&lt;/code&gt;&lt;/a&gt; items, are considered as exports from the interface. This means that types can further be used from the interface by other interfaces. An interface has a single namespace which means that none of the defined names can collide.&lt;/p&gt; 
&lt;p&gt;A WIT package can contain any number of interfaces listed at the top-level and in any order. The WIT validator will ensure that all references between interfaces are well-formed and acyclic.&lt;/p&gt; 
&lt;h2&gt;WIT Worlds&lt;/h2&gt; 
&lt;p&gt;WIT packages can contain &lt;code&gt;world&lt;/code&gt; definitions at the top-level in addition to &lt;a href=&quot;#wit-interfaces&quot;&gt;&lt;code&gt;interface&lt;/code&gt;&lt;/a&gt; definitions. A world is a complete description of both imports and exports of a component. A world can be thought of as an equivalent of a &lt;code&gt;component&lt;/code&gt; type in the component model. For example this world:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-wit&quot;&gt;package local:demo;

world my-world {
    import host: interface {
      log: func(param: string);
    }

    export run: func();
}
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;can be thought of as this component type:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-wat&quot;&gt;(type $my-world (component
  (import &quot;host&quot; (instance
    (export &quot;log&quot; (func (param &quot;param&quot; string)))
  ))
  (export &quot;run&quot; (func))
))
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Worlds describe a concrete component and are the basis of bindings generation. A guest language will use a &lt;code&gt;world&lt;/code&gt; to determine what functions are imported, what they&apos;re named, and what functions are exported, in addition to their names.&lt;/p&gt; 
&lt;p&gt;Worlds can contain any number of imports and exports, and can be either a function or an interface.&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-wit&quot;&gt;package local:demo;

world command {
    import wasi:filesystem/filesystem;
    import wasi:random/random;
    import wasi:clocks/monotonic-clock;
    // ...

    export main: func(args: list&amp;lt;string&amp;gt;);
}
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;More information about the &lt;code&gt;wasi:random/random&lt;/code&gt; syntax is available below in the description of &lt;a href=&quot;#wit-packages-and-use&quot;&gt;&lt;code&gt;use&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt; 
&lt;p&gt;An imported or exported interface corresponds to an imported or exported instance in the component model. Functions are equivalent to bare component functions. Additionally interfaces can be defined inline with an explicit &lt;a href=&quot;Explainer.md#import-and-export-definitions&quot;&gt;plain name&lt;/a&gt; that avoids the need to have an out-of-line definition.&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-wit&quot;&gt;package local:demo;

interface out-of-line {
    the-function: func();
}

world your-world {
    import out-of-line;
    // ... is roughly equivalent to ...
    import out-of-line: interface {
      the-function: func();
    }
}
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;The plain name of an &lt;code&gt;import&lt;/code&gt; or &lt;code&gt;export&lt;/code&gt; statement is used as the plain name of the final component &lt;code&gt;import&lt;/code&gt; or &lt;code&gt;export&lt;/code&gt; definition.&lt;/p&gt; 
&lt;p&gt;In the component model imports to a component either use a plain or interface name, and in WIT this is reflected in the syntax:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-wit&quot;&gt;package local:demo;

interface my-interface {
    // ..
}

world command {
    // generates an import of the name `local:demo/my-interface`
    import my-interface;

    // generates an import of the name `wasi:filesystem/types`
    import wasi:filesystem/types;

    // generates an import of the plain name `foo`
    import foo: func();

    // generates an import of the plain name `bar`
    import bar: interface {
      // ...
    }
}
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Each name must be case-insensitively unique in the scope in which it is declared. In the case of worlds, all imported names are in the same scope, but separate from all the export names, and thus the same name can &lt;em&gt;not&lt;/em&gt; be imported twice, but &lt;em&gt;can&lt;/em&gt; be both imported and exported.&lt;/p&gt; 
&lt;h3&gt;Union of Worlds with &lt;code&gt;include&lt;/code&gt;&lt;/h3&gt; 
&lt;p&gt;A World can be created by taking the union of two or more worlds. This operation allows world builders to form larger worlds from smaller worlds.&lt;/p&gt; 
&lt;p&gt;Below is a simple example of a world that includes two other worlds.&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-wit&quot;&gt;package local:demo;

// definitions of a, b, c, foo, bar, baz are omitted

world my-world-a {
    import a;
    import b;
    export c;
}

world my-world-b {
    import foo;
    import bar;
    export baz;
}

world union-my-world {
    include my-world-a;
    include my-world-b;
}
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;The &lt;code&gt;include&lt;/code&gt; statement is used to include the imports and exports of another World to the current World. It says that the new World should be able to run all components that target the included worlds and more.&lt;/p&gt; 
&lt;p&gt;The &lt;code&gt;union-my-world&lt;/code&gt; World defined above is equivalent to the following World:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-wit&quot;&gt;world union-my-world {
    import a;
    import b;
    export c;
    import foo;
    import bar;
    export baz;
}
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;De-duplication of interfaces&lt;/h3&gt; 
&lt;p&gt;If two worlds share an imported or exported &lt;a href=&quot;Explainer.md#import-and-export-definitions&quot;&gt;interface name&lt;/a&gt;, then the union of the two worlds will only contain one copy of that imported or exported name. For example, the following two worlds &lt;code&gt;union-my-world-a&lt;/code&gt; and &lt;code&gt;union-my-world-b&lt;/code&gt; are equivalent:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-wit&quot;&gt;package local:demo;

world my-world-a {
    import a1;
    import b1;
}

world my-world-b {
    import a1;
    import b1;
}

world union-my-world-a {
    include my-world-a;
    include my-world-b;
}

world union-my-world-b {
    import a1;
    import b1;
}
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;Name Conflicts and &lt;code&gt;with&lt;/code&gt;&lt;/h3&gt; 
&lt;p&gt;When two or more included Worlds have the same name for an import or export with a &lt;em&gt;plain&lt;/em&gt; name, automatic de-duplication cannot be used (because the two same-named imports/exports might have different meanings in the different worlds) and thus the conflict has to be resolved manually using the &lt;code&gt;with&lt;/code&gt; keyword.&lt;/p&gt; 
&lt;p&gt;The following example shows how to resolve name conflicts where &lt;code&gt;union-my-world-a&lt;/code&gt; and &lt;code&gt;union-my-world-b&lt;/code&gt; are equivalent:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-wit&quot;&gt;package local:demo;

world world-one { import a: func(); }
world world-two { import a: func(); }

world union-my-world-a {
    include world-one;
    include world-two with { a as b }
}

world union-my-world-b {
    import a: func();
    import b: func();
}
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;&lt;code&gt;with&lt;/code&gt; cannot be used to rename interface names, however, so the following world would be invalid:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-wit&quot;&gt;package local:demo;

interface a {
    foo: func();
}

world world-using-a {
    import a;
}

world invalid-union-world {
    include my-using-a with { a as b }  // invalid: &apos;a&apos;, which is short for &apos;local:demo/a&apos;, is an interface name
}

&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;A Note on Subtyping&lt;/h3&gt; 
&lt;p&gt;In the future, when &lt;code&gt;optional&lt;/code&gt; export is supported, the world author may explicitly mark exports as optional to make a component targeting an included World a subtype of the union World.&lt;/p&gt; 
&lt;p&gt;For now, we are not following the subtyping rules for the &lt;code&gt;include&lt;/code&gt; statement. That is, the &lt;code&gt;include&lt;/code&gt; statement does not imply any subtyping relationship between the included worlds and the union world.&lt;/p&gt; 
&lt;h2&gt;WIT Packages and &lt;code&gt;use&lt;/code&gt;&lt;/h2&gt; 
&lt;p&gt;A WIT package represents a unit of distribution that can be published to a registry, for example, and used by other WIT packages. WIT packages are a flat list of interfaces and worlds defined in &lt;code&gt;*.wit&lt;/code&gt; files. The current thinking for a convention is that projects will have a &lt;code&gt;wit&lt;/code&gt; folder where all &lt;code&gt;wit/*.wit&lt;/code&gt; files within describe a single package.&lt;/p&gt; 
&lt;p&gt;The purpose of the &lt;code&gt;use&lt;/code&gt; statement is to enable sharing types between interfaces, even if they&apos;re defined outside of the current package in a dependency. The &lt;code&gt;use&lt;/code&gt; statement can be used both within interfaces and worlds and at the top-level of a WIT file.&lt;/p&gt; 
&lt;h4&gt;Interfaces, worlds, and &lt;code&gt;use&lt;/code&gt;&lt;/h4&gt; 
&lt;p&gt;A &lt;code&gt;use&lt;/code&gt; statement inside of an &lt;code&gt;interface&lt;/code&gt; or &lt;code&gt;world&lt;/code&gt; block can be used to&lt;br&gt; import types:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-wit&quot;&gt;package local:demo;

interface types {
    enum errno { /* ... */ }

    type size = u32;
}

interface my-host-functions {
    use types.{errno, size};
}
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;The &lt;code&gt;use&lt;/code&gt; target, &lt;code&gt;types&lt;/code&gt;, is resolved within the scope of the package to an&lt;br&gt; interface, in this case defined prior. Afterwards a list of types are provided&lt;br&gt; as what&apos;s going to be imported with the &lt;code&gt;use&lt;/code&gt; statement. The interface &lt;code&gt;types&lt;/code&gt;&lt;br&gt; may textually come either after or before the &lt;code&gt;use&lt;/code&gt; directive&apos;s interface.&lt;br&gt; Interfaces linked with &lt;code&gt;use&lt;/code&gt; must be acyclic.&lt;/p&gt; 
&lt;p&gt;Names imported via &lt;code&gt;use&lt;/code&gt; can be renamed as they&apos;re imported as well:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-wit&quot;&gt;package local:demo;

interface my-host-functions {
    use types.{errno as my-errno};
}
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;This form of &lt;code&gt;use&lt;/code&gt; is using a single identifier as the target of what&apos;s being&lt;br&gt; imported, in this case &lt;code&gt;types&lt;/code&gt;. The name &lt;code&gt;types&lt;/code&gt; is first looked up within the&lt;br&gt; scope of the current file, but it will additionally consult the package&apos;s&lt;br&gt; namespace as well. This means that the above syntax still works if the&lt;br&gt; interfaces are defined in sibling files:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-wit&quot;&gt;// types.wit
interface types {
    enum errno { /* ... */ }

    type size = u32;
}

// host.wit
package local:demo;

interface my-host-functions {
    use types.{errno, size};
}
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Here the &lt;code&gt;types&lt;/code&gt; interface is not defined in &lt;code&gt;host.wit&lt;/code&gt; but lookup will find it&lt;br&gt; as it&apos;s defined in the same package, just instead in a different file. Since&lt;br&gt; files are not ordered, but type definitions in the Component Model are ordered&lt;br&gt; and acyclic, the WIT parser will perform an implicit topological sort of all&lt;br&gt; parsed WIT definitions to find an acyclic definition order (or produce an error&lt;br&gt; if there is none).&lt;/p&gt; 
&lt;p&gt;When importing or exporting an &lt;a href=&quot;#wit-interfaces&quot;&gt;interface&lt;/a&gt; in a &lt;a href=&quot;#wit-worlds&quot;&gt;world&lt;/a&gt;&lt;br&gt; the same syntax is used in &lt;code&gt;import&lt;/code&gt; and &lt;code&gt;export&lt;/code&gt; directives:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-wit&quot;&gt;// a.wit
package local:demo;

world my-world {
    import host;

    export another-interface;
}

interface host {
    // ...
}

// b.wit
interface another-interface {
    // ...
}
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;When referring to an interface, a fully-qualified &lt;a href=&quot;Explainer.md#import-and-export-definitions&quot;&gt;interface name&lt;/a&gt; can be used.&lt;br&gt; For example, in this WIT document:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-wit&quot;&gt;package local:demo;

world my-world {
    import wasi:clocks/monotonic-clock;
}
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;The &lt;code&gt;monotonic-clock&lt;/code&gt; interface of the &lt;code&gt;wasi:clocks&lt;/code&gt; package is being imported.&lt;br&gt; This same syntax can be used in &lt;code&gt;use&lt;/code&gt; as well:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-wit&quot;&gt;package local:demo;

interface my-interface {
    use wasi:http/types.{request, response};
}
&lt;/code&gt;&lt;/pre&gt; 
&lt;h4&gt;Top-level &lt;code&gt;use&lt;/code&gt;&lt;/h4&gt; 
&lt;p&gt;If a package being referred to has a version number, then using the above syntax&lt;br&gt; so far it can get a bit repetitive to be referred to:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-wit&quot;&gt;package local:demo;

interface my-interface {
    use wasi:http/types@1.0.0.{request, response};
}

world my-world {
    import wasi:http/handler@1.0.0;
    export wasi:http/handler@1.0.0;
}
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;To reduce repetition and to possibly help avoid naming conflicts the &lt;code&gt;use&lt;/code&gt;&lt;br&gt; statement can additionally be used at the top-level of a file to rename&lt;br&gt; interfaces within the scope of the file itself. For example the above could be&lt;br&gt; rewritten as:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-wit&quot;&gt;package local:demo;

use wasi:http/types@1.0.0;
use wasi:http/handler@1.0.0;

interface my-interface {
    use types.{request, response};
}

world my-world {
    import handler;
    export handler;
}
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;The meaning of this and the previous world are the same, and &lt;code&gt;use&lt;/code&gt; is purely a&lt;br&gt; developer convenience for providing smaller names if necessary.&lt;/p&gt; 
&lt;p&gt;The interface referred to by a &lt;code&gt;use&lt;/code&gt; is the name that is defined in the current&lt;br&gt; file&apos;s scope:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-wit&quot;&gt;package local:demo;

use wasi:http/types;   // defines the name `types`
use wasi:http/handler; // defines the name `handler`
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Like with interface-level-&lt;code&gt;use&lt;/code&gt; the &lt;code&gt;as&lt;/code&gt; keyword can be used to rename the&lt;br&gt; inferred name:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-wit&quot;&gt;package local:demo;

use wasi:http/types as http-types;
use wasi:http/handler as http-handler;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Note that these can all be combined to additionally import packages with&lt;br&gt; multiple versions and renaming as different WIT identifiers.&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-wit&quot;&gt;package local:demo;

use wasi:http/types@1.0.0 as http-types1;
use wasi:http/types@2.0.0 as http-types2;

// ...
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;Transitive imports and worlds&lt;/h3&gt; 
&lt;p&gt;A &lt;code&gt;use&lt;/code&gt; statement is not implemented by copying type information around but&lt;br&gt; instead retains that it&apos;s a reference to a type defined elsewhere. This&lt;br&gt; representation is plumbed all the way through to the final component, meaning&lt;br&gt; that &lt;code&gt;use&lt;/code&gt;d types have an impact on the structure of the final generated&lt;br&gt; component.&lt;/p&gt; 
&lt;p&gt;For example this document:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-wit&quot;&gt;package local:demo;

interface shared {
    record metadata {
      // ...
    }
}

world my-world {
    import host: interface {
      use shared.{metadata};

      get: func() -&amp;gt; metadata;
    }
}
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;would generate this component:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-wat&quot;&gt;(component
  (import &quot;local:demo/shared&quot; (instance $shared
    (type $metadata (record (; ... ;)))
    (export &quot;metadata&quot; (type (eq $metadata)))
  ))
  (alias export $shared &quot;metadata&quot; (type $metadata_from_shared))
  (import &quot;host&quot; (instance $host
    (export $metadata_in_host &quot;metadata&quot; (type (eq $metadata_from_shared)))
    (export &quot;get&quot; (func (result $metadata_in_host)))
  ))
)
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Here it can be seen that despite the &lt;code&gt;world&lt;/code&gt; only listing &lt;code&gt;host&lt;/code&gt; as an import&lt;br&gt; the component additionally imports a &lt;code&gt;local:demo/shared&lt;/code&gt; interface. This is due&lt;br&gt; to the fact that the &lt;code&gt;use shared.{ ... }&lt;/code&gt; implicitly requires that &lt;code&gt;shared&lt;/code&gt; is&lt;br&gt; imported into the component as well.&lt;/p&gt; 
&lt;p&gt;Note that the name &lt;code&gt;&quot;local:demo/shared&quot;&lt;/code&gt; here is derived from the name of the&lt;br&gt; &lt;code&gt;interface&lt;/code&gt; plus the package name &lt;code&gt;local:demo&lt;/code&gt;.&lt;/p&gt; 
&lt;p&gt;For &lt;code&gt;export&lt;/code&gt;ed interfaces, any transitively &lt;code&gt;use&lt;/code&gt;d interface is assumed to be an&lt;br&gt; import unless it&apos;s explicitly listed as an export. For example, here &lt;code&gt;w1&lt;/code&gt; is&lt;br&gt; equivalent to &lt;code&gt;w2&lt;/code&gt;:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-wit&quot;&gt;interface a {
    resource r;
}
interface b {
    use a.{r};
    foo: func() -&amp;gt; r;
}

world w1 {
    export b;
}
world w2 {
    import a;
    export b;
}
&lt;/code&gt;&lt;/pre&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: It&apos;s planned in the future to have &quot;power user syntax&quot; to configure&lt;br&gt; this on a more fine-grained basis for exports, for example being able to&lt;br&gt; configure that a &lt;code&gt;use&lt;/code&gt;&apos;d interface is a particular import or a particular&lt;br&gt; export.&lt;/p&gt; 
&lt;/blockquote&gt; 
&lt;h2&gt;WIT Functions&lt;/h2&gt; 
&lt;p&gt;Functions are defined in an &lt;a href=&quot;#wit-interfaces&quot;&gt;&lt;code&gt;interface&lt;/code&gt;&lt;/a&gt; or are listed as an&lt;br&gt; &lt;code&gt;import&lt;/code&gt; or &lt;code&gt;export&lt;/code&gt; from a &lt;a href=&quot;#wit-worlds&quot;&gt;&lt;code&gt;world&lt;/code&gt;&lt;/a&gt;. Parameters to a function must all&lt;br&gt; be named and have case-insensitively unique names:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-wit&quot;&gt;package local:demo;

interface foo {
    a1: func();
    a2: func(x: u32);
    a3: func(y: u64, z: f32);
}
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Functions can optionally return a type:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-wit&quot;&gt;package local:demo;

interface foo {
    a1: func() -&amp;gt; u32;
    a2: func() -&amp;gt; string;
}
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Multiple return values can be achieved via &lt;code&gt;tuple&lt;/code&gt; or &lt;code&gt;record&lt;/code&gt; type:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-wit&quot;&gt;package local:demo;

interface foo {
    record r {
      a: u32,
      b: f32
    }

    a1: func() -&amp;gt; r;
    a2: func() -&amp;gt; tuple&amp;lt;u32, f32&amp;gt;;
}
&lt;/code&gt;&lt;/pre&gt; 
&lt;h2&gt;WIT Types&lt;/h2&gt; 
&lt;p&gt;Types in WIT files can only be defined in &lt;a href=&quot;#wit-interfaces&quot;&gt;&lt;code&gt;interface&lt;/code&gt;s&lt;/a&gt; at this&lt;br&gt; time. The types supported in WIT is the same set of types supported in the&lt;br&gt; component model itself:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-wit&quot;&gt;package local:demo;

interface foo {
    // &quot;package of named fields&quot;
    record r {
      a: u32,
      b: string,
    }

    // values of this type will be one of the specified cases
    variant human {
      baby,
      child(u32), // optional type payload
      adult,
    }

    // similar to `variant`, but no type payloads
    enum errno {
      too-big,
      too-small,
      too-fast,
      too-slow,
    }

    // a bitflags type
    flags permissions {
      read,
      write,
      exec,
    }

    // type aliases are allowed to primitive types and additionally here are some
    // examples of other types
    type t1 = u32;
    type t2 = tuple&amp;lt;u32, u64&amp;gt;;
    type t3 = string;
    type t4 = option&amp;lt;u32&amp;gt;;
    type t5 = result&amp;lt;_, errno&amp;gt;;           // no &quot;ok&quot; type
    type t6 = result&amp;lt;string&amp;gt;;             // no &quot;err&quot; type
    type t7 = result&amp;lt;char, errno&amp;gt;;        // both types specified
    type t8 = result;                     // no &quot;ok&quot; or &quot;err&quot; type
    type t9 = list&amp;lt;string&amp;gt;;
    type t10 = t9;
}
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;The &lt;code&gt;record&lt;/code&gt;, &lt;code&gt;variant&lt;/code&gt;, &lt;code&gt;enum&lt;/code&gt;, and &lt;code&gt;flags&lt;/code&gt; types must all have names&lt;br&gt; associated with them. The &lt;code&gt;list&lt;/code&gt;, &lt;code&gt;option&lt;/code&gt;, &lt;code&gt;result&lt;/code&gt;, &lt;code&gt;tuple&lt;/code&gt;, and primitive&lt;br&gt; types do not need a name and can be mentioned in any context. This restriction&lt;br&gt; is in place to assist with code generation in all languages to leverage&lt;br&gt; language-builtin types where possible while accommodating types that need to be&lt;br&gt; defined within each language as well.&lt;/p&gt; 
&lt;h2&gt;WIT Identifiers&lt;/h2&gt; 
&lt;p&gt;Identifiers in WIT can be defined with two different forms. The first is the&lt;br&gt; &lt;a href=&quot;https://en.wikipedia.org/wiki/Letter_case#Kebab_case&quot;&gt;kebab-case&lt;/a&gt; &lt;a href=&quot;Explainer.md#import-and-export-names&quot;&gt;&lt;code&gt;label&lt;/code&gt;&lt;/a&gt; production in the&lt;br&gt; Component Model text format.&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-wit&quot;&gt;foo: func(bar: u32);

red-green-blue: func(r: u32, g: u32, b: u32);

resource XML { ... }
parse-XML-document: func(s: string) -&amp;gt; XML;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;This form can&apos;t lexically represent WIT &lt;a href=&quot;#keywords&quot;&gt;keywords&lt;/a&gt;, so the second form is the&lt;br&gt; same syntax with the same restrictions as the first, but prefixed with &apos;%&apos;:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-wit&quot;&gt;%foo: func(%bar: u32);

%red-green-blue: func(%r: u32, %g: u32, %b: u32);

// This form also supports identifiers that would otherwise be keywords.
%variant: func(%enum: s32);
&lt;/code&gt;&lt;/pre&gt; 
&lt;h1&gt;Filesystem structure&lt;/h1&gt; 
&lt;p&gt;WIT supports multiple &lt;code&gt;package&lt;/code&gt;s and the ability to define a single package&lt;br&gt; across many files, and this section is intended to set a number of conventions&lt;br&gt; for WIT-processing tooling to conform to.&lt;/p&gt; 
&lt;p&gt;This won&apos;t go into the specific details of any one particular tool and you&lt;br&gt; should consult tooling-specific documentation for more detailed information&lt;br&gt; about exactly how to configure a WIT parser. This will, however use the Rust&lt;br&gt; guest &lt;code&gt;wit-bindgen&lt;/code&gt; crate as an example to have a concrete example to link to,&lt;br&gt; but this is intended to be translatable to other examples and bindings&lt;br&gt; generators as well.&lt;/p&gt; 
&lt;h2&gt;Specifying a &quot;Root Package&quot;&lt;/h2&gt; 
&lt;p&gt;To start out when processing WIT a package needs to be conceptually considered&lt;br&gt; the &quot;root package&quot;. This is used down below in &lt;code&gt;world&lt;/code&gt; selection and the&lt;br&gt; conventional processing of WIT is intended to currently generally have a package&lt;br&gt; as the &quot;default&quot; for lookups. A root package is specified via a path on the&lt;br&gt; filesystem to either a file or directory. Lookup of dependencies and of this&lt;br&gt; package happen differently depending if it&apos;s a file or directory.&lt;/p&gt; 
&lt;h3&gt;Root Package: A File&lt;/h3&gt; 
&lt;p&gt;When the root package is a single file then it means that file contains all WIT&lt;br&gt; that is going to be parsed. No further file discovery on the filesystem will&lt;br&gt; happen and after the file is read then no more filesystem interaction will be&lt;br&gt; happening.&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-rust&quot;&gt;wit_bindgen::generate!(&quot;./my.wit&quot;);
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;To be a valid WIT file the file being parsed must have a leading &lt;code&gt;package ...;&lt;/code&gt;&lt;br&gt; statement meaning that it&apos;s now the &quot;root package&quot;. Dependencies of this package&lt;br&gt; must be specified inline with &lt;code&gt;package ... { ... }&lt;/code&gt; blocks when using this&lt;br&gt; format.&lt;/p&gt; 
&lt;p&gt;Some tooling may support the ability to load multiple &quot;roots&quot; which means that&lt;br&gt; the final root is used for &lt;code&gt;world&lt;/code&gt; selection and the other roots are used to&lt;br&gt; load dependencies. This can be used when you don&apos;t necessarily have full control&lt;br&gt; over filesystem structure and need to load dependencies from a possibly&lt;br&gt; non-standard location.&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-rust&quot;&gt;// here `deps.wit` will be available when parsing `my.wit` for dependency
// resolution.
wit_bindgen::generate!({
    path: [&quot;./deps.wit&quot;, &quot;./my.wit&quot;],
});
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Note that specifying a file is not the only option for organizing WIT bindings.&lt;br&gt; Below can be a more maintainable strategy with WIT files separate from each&lt;br&gt; other. A single file can be useful when tooling manages WIT for you, but&lt;br&gt; handwritten WIT may often prefer to use a directory.&lt;/p&gt; 
&lt;h3&gt;Root Package: A Directory&lt;/h3&gt; 
&lt;p&gt;When the root package is a directory then it means the filesystem structure of&lt;br&gt; that directory will be traversed to look for WIT to load. A directory not only&lt;br&gt; supports splitting a single package across multiple files on the filesystem but&lt;br&gt; it also enables having all dependencies located within the directory as well.&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-rust&quot;&gt;wit_bindgen::generate!(&quot;./wit&quot;);
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;This example will parse the directory &lt;code&gt;./wit&lt;/code&gt; and look for WIT files. The&lt;br&gt; parsing process first looks at all &lt;code&gt;*.wit&lt;/code&gt; files inside the directory itself.&lt;br&gt; This collection of &lt;code&gt;*.wit&lt;/code&gt; files will be combined together to form the &quot;root&lt;br&gt; package&quot;. No other files will be considered for the &quot;root package&quot;. For example&lt;br&gt; though you could have this filesystem structure.&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-rust&quot;&gt;wit/
    types.wit
    world.wit
    my-interface.wit
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Here &lt;code&gt;types.wit&lt;/code&gt;, &lt;code&gt;world.wit&lt;/code&gt;, and &lt;code&gt;my-interface.wit&lt;/code&gt; would all be parsed&lt;br&gt; together as a single package.&lt;/p&gt; 
&lt;p&gt;Dependencies in the directory format of the filesystem are specified in a &lt;code&gt;deps&lt;/code&gt;&lt;br&gt; folder within the root folder. Above for example dependencies would be specified&lt;br&gt; in &lt;code&gt;wit/deps&lt;/code&gt;. Dependencies are specified in a flat format where each dependency&lt;br&gt; may itself be a file or a directory, but directories do not have recursive&lt;br&gt; &lt;code&gt;deps&lt;/code&gt; folders. The name of files/folders used for organization within a&lt;br&gt; directory are not used during parsing and are purely meant for human-read&lt;br&gt; organization.&lt;/p&gt; 
&lt;p&gt;For example we can extend our above &lt;code&gt;wit/&lt;/code&gt; folder like so:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-rust&quot;&gt;wit/
    types.wit
    world.wit
    my-interface.wit

    deps/
        my-dependency.wit
        wasi:clocks/
            types.wit
            world.wit
        wasi:clocks@0.3.0-pre/
            types.wit
            world.wit
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;The name &lt;code&gt;my-dependency&lt;/code&gt; in &lt;code&gt;my-dependency.wit&lt;/code&gt;, as well as &lt;code&gt;wasi:clocks&lt;/code&gt; in&lt;br&gt; &lt;code&gt;wasi:clocks/&lt;/code&gt;, is arbitrary. This distinguishes one dependency from another but&lt;br&gt; is only used for uniqueness on the filesystem.&lt;/p&gt; 
&lt;p&gt;All dependencies in &lt;code&gt;deps&lt;/code&gt; will be loaded and processed in topological order.&lt;br&gt; The &lt;code&gt;my-dependency.wit&lt;/code&gt; file may, for example, depend on &lt;code&gt;wasi:clocks/&lt;/code&gt;.&lt;br&gt; Additionally &lt;code&gt;my-dependency.wit&lt;/code&gt; may have its own inline &lt;code&gt;package .. { ... }&lt;/code&gt;&lt;br&gt; blocks too which define packages available for dependency resolution. Any&lt;br&gt; package which is duplicated across dependencies must have the same contents.&lt;/p&gt; 
&lt;h2&gt;Specifying a World&lt;/h2&gt; 
&lt;p&gt;The primary unit of bindings generation for WIT tooling is a &lt;code&gt;world&lt;/code&gt; which means&lt;br&gt; that various phases of the process must take a &lt;code&gt;world&lt;/code&gt; input. For example when&lt;br&gt; generating guest bindings within a language you&apos;ll be specifying a &lt;code&gt;world&lt;/code&gt; as&lt;br&gt; the unit of bindings generation. WIT tooling should follow these conventions for&lt;br&gt; selecting a world:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Inputs to world selection are a &quot;root package&quot; (what was parsed from the WIT&lt;br&gt; path specified) as well as an optional world string.&lt;/li&gt; 
 &lt;li&gt;If the world string is not present, then the root package must have a single&lt;br&gt; world in it. If so that world is used for bindings generation.&lt;/li&gt; 
 &lt;li&gt;If the world string is a WIT identifier, then it specifies the name of a world&lt;br&gt; in the root package to use for bindings generation.&lt;/li&gt; 
 &lt;li&gt;If the world string is a WIT path, such as &lt;code&gt;a:b/c&lt;/code&gt;, then that is a&lt;br&gt; fully-qualified path which can be used to select a world in the dependencies&lt;br&gt; for bindings generation as well.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;If the above heuristics all fail then bindings generation fails and a different&lt;br&gt; combination of arguments must be passed to select a world for bindings&lt;br&gt; generation.&lt;/p&gt; 
&lt;h1&gt;Lexical structure&lt;/h1&gt; 
&lt;p&gt;The &lt;code&gt;wit&lt;/code&gt; format is a curly-braced-based format where whitespace is optional (but&lt;br&gt; recommended). A &lt;code&gt;wit&lt;/code&gt; document is parsed as a unicode string, and when stored in&lt;br&gt; a file is expected to be encoded as utf-8.&lt;/p&gt; 
&lt;p&gt;Additionally, wit files must not contain any bidirectional override scalar&lt;br&gt; values, control codes other than newline, carriage return, and horizontal tab,&lt;br&gt; or codepoints that Unicode officially deprecates or strongly discourages.&lt;/p&gt; 
&lt;p&gt;The current structure of tokens are:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-ebnf&quot;&gt;token ::= whitespace
        | operator
        | keyword
        | integer
        | identifier
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Whitespace and comments are ignored when parsing structures defined elsewhere&lt;br&gt; here.&lt;/p&gt; 
&lt;h3&gt;Whitespace&lt;/h3&gt; 
&lt;p&gt;A &lt;code&gt;whitespace&lt;/code&gt; token in &lt;code&gt;wit&lt;/code&gt; is a space, a newline, a carriage return, a&lt;br&gt; tab character, or a comment:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-ebnf&quot;&gt;whitespace ::= &apos; &apos; | &apos;\n&apos; | &apos;\r&apos; | &apos;\t&apos; | comment
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;Comments&lt;/h3&gt; 
&lt;p&gt;A &lt;code&gt;comment&lt;/code&gt; token in &lt;code&gt;wit&lt;/code&gt; is either a line comment preceded with &lt;code&gt;//&lt;/code&gt; which&lt;br&gt; ends at the next newline (&lt;code&gt;\n&lt;/code&gt;) character or it&apos;s a block comment which starts&lt;br&gt; with &lt;code&gt;/*&lt;/code&gt; and ends with &lt;code&gt;*/&lt;/code&gt;. Note that block comments are allowed to be nested&lt;br&gt; and their delimiters must be balanced&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-ebnf&quot;&gt;comment ::= &apos;//&apos; character-that-isnt-a-newline*
          | &apos;/*&apos; any-unicode-character* &apos;*/&apos;
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;Operators&lt;/h3&gt; 
&lt;p&gt;There are some common operators in the lexical structure of &lt;code&gt;wit&lt;/code&gt; used for&lt;br&gt; various constructs. Note that delimiters such as &lt;code&gt;{&lt;/code&gt; and &lt;code&gt;(&lt;/code&gt; must all be&lt;br&gt; balanced.&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-ebnf&quot;&gt;operator ::= &apos;=&apos; | &apos;,&apos; | &apos;:&apos; | &apos;;&apos; | &apos;(&apos; | &apos;)&apos; | &apos;{&apos; | &apos;}&apos; | &apos;&amp;lt;&apos; | &apos;&amp;gt;&apos; | &apos;*&apos; | &apos;-&amp;gt;&apos; | &apos;/&apos; | &apos;.&apos; | &apos;@&apos;
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;Keywords&lt;/h3&gt; 
&lt;p&gt;Certain identifiers are reserved for use in WIT documents and cannot be used&lt;br&gt; bare as an identifier. These are used to help parse the format, and the list of&lt;br&gt; keywords is still in flux at this time but the current set is:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-ebnf&quot;&gt;keyword ::= &apos;as&apos;
          | &apos;async&apos;
          | &apos;bool&apos;
          | &apos;borrow&apos;
          | &apos;char&apos;
          | &apos;constructor&apos;
          | &apos;enum&apos;
          | &apos;export&apos;
          | &apos;f32&apos;
          | &apos;f64&apos;
          | &apos;flags&apos;
          | &apos;from&apos;
          | &apos;func&apos;
          | &apos;future&apos;
          | &apos;import&apos;
          | &apos;include&apos;
          | &apos;interface&apos;
          | &apos;list&apos;
          | &apos;option&apos;
          | &apos;own&apos;
          | &apos;package&apos;
          | &apos;record&apos;
          | &apos;resource&apos;
          | &apos;result&apos;
          | &apos;s16&apos;
          | &apos;s32&apos;
          | &apos;s64&apos;
          | &apos;s8&apos;
          | &apos;static&apos;
          | &apos;stream&apos;
          | &apos;string&apos;
          | &apos;tuple&apos;
          | &apos;type&apos;
          | &apos;u16&apos;
          | &apos;u32&apos;
          | &apos;u64&apos;
          | &apos;u8&apos;
          | &apos;use&apos;
          | &apos;variant&apos;
          | &apos;with&apos;
          | &apos;world&apos;
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;Integers&lt;/h3&gt; 
&lt;p&gt;Integers are currently only used for package versions and are a contiguous&lt;br&gt; sequence of digits:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-ebnf&quot;&gt;integer ::= [0-9]+
&lt;/code&gt;&lt;/pre&gt; 
&lt;h2&gt;Top-level items&lt;/h2&gt; 
&lt;p&gt;A &lt;code&gt;wit&lt;/code&gt; document is a sequence of items specified at the top level. These items&lt;br&gt; come one after another and it&apos;s recommended to separate them with newlines for&lt;br&gt; readability but this isn&apos;t required.&lt;/p&gt; 
&lt;p&gt;Concretely, the structure of a &lt;code&gt;wit&lt;/code&gt; file is:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-ebnf&quot;&gt;wit-file ::= (package-decl &apos;;&apos;)? (package-items | nested-package-definition)*

nested-package-definition ::= package-decl &apos;{&apos; package-items* &apos;}&apos;

package-items ::= toplevel-use-item | interface-item | world-item
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Essentially, these top level items are &lt;a href=&quot;#wit-worlds&quot;&gt;worlds&lt;/a&gt;, &lt;a href=&quot;#wit-interfaces&quot;&gt;interfaces&lt;/a&gt;, &lt;a href=&quot;#wit-packages-and-use&quot;&gt;use statements&lt;/a&gt; and other package definitions.&lt;/p&gt; 
&lt;h3&gt;Feature Gates&lt;/h3&gt; 
&lt;p&gt;Various WIT items can be &quot;gated&quot;, to reflect the fact that the item is part of&lt;br&gt; an unstable feature, that the item was added as part of a minor version&lt;br&gt; update and shouldn&apos;t be used when targeting an earlier minor version, or that a&lt;br&gt; feature has been deprecated and should no longer be used.&lt;/p&gt; 
&lt;p&gt;For example, the following interface has 4 items, 3 of which are gated:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-wit&quot;&gt;interface foo {
    a: func();

    @since(version = 0.2.1)
    b: func();

    @since(version = 0.2.2)
    c: func();

    @unstable(feature = fancier-foo)
    d: func();

    @since(version = 0.2.0)
    @deprecated(version = 0.2.2)
    e: func();
}
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;The &lt;code&gt;@since&lt;/code&gt; gate indicates that &lt;code&gt;b&lt;/code&gt; and &lt;code&gt;c&lt;/code&gt; were added as part of the &lt;code&gt;0.2.1&lt;/code&gt;&lt;br&gt; and &lt;code&gt;0.2.2&lt;/code&gt; releases, resp. Thus, when building a component targeting, e.g.,&lt;br&gt; &lt;code&gt;0.2.1&lt;/code&gt;, &lt;code&gt;b&lt;/code&gt; can be used, but &lt;code&gt;c&lt;/code&gt; cannot. An important expectation set by the&lt;br&gt; &lt;code&gt;@since&lt;/code&gt; gate is that, once applied to an item, the item is not modified&lt;br&gt; incompatibly going forward (according to general semantic versioning rules).&lt;/p&gt; 
&lt;p&gt;In contrast, the &lt;code&gt;@unstable&lt;/code&gt; gate on &lt;code&gt;d&lt;/code&gt; indicates that &lt;code&gt;d&lt;/code&gt; is part of the&lt;br&gt; &lt;code&gt;fancier-foo&lt;/code&gt; feature that is still under active development and thus &lt;code&gt;d&lt;/code&gt; may&lt;br&gt; change type or be removed at any time. An important expectation set by the&lt;br&gt; &lt;code&gt;@unstable&lt;/code&gt; gate is that toolchains will not expose &lt;code&gt;@unstable&lt;/code&gt; features by&lt;br&gt; default unless explicitly opted-into by the developer.&lt;/p&gt; 
&lt;p&gt;Finally, the &lt;code&gt;@deprecated&lt;/code&gt; gate on &lt;code&gt;e&lt;/code&gt; indicates that &lt;code&gt;e&lt;/code&gt; should no longer be&lt;br&gt; used starting version &lt;code&gt;0.2.2&lt;/code&gt;. Both toolchains and host runtimes may warn users&lt;br&gt; if they detect an &lt;code&gt;@deprecated&lt;/code&gt; API is being used. A &lt;code&gt;@deprecated&lt;/code&gt; gate is&lt;br&gt; required to always be paired up with either a &lt;code&gt;@since&lt;/code&gt; or &lt;code&gt;@deprecated&lt;/code&gt; gate.&lt;/p&gt; 
&lt;p&gt;Together, these gates support a development flow in which new features start&lt;br&gt; with an &lt;code&gt;@unstable&lt;/code&gt; gate while the details are still being hashed out. Then,&lt;br&gt; once the feature is stable (and, in a WASI context, voted upon), the&lt;br&gt; &lt;code&gt;@unstable&lt;/code&gt; gate is switched to a &lt;code&gt;@since&lt;/code&gt; gate.&lt;/p&gt; 
&lt;h4&gt;Feature gate syntax&lt;/h4&gt; 
&lt;p&gt;The grammar that governs feature gate syntax is:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-wit&quot;&gt;gate ::= gate-item*
gate-item ::= unstable-gate
            | since-gate
            | deprecated-gate

unstable-gate ::= &apos;@unstable&apos; &apos;(&apos; feature-field &apos;)&apos;
since-gate ::= &apos;@since&apos; &apos;(&apos; version-field &apos;)&apos;
deprecated-gate ::= &apos;@deprecated&apos; &apos;(&apos; version-field &apos;)&apos;

feature-field ::= &apos;feature&apos; &apos;=&apos; id
version-field ::= &apos;version&apos; &apos;=&apos; &amp;lt;valid semver&amp;gt;
&lt;/code&gt;&lt;/pre&gt; 
&lt;h4&gt;Rules for feature gate usage&lt;/h4&gt; 
&lt;p&gt;As part of WIT validation, any item that refers to another gated item must also&lt;br&gt; be compatibly gated. For example, this is an error:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-wit&quot;&gt;interface i {
    @since(version = 1.0.1)
    type t1 = u32;

    type t2 = t1; // error
}
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Additionally, if an item is &lt;em&gt;contained&lt;/em&gt; by a gated item, it must also be&lt;br&gt; compatibly gated. For example, this is an error:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-wit&quot;&gt;@since(version = 1.0.2)
interface i {
    foo: func();  // error: no gate

    @since(version = 1.0.1)
    bar: func();  // also error: weaker gate
}
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;The following rules apply to the use of feature gates:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Either &lt;code&gt;@since&lt;/code&gt; &lt;em&gt;or&lt;/em&gt; &lt;code&gt;@unstable&lt;/code&gt; should be used, but not both (exclusive or).&lt;/li&gt; 
 &lt;li&gt;If a package contains a feature gate, it&apos;s version must be specified (i.e. &lt;code&gt;namespace:package@x.y.z&lt;/code&gt;)&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;Scenario: Stabilization of a new feature&lt;/h4&gt; 
&lt;p&gt;This section lays out the basic flow and expected usage of feature gate machinery&lt;br&gt; when stabilizing new features and deprecating old ones.&lt;/p&gt; 
&lt;p&gt;Assume the following WIT package as the initial interface:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-wit&quot;&gt;package examples:fgates-calc@0.1.0;

@since(version = 0.1.0)
interface calc {
    @since(version = 0.1.0)
    variant calc-error {
      integer-overflow,
      integer-underflow,
      unexpected,
    }

    @since(version = 0.1.0)
    add: func(x: s32, y: s32) -&amp;gt; result&amp;lt;s32, calc-error&amp;gt;;
}
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;&lt;strong&gt;First, add new items under an &lt;code&gt;@unstable&lt;/code&gt; annotation with a &lt;code&gt;feature&lt;/code&gt; specified:&lt;/strong&gt;&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-wit&quot;&gt;package examples:fgates-calc@0.1.1;

@since(version = 0.1.0)
interface calc {
    @since(version = 0.1.0)
    variant calc-error {
      integer-overflow,
      integer-underflow,
      unexpected,
    }

    @since(version = 0.1.0)
    add: func(x: s32, y: s32) -&amp;gt; result&amp;lt;s32, calc-error&amp;gt;;

    /// By convention, feature flags should be prefixed with package name to reduce chance of collisions
    ///
    /// see: https://github.com/WebAssembly/WASI/blob/main/Contributing.md#filing-changes-to-existing-phase-3-proposals
    @unstable(feature = fgates-calc-minus)
    sub: func(x: s32, y: s32) -&amp;gt; result&amp;lt;s32, calc-error&amp;gt;;
}
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;At this point, consumers of the WIT can enable feature &lt;code&gt;fgates-calc-minus&lt;/code&gt; through their relevant tooling and get access to the &lt;code&gt;sub&lt;/code&gt; function.&lt;/p&gt; 
&lt;p&gt;Note that, at least until subtyping is relaxed in the Component Model, if we had to &lt;em&gt;add&lt;/em&gt; a new case to &lt;code&gt;calc-error&lt;/code&gt;, this would be a &lt;em&gt;breaking change&lt;/em&gt; and require either a new major version or adding a second, distinct &lt;code&gt;variant&lt;/code&gt; definition used by new functions.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Second, when the feature is ready to be stabilized, switch to a &lt;code&gt;@since&lt;/code&gt; annotation:&lt;/strong&gt;&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-wit&quot;&gt;package examples:fgates-calc@0.1.2;

@since(version = 0.1.0)
interface calc {
    @since(version = 0.1.0)
    variant calc-error {
      integer-overflow,
      integer-underflow,
      unexpected,
    }

    @since(version = 0.1.0)
    add: func(x: s32, y: s32) -&amp;gt; result&amp;lt;s32, calc-error&amp;gt;;

    @since(version = 0.1.2)
    sub: func(x: s32, y: s32) -&amp;gt; result&amp;lt;s32, calc-error&amp;gt;;
}
&lt;/code&gt;&lt;/pre&gt; 
&lt;h4&gt;Scenario: Deprecation of an existing stable feature&lt;/h4&gt; 
&lt;p&gt;This section lays out the basic flow and expected usage of feature gate machinery when stabilizing a new feature.&lt;/p&gt; 
&lt;p&gt;Assume the following WIT package as the initial interface:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-wit&quot;&gt;package examples:fgates-deprecation@0.1.1;

@since(version = 0.1.0)
interface calc {
    @since(version = 0.1.0)
    variant calc-error {
      integer-overflow,
      integer-underflow,
      unexpected,
    }

    @since(version = 0.1.0)
    add-one: func(x: s32) -&amp;gt; result&amp;lt;s32, calc-error&amp;gt;;

    @since(version = 0.1.1)
    add: func(x: s32, y: s32) -&amp;gt; result&amp;lt;s32, calc-error&amp;gt;;
}
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;&lt;strong&gt;First: Add the &lt;code&gt;@deprecated&lt;/code&gt; annotation to the relevant item in a new version&lt;/strong&gt;&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-wit&quot;&gt;package examples:fgates-deprecation@0.1.2;

@since(version = 0.1.0)
interface calc {
    @since(version = 0.1.0)
    variant calc-error {
      integer-overflow,
      integer-underflow,
      unexpected,
    }

    @deprecated(version = 0.1.2)
    add-one: func(x: s32) -&amp;gt; result&amp;lt;s32, calc-error&amp;gt;;

    @since(version = 0.1.1)
    add: func(x: s32, y: s32) -&amp;gt; result&amp;lt;s32, calc-error&amp;gt;;
}
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;At this point, tooling consuming this WIT will be able to appropriately alert users to the now-deprecated &lt;code&gt;add-one&lt;/code&gt; function.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Second: completely remove the deprecated item in some future SemVer-compliant major version&lt;/strong&gt;&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-wit&quot;&gt;package examples:fgates-deprecation@0.2.0;

@since(version = 0.1.0)
interface calc {
    @since(version = 0.1.0)
    variant calc-error {
      integer-overflow,
      integer-underflow,
      unexpected,
    }

    @since(version = 0.1.1)
    add: func(x: s32, y: s32) -&amp;gt; result&amp;lt;s32, calc-error&amp;gt;;
}
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;In this new &quot;major&quot; version (this is considered a major version under SemVer 0.X rules) -- the &lt;code&gt;add-one&lt;/code&gt; function can be fully removed.&lt;/p&gt; 
&lt;h2&gt;Package declaration&lt;/h2&gt; 
&lt;p&gt;WIT files optionally start with a package declaration which defines the name of&lt;br&gt; the package.&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-ebnf&quot;&gt;package-decl        ::= &apos;package&apos; ( id &apos;:&apos; )+ id ( &apos;/&apos; id )* (&apos;@&apos; valid-semver)?
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;The production &lt;code&gt;valid-semver&lt;/code&gt; is as defined by&lt;br&gt; &lt;a href=&quot;https://semver.org/&quot;&gt;Semantic Versioning 2.0&lt;/a&gt; and optional.&lt;/p&gt; 
&lt;h2&gt;Item: &lt;code&gt;toplevel-use&lt;/code&gt;&lt;/h2&gt; 
&lt;p&gt;A &lt;code&gt;use&lt;/code&gt; statement at the top-level of a file can be used to bring interfaces&lt;br&gt; into the scope of the current file and/or rename interfaces locally for&lt;br&gt; convenience:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-ebnf&quot;&gt;toplevel-use-item ::= &apos;use&apos; use-path (&apos;as&apos; id)? &apos;;&apos;

use-path ::= id
           | id &apos;:&apos; id &apos;/&apos; id (&apos;@&apos; valid-semver)?
           | ( id &apos;:&apos; )+ id ( &apos;/&apos; id )+ (&apos;@&apos; valid-semver)? 🪺
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Here &lt;code&gt;use-path&lt;/code&gt; is an &lt;a href=&quot;Explainer.md#import-and-export-definitions&quot;&gt;interface name&lt;/a&gt;. The bare form &lt;code&gt;id&lt;/code&gt;&lt;br&gt; refers to interfaces defined within the current package, and the full form&lt;br&gt; refers to interfaces in package dependencies.&lt;/p&gt; 
&lt;p&gt;The &lt;code&gt;as&lt;/code&gt; syntax can be optionally used to specify a name that should be assigned&lt;br&gt; to the interface. Otherwise the name is inferred from &lt;code&gt;use-path&lt;/code&gt;.&lt;/p&gt; 
&lt;p&gt;As a future extension, WIT, components and component registries may allow&lt;br&gt; nesting both namespaces and packages, which would then generalize the syntax of&lt;br&gt; &lt;code&gt;use-path&lt;/code&gt; as suggested by the 🪺 suffixed rule.&lt;/p&gt; 
&lt;h2&gt;Item: &lt;code&gt;world&lt;/code&gt;&lt;/h2&gt; 
&lt;p&gt;Worlds define a &lt;a href=&quot;Explainer.md#type-definitions&quot;&gt;&lt;code&gt;componenttype&lt;/code&gt;&lt;/a&gt; as a collection of imports and exports, all&lt;br&gt; of which can be gated.&lt;/p&gt; 
&lt;p&gt;Concretely, the structure of a world is:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-ebnf&quot;&gt;world-item ::= gate &apos;world&apos; id &apos;{&apos; world-items* &apos;}&apos;

world-items ::= gate world-definition

world-definition ::= export-item
                   | import-item
                   | use-item
                   | typedef-item
                   | include-item

export-item ::= &apos;export&apos; id &apos;:&apos; extern-type
              | &apos;export&apos; use-path &apos;;&apos;
import-item ::= &apos;import&apos; id &apos;:&apos; extern-type
              | &apos;import&apos; use-path &apos;;&apos;

extern-type ::= func-type &apos;;&apos; | &apos;interface&apos; &apos;{&apos; interface-items* &apos;}&apos;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Note that worlds can import types and define their own types to be exported&lt;br&gt; from the root of a component and used within functions imported and exported.&lt;br&gt; The &lt;code&gt;interface&lt;/code&gt; item here additionally defines the grammar for IDs used to refer&lt;br&gt; to &lt;code&gt;interface&lt;/code&gt; items.&lt;/p&gt; 
&lt;h2&gt;Item: &lt;code&gt;include&lt;/code&gt;&lt;/h2&gt; 
&lt;p&gt;A &lt;code&gt;include&lt;/code&gt; statement enables the union of the current world with another world. The structure of an &lt;code&gt;include&lt;/code&gt; statement is:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-wit&quot;&gt;include wasi:io/my-world-1 with { a as a1, b as b1 };
include my-world-2;
&lt;/code&gt;&lt;/pre&gt; 
&lt;pre&gt;&lt;code class=&quot;language-ebnf&quot;&gt;include-item ::= &apos;include&apos; use-path &apos;;&apos;
               | &apos;include&apos; use-path &apos;with&apos; &apos;{&apos; include-names-list &apos;}&apos;

include-names-list ::= include-names-item
                     | include-names-list &apos;,&apos; include-names-item

include-names-item ::= id &apos;as&apos; id
&lt;/code&gt;&lt;/pre&gt; 
&lt;h2&gt;Item: &lt;code&gt;interface&lt;/code&gt;&lt;/h2&gt; 
&lt;p&gt;Interfaces can be defined in a &lt;code&gt;wit&lt;/code&gt; file. Interfaces have a name and a&lt;br&gt; sequence of items and functions, all of which can be gated.&lt;/p&gt; 
&lt;p&gt;Specifically interfaces have the structure:&lt;/p&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: The symbol &lt;code&gt;ε&lt;/code&gt;, also known as Epsilon, denotes an empty string.&lt;/p&gt; 
&lt;/blockquote&gt; 
&lt;pre&gt;&lt;code class=&quot;language-ebnf&quot;&gt;interface-item ::= gate &apos;interface&apos; id &apos;{&apos; interface-items* &apos;}&apos;

interface-items ::= gate interface-definition

interface-definition ::= typedef-item
                       | use-item
                       | func-item

typedef-item ::= resource-item
               | variant-items
               | record-item
               | flags-items
               | enum-items
               | type-item

func-item ::= id &apos;:&apos; func-type &apos;;&apos;

func-type ::= &apos;async&apos;? &apos;func&apos; param-list result-list

param-list ::= &apos;(&apos; named-type-list &apos;)&apos;

result-list ::= ϵ
              | &apos;-&amp;gt;&apos; ty

named-type-list ::= ϵ
                  | named-type ( &apos;,&apos; named-type )*

named-type ::= id &apos;:&apos; ty
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;The optional &lt;code&gt;async&lt;/code&gt; hint in a WIT function type indicates that the callee&lt;br&gt; is expected to block and thus the caller should emit whatever asynchronous&lt;br&gt; language bindings are appropriate (e.g., in JS, Python, C# or Rust, an &lt;code&gt;async&lt;/code&gt;&lt;br&gt; WIT function would emit an &lt;code&gt;async&lt;/code&gt; JS/Python/C#/Rust function). Because &lt;code&gt;async&lt;/code&gt;&lt;br&gt; is just a hint and not enforced by the runtime, it is technically possible for&lt;br&gt; a non-&lt;code&gt;async&lt;/code&gt; callee to block. In that case, though, it is the &lt;em&gt;callee&apos;s&lt;/em&gt; fault&lt;br&gt; for any resultant loss of concurrency, not the caller&apos;s. Thus, &lt;code&gt;async&lt;/code&gt; is&lt;br&gt; primarily intended to document expectations in a way that can be taken&lt;br&gt; advantage of by bindings generators. (For more details, see the &lt;a href=&quot;Async.md#sync-and-async-functions&quot;&gt;async&lt;br&gt; explainer&lt;/a&gt;.)&lt;/p&gt; 
&lt;h2&gt;Item: &lt;code&gt;use&lt;/code&gt;&lt;/h2&gt; 
&lt;p&gt;A &lt;code&gt;use&lt;/code&gt; statement enables importing type or resource definitions from other&lt;br&gt; wit packages or interfaces. The structure of a use statement is:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-wit&quot;&gt;use an-interface.{a, list, of, names}
use my:dependency/the-interface.{more, names as foo}
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Specifically the structure of this is:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-ebnf&quot;&gt;use-item ::= &apos;use&apos; use-path &apos;.&apos; &apos;{&apos; use-names-list &apos;}&apos; &apos;;&apos;

use-names-list ::= use-names-item
                 | use-names-item &apos;,&apos; use-names-list?

use-names-item ::= id
                 | id &apos;as&apos; id
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Note: Here &lt;code&gt;use-names-list?&lt;/code&gt; means at least one &lt;code&gt;use-name-list&lt;/code&gt; term.&lt;/p&gt; 
&lt;h2&gt;Items: type&lt;/h2&gt; 
&lt;p&gt;There are a number of methods of defining types in a &lt;code&gt;wit&lt;/code&gt; package, and all of&lt;br&gt; the types that can be defined in &lt;code&gt;wit&lt;/code&gt; are intended to map directly to types in&lt;br&gt; the &lt;a href=&quot;https://github.com/WebAssembly/component-model&quot;&gt;component model&lt;/a&gt;.&lt;/p&gt; 
&lt;h3&gt;Item: &lt;code&gt;type&lt;/code&gt; (alias)&lt;/h3&gt; 
&lt;p&gt;A &lt;code&gt;type&lt;/code&gt; statement declares a new named type in the &lt;code&gt;wit&lt;/code&gt; document. This name can&lt;br&gt; be later referred to when defining items using this type. This construct is&lt;br&gt; similar to a type alias in other languages&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-wit&quot;&gt;type my-awesome-u32 = u32;
type my-complicated-tuple = tuple&amp;lt;u32, s32, string&amp;gt;;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Specifically the structure of this is:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-ebnf&quot;&gt;type-item ::= &apos;type&apos; id &apos;=&apos; ty &apos;;&apos;
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;Item: &lt;code&gt;record&lt;/code&gt; (bag of named fields)&lt;/h3&gt; 
&lt;p&gt;A &lt;code&gt;record&lt;/code&gt; statement declares a new named structure with named fields. Records&lt;br&gt; are similar to a &lt;code&gt;struct&lt;/code&gt; in many languages. Instances of a &lt;code&gt;record&lt;/code&gt; always have&lt;br&gt; their fields defined.&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-wit&quot;&gt;record pair {
    x: u32,
    y: u32,
}

record person {
    name: string,
    age: u32,
    has-lego-action-figure: bool,
}
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Specifically the structure of this is:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-ebnf&quot;&gt;record-item ::= &apos;record&apos; id &apos;{&apos; record-fields &apos;}&apos;

record-fields ::= record-field
                | record-field &apos;,&apos; record-fields?

record-field ::= id &apos;:&apos; ty
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;Item: &lt;code&gt;flags&lt;/code&gt; (bag-of-bools)&lt;/h3&gt; 
&lt;p&gt;A &lt;code&gt;flags&lt;/code&gt; represents a bitset structure with a name for each bit. The &lt;code&gt;flags&lt;/code&gt;&lt;br&gt; type is represented as a bit flags representation in&lt;br&gt; the canonical ABI.&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-wit&quot;&gt;flags properties {
    lego,
    marvel-superhero,
    supervillan,
}
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Specifically the structure of this is:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-ebnf&quot;&gt;flags-items ::= &apos;flags&apos; id &apos;{&apos; flags-fields &apos;}&apos;

flags-fields ::= id
               | id &apos;,&apos; flags-fields?
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;Item: &lt;code&gt;variant&lt;/code&gt; (one of a set of types)&lt;/h3&gt; 
&lt;p&gt;A &lt;code&gt;variant&lt;/code&gt; statement defines a new type where instances of the type match&lt;br&gt; exactly one of the variants listed for the type. This is similar to a &quot;sum&quot; type&lt;br&gt; in algebraic datatypes (or an &lt;code&gt;enum&lt;/code&gt; in Rust if you&apos;re familiar with it).&lt;br&gt; Variants can be thought of as tagged unions as well.&lt;/p&gt; 
&lt;p&gt;Each case of a variant can have an optional type associated with it which is&lt;br&gt; present when values have that particular case&apos;s tag.&lt;/p&gt; 
&lt;p&gt;All &lt;code&gt;variant&lt;/code&gt; type must have at least one case specified.&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-wit&quot;&gt;variant filter {
    all,
    none,
    some(list&amp;lt;string&amp;gt;),
}
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Specifically the structure of this is:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-ebnf&quot;&gt;variant-items ::= &apos;variant&apos; id &apos;{&apos; variant-cases &apos;}&apos;

variant-cases ::= variant-case
                | variant-case &apos;,&apos; variant-cases?

variant-case ::= id
               | id &apos;(&apos; ty &apos;)&apos;
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;Item: &lt;code&gt;enum&lt;/code&gt; (variant but with no payload)&lt;/h3&gt; 
&lt;p&gt;An &lt;code&gt;enum&lt;/code&gt; statement defines a new type which is semantically equivalent to a&lt;br&gt; &lt;code&gt;variant&lt;/code&gt; where none of the cases have a payload type. This is special-cased,&lt;br&gt; however, to possibly have a different representation in the language ABIs or&lt;br&gt; have different bindings generated in for languages.&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-wit&quot;&gt;enum color {
    red,
    green,
    blue,
    yellow,
    other,
}
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Specifically the structure of this is:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-ebnf&quot;&gt;enum-items ::= &apos;enum&apos; id &apos;{&apos; enum-cases &apos;}&apos;

enum-cases ::= id
             | id &apos;,&apos; enum-cases?
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;Item: &lt;code&gt;resource&lt;/code&gt;&lt;/h3&gt; 
&lt;p&gt;A &lt;code&gt;resource&lt;/code&gt; statement defines a new abstract type for a &lt;em&gt;resource&lt;/em&gt;, which is&lt;br&gt; an entity with a lifetime that can only be passed around indirectly via &lt;a href=&quot;#handles&quot;&gt;handle&lt;br&gt; values&lt;/a&gt;. Resource types are used in interfaces to describe things&lt;br&gt; that can&apos;t or shouldn&apos;t be copied by value.&lt;/p&gt; 
&lt;p&gt;For example, the following Wit defines a resource type and a function that&lt;br&gt; takes and returns a handle to a &lt;code&gt;blob&lt;/code&gt;:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-wit&quot;&gt;resource blob;
transform: func(blob) -&amp;gt; blob;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;As syntactic sugar, resource statements can also declare any number of&lt;br&gt; &lt;em&gt;methods&lt;/em&gt;, which are functions that implicitly take a &lt;code&gt;self&lt;/code&gt; parameter that is&lt;br&gt; a handle. A resource statement can also contain any number of &lt;em&gt;static&lt;br&gt; functions&lt;/em&gt;, which do not have an implicit &lt;code&gt;self&lt;/code&gt; parameter but are meant to be&lt;br&gt; lexically nested in the scope of the resource type. Lastly, a resource&lt;br&gt; statement can contain at most one &lt;em&gt;constructor&lt;/em&gt; function, which is syntactic&lt;br&gt; sugar for a function returning a handle of the containing resource type.&lt;/p&gt; 
&lt;p&gt;For example, the following resource definition:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-wit&quot;&gt;resource blob {
    constructor(init: list&amp;lt;u8&amp;gt;);
    write: func(bytes: list&amp;lt;u8&amp;gt;);
    read: func(n: u32) -&amp;gt; list&amp;lt;u8&amp;gt;;
    merge: static func(lhs: borrow&amp;lt;blob&amp;gt;, rhs: borrow&amp;lt;blob&amp;gt;) -&amp;gt; blob;
}
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;desugars into:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-wit&quot;&gt;resource blob;
%[constructor]blob: func(init: list&amp;lt;u8&amp;gt;) -&amp;gt; blob;
%[method]blob.write: func(self: borrow&amp;lt;blob&amp;gt;, bytes: list&amp;lt;u8&amp;gt;);
%[method]blob.read: func(self: borrow&amp;lt;blob&amp;gt;, n: u32) -&amp;gt; list&amp;lt;u8&amp;gt;;
%[static]blob.merge: func(lhs: borrow&amp;lt;blob&amp;gt;, rhs: borrow&amp;lt;blob&amp;gt;) -&amp;gt; blob;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;These &lt;code&gt;%&lt;/code&gt;-prefixed &lt;a href=&quot;Explainer.md&quot;&gt;&lt;code&gt;name&lt;/code&gt;s&lt;/a&gt; embed the resource type name so that&lt;br&gt; bindings generators can generate idiomatic syntax for the target language or&lt;br&gt; (for languages like C) fall back to an appropriately-prefixed free function&lt;br&gt; name.&lt;/p&gt; 
&lt;p&gt;When a resource type name is used directly (e.g. when &lt;code&gt;blob&lt;/code&gt; is used as the&lt;br&gt; return value of the constructor above), it stands for an &quot;owning&quot; handle&lt;br&gt; that will call the resource&apos;s destructor when dropped. When a resource&lt;br&gt; type name is wrapped with &lt;code&gt;borrow&amp;lt;...&amp;gt;&lt;/code&gt;, it stands for a &quot;borrowed&quot; handle&lt;br&gt; that will &lt;em&gt;not&lt;/em&gt; call the destructor when dropped. As shown above, methods&lt;br&gt; always desugar to a borrowed self parameter whereas constructors always&lt;br&gt; desugar to an owned return value.&lt;/p&gt; 
&lt;p&gt;Specifically, the syntax for a &lt;code&gt;resource&lt;/code&gt; definition is:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-ebnf&quot;&gt;resource-item ::= &apos;resource&apos; id &apos;;&apos;
                | &apos;resource&apos; id &apos;{&apos; resource-method* &apos;}&apos;
resource-method ::= func-item
                  | id &apos;:&apos; &apos;static&apos; func-type &apos;;&apos;
                  | &apos;constructor&apos; param-list &apos;;&apos;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;The optional &lt;code&gt;async&lt;/code&gt; hint on &lt;code&gt;static&lt;/code&gt; functions has the same meaning as&lt;br&gt; in a non-&lt;code&gt;static&lt;/code&gt; &lt;code&gt;func-item&lt;/code&gt;.&lt;/p&gt; 
&lt;p&gt;The syntax for handle types is presented &lt;a href=&quot;#handles&quot;&gt;below&lt;/a&gt;.&lt;/p&gt; 
&lt;h2&gt;Types&lt;/h2&gt; 
&lt;p&gt;As mentioned previously the intention of &lt;code&gt;wit&lt;/code&gt; is to allow defining types&lt;br&gt; corresponding to the interface types specification. Many of the top-level items&lt;br&gt; above are introducing new named types but &quot;anonymous&quot; types are also supported,&lt;br&gt; such as built-ins. For example:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-wit&quot;&gt;type number = u32;
type fallible-function-result = result&amp;lt;u32, string&amp;gt;;
type headers = list&amp;lt;string&amp;gt;;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Specifically the following types are available:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-ebnf&quot;&gt;ty ::= &apos;u8&apos; | &apos;u16&apos; | &apos;u32&apos; | &apos;u64&apos;
     | &apos;s8&apos; | &apos;s16&apos; | &apos;s32&apos; | &apos;s64&apos;
     | &apos;f32&apos; | &apos;f64&apos;
     | &apos;char&apos;
     | &apos;bool&apos;
     | &apos;string&apos;
     | tuple
     | list
     | option
     | result
     | handle
     | future
     | stream
     | id

tuple ::= &apos;tuple&apos; &apos;&amp;lt;&apos; tuple-list &apos;&amp;gt;&apos;
tuple-list ::= ty
             | ty &apos;,&apos; tuple-list?

list ::= &apos;list&apos; &apos;&amp;lt;&apos; ty &apos;&amp;gt;&apos;
       | &apos;list&apos; &apos;&amp;lt;&apos; ty &apos;,&apos; uint &apos;&amp;gt;&apos; 🔧

uint ::= [1-9][0-9]*

option ::= &apos;option&apos; &apos;&amp;lt;&apos; ty &apos;&amp;gt;&apos;

result ::= &apos;result&apos; &apos;&amp;lt;&apos; ty &apos;,&apos; ty &apos;&amp;gt;&apos;
         | &apos;result&apos; &apos;&amp;lt;&apos; &apos;_&apos; &apos;,&apos; ty &apos;&amp;gt;&apos;
         | &apos;result&apos; &apos;&amp;lt;&apos; ty &apos;&amp;gt;&apos;
         | &apos;result&apos;

future ::= &apos;future&apos; &apos;&amp;lt;&apos; ty &apos;&amp;gt;&apos;
         | &apos;future&apos;

stream ::= &apos;stream&apos; &apos;&amp;lt;&apos; ty &apos;&amp;gt;&apos;
         | &apos;stream&apos;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;The &lt;code&gt;tuple&lt;/code&gt; type is semantically equivalent to a &lt;code&gt;record&lt;/code&gt; with numerical fields,&lt;br&gt; but it frequently can have language-specific meaning so it&apos;s provided as a&lt;br&gt; first-class type.&lt;/p&gt; 
&lt;p&gt;🔧 A &lt;code&gt;list&lt;/code&gt; with a fixed length provides the low-level memory representation of a&lt;br&gt; homogeneous &lt;code&gt;tuple&lt;/code&gt; of the same length, but with the dynamic indexing of a&lt;br&gt; list. E.g., the following two functions have the same low-level (Core&lt;br&gt; WebAssembly) representation, but will naturally produce different source-level&lt;br&gt; bindings:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-wit&quot;&gt;get-ipv4-address1: func() -&amp;gt; list&amp;lt;u8, 4&amp;gt;;
get-ipv4-address2: func() -&amp;gt; tuple&amp;lt;u8, u8, u8, u8&amp;gt;;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;The &lt;code&gt;option&lt;/code&gt; and &lt;code&gt;result&lt;/code&gt; types are semantically equivalent to the variants:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-wit&quot;&gt;variant option {
    none,
    some(ty),
}

variant result {
    ok(ok-ty),
    err(err-ty),
}
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;These types are so frequently used and frequently have language-specific&lt;br&gt; meanings though so they&apos;re also provided as first-class types.&lt;/p&gt; 
&lt;p&gt;The &lt;code&gt;future&lt;/code&gt; and &lt;code&gt;stream&lt;/code&gt; types are described as part of the &lt;a href=&quot;Async.md#streams-and-futures&quot;&gt;async&lt;br&gt; explainer&lt;/a&gt;.&lt;/p&gt; 
&lt;p&gt;Finally the last case of a &lt;code&gt;ty&lt;/code&gt; is simply an &lt;code&gt;id&lt;/code&gt; which is intended to refer to&lt;br&gt; another type or resource defined in the document. Note that definitions can come&lt;br&gt; through a &lt;code&gt;use&lt;/code&gt; statement or they can be defined locally.&lt;/p&gt; 
&lt;h2&gt;Handles&lt;/h2&gt; 
&lt;p&gt;There are two types of handles in Wit: &quot;owned&quot; handles and &quot;borrowed&quot; handles.&lt;br&gt; Owned handles represent the passing of unique ownership of a resource between&lt;br&gt; two components. When the owner of an owned handle drops that handle, the&lt;br&gt; resource is destroyed. In contrast, a borrowed handle represents a temporary&lt;br&gt; loan of a handle from the caller to the callee for the duration of the call.&lt;/p&gt; 
&lt;p&gt;The syntax for handles is:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-ebnf&quot;&gt;handle ::= id
         | &apos;borrow&apos; &apos;&amp;lt;&apos; id &apos;&amp;gt;&apos;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;The &lt;code&gt;id&lt;/code&gt; case denotes an owned handle, where &lt;code&gt;id&lt;/code&gt; is the name of a preceding&lt;br&gt; &lt;code&gt;resource&lt;/code&gt; item. Thus, the &quot;default&quot; way that resources are passed between&lt;br&gt; components is via transfer of unique ownership.&lt;/p&gt; 
&lt;p&gt;The resource method syntax defined above is syntactic sugar that expands into&lt;br&gt; separate function items that take a first parameter named &lt;code&gt;self&lt;/code&gt; of type&lt;br&gt; &lt;code&gt;borrow&lt;/code&gt;. For example, the compound definition:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-wit&quot;&gt;resource file {
    read: func(n: u32) -&amp;gt; list&amp;lt;u8&amp;gt;;
}
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;is expanded into:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-wit&quot;&gt;resource file
%[method]file.read: func(self: borrow&amp;lt;file&amp;gt;, n: u32) -&amp;gt; list&amp;lt;u8&amp;gt;;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;where &lt;code&gt;%[method]file.read&lt;/code&gt; is the desugared name of a method according to the&lt;br&gt; Component Model&apos;s definition of &lt;a href=&quot;Explainer.md&quot;&gt;&lt;code&gt;name&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt; 
&lt;h2&gt;Name resolution&lt;/h2&gt; 
&lt;p&gt;A &lt;code&gt;wit&lt;/code&gt; document is resolved after parsing to ensure that all names resolve&lt;br&gt; correctly. For example this is not a valid &lt;code&gt;wit&lt;/code&gt; document:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-wit&quot;&gt;type foo = bar;  // ERROR: name `bar` not defined
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Type references primarily happen through the &lt;code&gt;id&lt;/code&gt; production of &lt;code&gt;ty&lt;/code&gt;.&lt;/p&gt; 
&lt;p&gt;Additionally names in a &lt;code&gt;wit&lt;/code&gt; document can only be defined once:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-wit&quot;&gt;type foo = u32;
type foo = u64;  // ERROR: name `foo` already defined
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Names do not need to be defined before they&apos;re used (unlike in C or C++),&lt;br&gt; it&apos;s ok to define a type after it&apos;s used:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-wit&quot;&gt;type foo = bar;

record bar {
    age: u32,
}
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Types, however, cannot be recursive:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-wit&quot;&gt;type foo = foo;  // ERROR: cannot refer to itself

record bar1 {
    a: bar2,
}

record bar2 {
    a: bar1,    // ERROR: record cannot refer to itself
}
&lt;/code&gt;&lt;/pre&gt; 
&lt;h1&gt;Package Format&lt;/h1&gt; 
&lt;p&gt;Each top-level WIT definition can be compiled into a single canonical&lt;br&gt; Component Model &lt;a href=&quot;Explainer.md#type-definitions&quot;&gt;type definition&lt;/a&gt; that&lt;br&gt; captures the result of performing the type resolution described above. These&lt;br&gt; Component Model types can then be exported by a component along with other&lt;br&gt; sorts of exports, allowing a single component to package both runtime&lt;br&gt; functionality and development-time WIT interfaces. Thus, WIT does not need its&lt;br&gt; own separate package format; WIT can be packaged as a component binary.&lt;/p&gt; 
&lt;p&gt;Using component binaries to package WIT in this manner has several advantages:&lt;br&gt; * We get to reuse the &lt;a href=&quot;Binary.md&quot;&gt;binary format&lt;/a&gt; of components, especially the&lt;br&gt; tricky type bits.&lt;br&gt; * Downstream tooling does not need to replicate the resolution logic nor the&lt;br&gt; resolution environment (directories, registries, paths, arguments, etc) of&lt;br&gt; the WIT package producer; it can reuse the simpler compiled result.&lt;br&gt; * Many aspects of the WIT syntax can evolve over time without breaking&lt;br&gt; downstream tooling, similar to what has happened with the Core WebAssembly&lt;br&gt; WAT text format over time.&lt;br&gt; * When components are published in registries and assigned names (see the&lt;br&gt; discussion of naming in &lt;a href=&quot;Explainer.md#import-and-export-definitions&quot;&gt;Import and Export Definitions&lt;/a&gt;),&lt;br&gt; WIT interfaces and worlds can be published with the same tooling and named&lt;br&gt; using the same &lt;code&gt;namespace:package/export&lt;/code&gt; naming scheme.&lt;br&gt; * A single package can both contain an implementation and a collection of&lt;br&gt; &lt;code&gt;interface&lt;/code&gt; and &lt;code&gt;world&lt;/code&gt; definitions that are imported by that implementation&lt;br&gt; (e.g., an engine component can define and exports its own plugin &lt;code&gt;world&lt;/code&gt;).&lt;/p&gt; 
&lt;p&gt;As a first example, the following WIT:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-wit&quot;&gt;package local:demo;

interface types {
    resource file {
      read: func(off: u32, n: u32) -&amp;gt; list&amp;lt;u8&amp;gt;;
      write: func(off: u32, bytes: list&amp;lt;u8&amp;gt;);
    }
}

interface namespace {
    use types.{file};
    open: func(name: string) -&amp;gt; file;
}
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;can be packaged into a component as:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-wat&quot;&gt;(component
  (type (export &quot;types&quot;) (component
    (export &quot;local:demo/types&quot; (instance
      (export $file &quot;file&quot; (type (sub resource)))
      (export &quot;[method]file.read&quot; (func
        (param &quot;self&quot; (borrow $file)) (param &quot;off&quot; u32) (param &quot;n&quot; u32)
        (result (list u8))
      ))
      (export &quot;[method]file.write&quot; (func
        (param &quot;self&quot; (borrow $file))
        (param &quot;bytes&quot; (list u8))
      ))
    ))
  ))
  (type (export &quot;namespace&quot;) (component
    (import &quot;local:demo/types&quot; (instance $types
      (export &quot;file&quot; (type (sub resource)))
    ))
    (alias export $types &quot;file&quot; (type $file))
    (export &quot;local:demo/namespace&quot; (instance
      (export &quot;open&quot; (func (param &quot;name&quot; string) (result (own $file))))
    ))
  ))
)
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;This example illustrates the basic structure of interfaces:&lt;br&gt; * Each top-level WIT definition (in this example: &lt;code&gt;types&lt;/code&gt; and &lt;code&gt;namespace&lt;/code&gt;)&lt;br&gt; turns into a type export of the same kebab-name.&lt;br&gt; * Each WIT interface is mapped to a component-type that exports an&lt;br&gt; instance with a fully-qualified &lt;a href=&quot;Explainer.md#import-and-export-definitions&quot;&gt;interface name&lt;/a&gt;(in this example:&lt;br&gt; &lt;code&gt;local:demo/types&lt;/code&gt; and &lt;code&gt;local:demo/namespace&lt;/code&gt;). Note that this nested&lt;br&gt; scheme allows a single component to both define and implement a WIT interface&lt;br&gt; without name conflict.&lt;br&gt; * The wrapping component-type has an &lt;code&gt;import&lt;/code&gt; for every &lt;code&gt;use&lt;/code&gt; in the interface,&lt;br&gt; bringing any &lt;code&gt;use&lt;/code&gt;d types into scope so that they can be aliased when&lt;br&gt; building the instance-type. The component-type can be thought of as&lt;br&gt; &quot;parameterizing&quot; the interface&apos;s compiled instance type (∀T.{instance type}).&lt;br&gt; Note that there is &lt;em&gt;always&lt;/em&gt; an outer wrapping component-type, even when the&lt;br&gt; interface contains no &lt;code&gt;use&lt;/code&gt;s.&lt;/p&gt; 
&lt;p&gt;One useful consequence of this encoding scheme is that each top-level&lt;br&gt; definition is self-contained and valid (according to Component Model validation&lt;br&gt; rules) independent of each other definition. This allows packages to be&lt;br&gt; trivially split or unioned (assuming the result doesn&apos;t have to be a valid&lt;br&gt; package, but rather just a raw list of non-exported type definitions).&lt;/p&gt; 
&lt;p&gt;Another expectation is that, when a component containing WIT definitions is&lt;br&gt; published to a registry, the registry validates that the fully-qualified WIT&lt;br&gt; interface names inside the component are consistent with the registry-assigned&lt;br&gt; package name. For example, the above component would only be valid if published&lt;br&gt; with package name &lt;code&gt;local:demo&lt;/code&gt;; any other package name would be inconsistent&lt;br&gt; with the internal &lt;code&gt;local:demo/types&lt;/code&gt; and &lt;code&gt;local:demo/namespace&lt;/code&gt; exported&lt;br&gt; interface names.&lt;/p&gt; 
&lt;p&gt;Inter-package references are structurally no different than intra-package&lt;br&gt; references other than the referenced WIT definition is not present in&lt;br&gt; the component. For example, the following WIT:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-wit&quot;&gt;package local:demo

interface foo {
    use wasi:http/types.{request};
    frob: func(r: request) -&amp;gt; request;
}
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;is encoded as:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-wat&quot;&gt;(component
  (type (export &quot;foo&quot;) (component
    (import &quot;wasi:http/types&quot; (instance $types
      (export &quot;request&quot; (type (sub resource)))
    ))
    (alias export $types &quot;request&quot; (type $request))
    (export &quot;local:demo/foo&quot; (instance
      (export &quot;frob&quot; (func (param &quot;r&quot; (own $request)) (result (own $request))))
    ))
  ))
)
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Worlds are encoded similarly to interfaces, but replace the inner exported&lt;br&gt; instance with an inner exported &lt;em&gt;component&lt;/em&gt;. For example, this WIT:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-wit&quot;&gt;package local:demo;

world the-world {
    export test: func();
    export run: func();
}
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;is encoded as:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-wat&quot;&gt;(component
  (type (export &quot;the-world&quot;) (component
    (export &quot;local:demo/the-world&quot; (component
      (export &quot;test&quot; (func))
      (export &quot;run&quot; (func))
    ))
  ))
)
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;In the current version of WIT, the outer wrapping component-type will only ever&lt;br&gt; contain a single &lt;code&gt;export&lt;/code&gt; and thus only serves to separate the kebab-name&lt;br&gt; export from the inner exported interface name and to provide consistency with&lt;br&gt; the encoding of &lt;code&gt;interface&lt;/code&gt; shown above.&lt;/p&gt; 
&lt;p&gt;When a world imports or exports an interface, to produce a valid&lt;br&gt; component-type, the interface&apos;s compiled instance-type ends up getting copied&lt;br&gt; into the component-type. For example, the following WIT:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-wit&quot;&gt;package local:demo;

world the-world {
    import console;
}

interface console {
    log: func(arg: string);
}
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;is encoded as:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-wat&quot;&gt;(component
  (type (export &quot;the-world&quot;) (component
    (export &quot;local:demo/the-world&quot; (component
      (import &quot;local:demo/console&quot; (instance
        (export &quot;log&quot; (func (param &quot;arg&quot; string)))
      ))
    ))
  ))
  (type (export &quot;console&quot;) (component
    (export &quot;local:demo/console&quot; (instance
      (export &quot;log&quot; (func (param &quot;arg&quot; string)))
    ))
  ))
)
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;This duplication is useful in the case of cross-package references or split&lt;br&gt; packages, allowing a compiled &lt;code&gt;world&lt;/code&gt; definition to be fully self-contained and&lt;br&gt; able to be used to compile a component without additional type information.&lt;/p&gt; 
&lt;p&gt;Putting this all together, the following WIT definitions:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-wit&quot;&gt;// wasi-http repo

// wit/types.wit
interface types {
    resource request { ... }
    resource response { ... }
}

// wit/handler.wit
interface handler {
    use types.{request, response};
    handle: func(r: request) -&amp;gt; response;
}

// wit/proxy.wit
package wasi:http;

world proxy {
    import wasi:logging/logger;
    import handler;
    export handler;
}
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;are encoded as:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-wat&quot;&gt;(component
  (type (export &quot;types&quot;) (component
    (export &quot;wasi:http/types&quot; (instance
      (export &quot;request&quot; (type (sub resource)))
      (export &quot;response&quot; (type (sub resource)))
      ...
    ))
  ))
  (type (export &quot;handler&quot;) (component
    (import &quot;wasi:http/types&quot; (instance $http-types
      (export &quot;request&quot; (type (sub resource)))
      (export &quot;response&quot; (type (sub resource)))
    ))
    (alias export $http-types &quot;request&quot; (type $request))
    (alias export $http-types &quot;response&quot; (type $response))
    (export &quot;wasi:http/handler&quot; (instance
      (export &quot;handle&quot; (func (param &quot;r&quot; (own $request)) (result (own $response))))
    ))
  ))
  (type (export &quot;proxy&quot;) (component
    (export &quot;wasi:http/proxy&quot; (component
      (import &quot;wasi:logging/logger&quot; (instance
        ...
      ))
      (import &quot;wasi:http/types&quot; (instance $http-types
        (export &quot;request&quot; (type (sub resource)))
        (export &quot;response&quot; (type (sub resource)))
        ...
      ))
      (alias export $http-types &quot;request&quot; (type $request))
      (alias export $http-types &quot;response&quot; (type $response))
      (import &quot;wasi:http/handler&quot; (instance
        (export &quot;handle&quot; (func (param &quot;r&quot; (own $request)) (result (own $response))))
      ))
      (export &quot;wasi:http/handler&quot; (instance
        (export &quot;handle&quot; (func (param &quot;r&quot; (own $request)) (result (own $response))))
      ))
    ))
  ))
)
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;This examples shows how, in the context of concrete world (&lt;code&gt;wasi:http/proxy&lt;/code&gt;),&lt;br&gt; standalone interface definitions (such &lt;code&gt;wasi:http/handler&lt;/code&gt;) are no longer in a&lt;br&gt; &quot;parameterized&quot; form: there is no outer wrapping component-type and instead all&lt;br&gt; &lt;code&gt;use&lt;/code&gt;s are replaced by direct aliases to preceding type imports as determined&lt;br&gt; by the WIT resolution process.&lt;/p&gt; 
&lt;p&gt;Unlike most other WIT constructs, the &lt;code&gt;@since&lt;/code&gt; and &lt;code&gt;@unstable&lt;/code&gt; gates are not&lt;br&gt; represented in the component binary. Instead, they are considered &quot;macro&quot;&lt;br&gt; constructs that take the place of maintaining two copies of a single WIT&lt;br&gt; document. In particular, when encoding a collection of WIT documents into a&lt;br&gt; binary, the target version and set of explicitly-enabled feature names&lt;br&gt; determine whether individual gated features are included in the encoded type or&lt;br&gt; not.&lt;/p&gt; 
&lt;p&gt;For example, the following WIT document:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-wit&quot;&gt;package ns:p@1.1.0;

interface i {
    f: func();

    @since(version = 1.1.0)
    g: func();
}
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;is encoded as the following component when the target version is &lt;code&gt;1.0.0&lt;/code&gt;:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-wat&quot;&gt;(component
  (type (export &quot;i&quot;) (component
    (export &quot;ns:p/i@1.0.0&quot; (instance
      (export &quot;f&quot; (func))
    ))
  ))
)
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;If the target version was instead &lt;code&gt;1.1.0&lt;/code&gt;, the same WIT document would be&lt;br&gt; encoded as:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-wat&quot;&gt;(component
  (type (export &quot;i&quot;) (component
    (export &quot;ns:p/i@1.1.0&quot; (instance
      (export &quot;f&quot; (func))
      (export &quot;g&quot; (func))
    ))
  ))
)
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Thus, &lt;code&gt;@since&lt;/code&gt; and &lt;code&gt;@unstable&lt;/code&gt; gates are not part of the runtime semantics of&lt;br&gt; components, just part of the source-level tooling for producing components.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>WasmCloud</title>
      <link>https://tedneward.github.io/Research/platforms/wasmcloud/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">platforms/wasmcloud/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://wasmcloud.com/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/wasmcloud&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>VanillaOS</title>
      <link>https://tedneward.github.io/Research/platforms/vanillaos/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">platforms/vanillaos/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://vanillaos.org/&quot;&gt;Website&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://news.itsfoss.com/vanilla-os-release/&quot;&gt;Blog Post announcing stable release&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Visly (Figma)</title>
      <link>https://tedneward.github.io/Research/platforms/visly/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">platforms/visly/index.html</guid>
      	<description>
	&lt;p&gt;Looks to have been incorporated into Figma.&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://www.figma.com/&quot;&gt;https://www.figma.com/&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Wappler</title>
      <link>https://tedneward.github.io/Research/platforms/wappler/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">platforms/wappler/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://wappler.io/&quot;&gt;Website&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Unqork</title>
      <link>https://tedneward.github.io/Research/platforms/unqork/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">platforms/unqork/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.unqork.com/&quot;&gt;Website&lt;/a&gt; Looks to be fully commercial&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Web Assembly Component Model</title>
      <link>https://tedneward.github.io/Research/platforms/wasm/components/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">platforms/wasm/components/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://component-model.bytecodealliance.org/introduction.html&quot;&gt;Website&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://radu-matei.com/blog/intro-wasm-components/&quot;&gt;An introduction to WebAssembly components&lt;/a&gt;&lt;/p&gt; 
&lt;h2&gt;Component Model Concepts&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt; &lt;p&gt;A WebAssembly Component is the next evolution of core WebAssembly binaries.&lt;/p&gt; 
  &lt;ul&gt; 
   &lt;li&gt;WebAssembly components are nestable -- they may contain one or more core modules and/or sub-components composed together.&lt;/li&gt; 
   &lt;li&gt;Logically, components are containers for modules - or other components - which express their interfaces and dependencies via WIT.&lt;/li&gt; 
   &lt;li&gt;Conceptually, components are self-describing units of code that interact only through interfaces instead of shared memory.&lt;/li&gt; 
   &lt;li&gt;Physically, a component is a specially-formatted WebAssembly file. Internally, the component could include multiple traditional (&quot;core&quot;) WebAssembly modules, and sub-components, composed via their imports and exports.&lt;/li&gt; 
  &lt;/ul&gt; &lt;p&gt;The external interface of a component - its imports and exports - corresponds to a world. The component, however, internally defines how that world is implemented.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;The Component Model extends core WebAssembly by introducing higher level types and interface-driven development&lt;/p&gt; 
  &lt;ul&gt; 
   &lt;li&gt;WebAssembly Interface Types (WIT) is the IDL (Interface Definition Language) used to formally define functionality for WebAssembly modules.&lt;/li&gt; 
   &lt;li&gt;With WIT, WebAssembly components gain the ability to conform an language-agnostic and encode that support, so any WebAssembly component binary can be interrogated and executed.&lt;/li&gt; 
   &lt;li&gt;An Interface describes the types and functions used for a specific, focused bit of functionality. They are defined using WIT. 
    &lt;ul&gt; 
     &lt;li&gt;An interface describes a single-focus, composable contract, through which components can interact with each other and with hosts. Interfaces describe the types and functions used to carry out that interaction. For example:&lt;/li&gt; 
     &lt;li&gt;A &quot;receive HTTP requests&quot; interface might have only a single &quot;handle request&quot; function, but contain types representing incoming requests, outgoing responses, HTTP methods and headers, and so on.&lt;/li&gt; 
     &lt;li&gt;A &quot;wall clock&quot; interface might have two functions, one to get the current time and one to get the granularity of the timer. It would also include a type to represent an instant in time.&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;A World assembles interfaces to express what features a component offers, and what features it depends on. A WIT world is a higher-level contract that describes a component&apos;s capabilities and needs.&lt;/p&gt; &lt;p&gt;On one hand, a world describes the shape of a component - it says which interfaces the component exposes for other code to call (its exports), and which interfaces the component depends on (its imports). A world only defines the surface of a component, not the internal behaviour. If you&apos;re an application or library developer creating a component, you&apos;ll specify the world your component targets. This world describes the functionality your component exposes and declares the functionality your component depends on in order to be able to run. Your component may target a custom world definition you have created with a unique set of imports and exports tailored just for your use case, or it may target an existing world definition that someone else has already specified.&lt;/p&gt; &lt;p&gt;On the other hand though, a world defines a hosting environment for components (i.e., an environment in which a component can be instantiated and its functionality can be invoked). An environment supports a world by providing implementations for all of the imports and by optionally invoking one or more of the exports.&lt;/p&gt; &lt;p&gt;For example, WASI (the WebAssembly System Interface) defines a &quot;command line&quot; world which imports interfaces that command line programs typically expect to have available to them such as file I/O, random number generation, clocks and so on. This world has a single export for running the command line tool. Components targeting this world must provide an implementation for this single export, and they may optionally call any of the imports. On the other hand, environments supporting this world must provide implementations for all of the imports and may invoke the single export.&lt;/p&gt; &lt;p&gt;A world is composed of interfaces, but each interface is directional - it indicates whether the interface is available for outside code to call (an &quot;export&quot;), or whether outside code must fulfill the interface for the component to call (an &quot;import&quot;). These interfaces strictly bound the component. A component cannot interact with anything outside itself except by having its exports called, or by it calling its imports. This provides very strong sandboxing; for example, if a component does not have an import for a secret store, then it cannot access that secret store, even if the store is running in the same process.&lt;/p&gt; &lt;p&gt;For a component to run, its imports must be fulfilled, by a host or by other components. Connecting up some or all of a component&apos;s imports to other components&apos; matching exports is called composition.&lt;/p&gt; &lt;p&gt;Example Worlds&lt;/p&gt; 
    &lt;ul&gt; 
     &lt;li&gt;A (trivial) &quot;HTTP proxy&quot; world would export a &quot;handle HTTP requests&quot; interface, and import a &quot;send HTTP requests&quot; interface. A host, or another component, would call the exported &quot;handle&quot; interface, passing an HTTP request; the component would forward it on via the imported &quot;send&quot; interface. To be a useful proxy, the component may also need to import interfaces such as I/O and clock time - without those imports the component could not perform, for example, on-disk caching.&lt;/li&gt; 
     &lt;li&gt;A &quot;regex parser&quot; world would export a &quot;parse regex&quot; function, and would import nothing. This declares not only that the component implementing this world can parse regular expressions, but also that it calls no other APIs. A user of such a parser could know, without looking at the implementation, that is does not access the file system, or send the user&apos;s regexes to a network service.&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;A Package is a set of WIT files containing a related set of interfaces and worlds.&lt;/p&gt; &lt;p&gt;A WIT package is a set of one or more WIT (Wasm Interface Type) files containing a related set of interfaces and worlds. WIT is an IDL (interface definition language) for the Component Model. Packages provide a way for worlds and interfaces to refer to each other, and thus for an ecosystem of components to share common definitions.&lt;/p&gt; &lt;p&gt;A WIT package is not a world. It&apos;s a way of grouping related interfaces and worlds together for ease of discovery and reference, more like a namespace.&lt;/p&gt; &lt;p&gt;The WebAssembly System Interface (WASI) defines a number of packages, including one named &lt;code&gt;wasi:clocks&lt;/code&gt;. Our HTTP proxy world could import the wall-clock interface from the &lt;code&gt;wasi:clocks&lt;/code&gt; package, rather than having to define a custom clock interface.&lt;/p&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;The Component Model introduces the idea of a &quot;platform&quot; to core WebAssembly -- enabling the structured, standardized use of &quot;host&quot; functionality for WebAssembly &quot;guest&quot;s.&lt;/p&gt; 
  &lt;ul&gt; 
   &lt;li&gt;The WebAssembly System Interface (WASI) defines in WIT a family of interfaces for common system-level functions.&lt;/li&gt; 
   &lt;li&gt;WASI defines common execution environments such as the command line (wasi:cli) or a HTTP server (wasi:http).&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;The Component Model makes core WebAssembly composable -- components that provide functionality and those that use them can be composed together into one resulting component&lt;/p&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Component Model Concepts&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt; &lt;p&gt;A WebAssembly Component is the next evolution of core WebAssembly binaries.&lt;/p&gt; 
  &lt;ul&gt; 
   &lt;li&gt;WebAssembly components are nestable -- they may contain one or more core modules and/or sub-components composed together.&lt;/li&gt; 
   &lt;li&gt;Logically, components are containers for modules - or other components - which express their interfaces and dependencies via WIT.&lt;/li&gt; 
   &lt;li&gt;Conceptually, components are self-describing units of code that interact only through interfaces instead of shared memory.&lt;/li&gt; 
   &lt;li&gt;Physically, a component is a specially-formatted WebAssembly file. Internally, the component could include multiple traditional (&quot;core&quot;) WebAssembly modules, and sub-components, composed via their imports and exports.&lt;/li&gt; 
  &lt;/ul&gt; &lt;p&gt;The external interface of a component - its imports and exports - corresponds to a world. The component, however, internally defines how that world is implemented.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;The Component Model extends core WebAssembly by introducing higher level types and interface-driven development&lt;/p&gt; 
  &lt;ul&gt; 
   &lt;li&gt;WebAssembly Interface Types (WIT) is the IDL (Interface Definition Language) used to formally define functionality for WebAssembly modules.&lt;/li&gt; 
   &lt;li&gt;With WIT, WebAssembly components gain the ability to conform an language-agnostic and encode that support, so any WebAssembly component binary can be interrogated and executed.&lt;/li&gt; 
   &lt;li&gt;An Interface describes the types and functions used for a specific, focused bit of functionality. They are defined using WIT. 
    &lt;ul&gt; 
     &lt;li&gt;An interface describes a single-focus, composable contract, through which components can interact with each other and with hosts. Interfaces describe the types and functions used to carry out that interaction. For example:&lt;/li&gt; 
     &lt;li&gt;A &quot;receive HTTP requests&quot; interface might have only a single &quot;handle request&quot; function, but contain types representing incoming requests, outgoing responses, HTTP methods and headers, and so on.&lt;/li&gt; 
     &lt;li&gt;A &quot;wall clock&quot; interface might have two functions, one to get the current time and one to get the granularity of the timer. It would also include a type to represent an instant in time.&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;A World assembles interfaces to express what features a component offers, and what features it depends on. A WIT world is a higher-level contract that describes a component&apos;s capabilities and needs.&lt;/p&gt; &lt;p&gt;On one hand, a world describes the shape of a component - it says which interfaces the component exposes for other code to call (its exports), and which interfaces the component depends on (its imports). A world only defines the surface of a component, not the internal behaviour. If you&apos;re an application or library developer creating a component, you&apos;ll specify the world your component targets. This world describes the functionality your component exposes and declares the functionality your component depends on in order to be able to run. Your component may target a custom world definition you have created with a unique set of imports and exports tailored just for your use case, or it may target an existing world definition that someone else has already specified.&lt;/p&gt; &lt;p&gt;On the other hand though, a world defines a hosting environment for components (i.e., an environment in which a component can be instantiated and its functionality can be invoked). An environment supports a world by providing implementations for all of the imports and by optionally invoking one or more of the exports.&lt;/p&gt; &lt;p&gt;For example, WASI (the WebAssembly System Interface) defines a &quot;command line&quot; world which imports interfaces that command line programs typically expect to have available to them such as file I/O, random number generation, clocks and so on. This world has a single export for running the command line tool. Components targeting this world must provide an implementation for this single export, and they may optionally call any of the imports. On the other hand, environments supporting this world must provide implementations for all of the imports and may invoke the single export.&lt;/p&gt; &lt;p&gt;A world is composed of interfaces, but each interface is directional - it indicates whether the interface is available for outside code to call (an &quot;export&quot;), or whether outside code must fulfill the interface for the component to call (an &quot;import&quot;). These interfaces strictly bound the component. A component cannot interact with anything outside itself except by having its exports called, or by it calling its imports. This provides very strong sandboxing; for example, if a component does not have an import for a secret store, then it cannot access that secret store, even if the store is running in the same process.&lt;/p&gt; &lt;p&gt;For a component to run, its imports must be fulfilled, by a host or by other components. Connecting up some or all of a component&apos;s imports to other components&apos; matching exports is called composition.&lt;/p&gt; &lt;p&gt;Example Worlds&lt;/p&gt; 
    &lt;ul&gt; 
     &lt;li&gt;A (trivial) &quot;HTTP proxy&quot; world would export a &quot;handle HTTP requests&quot; interface, and import a &quot;send HTTP requests&quot; interface. A host, or another component, would call the exported &quot;handle&quot; interface, passing an HTTP request; the component would forward it on via the imported &quot;send&quot; interface. To be a useful proxy, the component may also need to import interfaces such as I/O and clock time - without those imports the component could not perform, for example, on-disk caching.&lt;/li&gt; 
     &lt;li&gt;A &quot;regex parser&quot; world would export a &quot;parse regex&quot; function, and would import nothing. This declares not only that the component implementing this world can parse regular expressions, but also that it calls no other APIs. A user of such a parser could know, without looking at the implementation, that is does not access the file system, or send the user&apos;s regexes to a network service.&lt;/li&gt; 
    &lt;/ul&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;A Package is a set of WIT files containing a related set of interfaces and worlds.&lt;/p&gt; &lt;p&gt;A WIT package is a set of one or more WIT (Wasm Interface Type) files containing a related set of interfaces and worlds. WIT is an IDL (interface definition language) for the Component Model. Packages provide a way for worlds and interfaces to refer to each other, and thus for an ecosystem of components to share common definitions.&lt;/p&gt; &lt;p&gt;A WIT package is not a world. It&apos;s a way of grouping related interfaces and worlds together for ease of discovery and reference, more like a namespace.&lt;/p&gt; &lt;p&gt;The WebAssembly System Interface (WASI) defines a number of packages, including one named &lt;code&gt;wasi:clocks&lt;/code&gt;. Our HTTP proxy world could import the wall-clock interface from the &lt;code&gt;wasi:clocks&lt;/code&gt; package, rather than having to define a custom clock interface.&lt;/p&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;The Component Model introduces the idea of a &quot;platform&quot; to core WebAssembly -- enabling the structured, standardized use of &quot;host&quot; functionality for WebAssembly &quot;guest&quot;s.&lt;/p&gt; 
  &lt;ul&gt; 
   &lt;li&gt;The WebAssembly System Interface (WASI) defines in WIT a family of interfaces for common system-level functions.&lt;/li&gt; 
   &lt;li&gt;WASI defines common execution environments such as the command line (wasi:cli) or a HTTP server (wasi:http).&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;The Component Model makes core WebAssembly composable -- components that provide functionality and those that use them can be composed together into one resulting component&lt;/p&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;hr&gt;
	</description>
    </item>
    <item>
      <title>macOS Setup</title>
      <link>https://tedneward.github.io/Research/platforms/macos/setup/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">platforms/macos/setup/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://wilsonmar.github.io/ansible-mac-osx-setup/&quot;&gt;Ansible macOS setup&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://www.freecodecamp.org/news/set-up-your-macos-development-environment-using-thoughtbots-laptop-script-e6bf9b2e03dd/&quot;&gt;Thoughtbot&apos;s Setup script&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://www.xda-developers.com/how-install-macos-unsupported-mac/&quot;&gt;&quot;How to install macOS Sonoma on unsupported Macs&quot;&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://www.xda-developers.com/15-settings-you-didnt-know-you-need-to-change-on-mac/&quot;&gt;&quot;15 Settings you didn&apos;t know you need to change on Mac&quot;&lt;/a&gt;:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Create text replacements&lt;/li&gt; 
 &lt;li&gt;Generate unique email addresses (iCloud subscribers)&lt;/li&gt; 
 &lt;li&gt;Change Mac gestures&lt;/li&gt; 
 &lt;li&gt;Disable Private Relay&lt;/li&gt; 
 &lt;li&gt;Tweak Spotlight search&lt;/li&gt; 
 &lt;li&gt;Use Apple Watch to unlock applications on Mac&lt;/li&gt; 
 &lt;li&gt;Launch Focus when you open an app&lt;/li&gt; 
 &lt;li&gt;Enable and tweak iPhone notifications&lt;/li&gt; 
 &lt;li&gt;Enable notifications when mirroring on Mac&lt;/li&gt; 
 &lt;li&gt;Set the picture folder as wallpaper&lt;/li&gt; 
 &lt;li&gt;Show a message on the lock screen&lt;/li&gt; 
 &lt;li&gt;Tweak hot corners&lt;/li&gt; 
 &lt;li&gt;Use storage recommendations&lt;/li&gt; 
 &lt;li&gt;Prevent automatic sleeping on power adapter&lt;/li&gt; 
 &lt;li&gt;Enable Low Data mode for Wi-Fi&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>GNU MIX Development Kit (MDK)</title>
      <link>https://tedneward.github.io/Research/platforms/mdk/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">platforms/mdk/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.gnu.org/software/mdk/mdk.html&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://savannah.gnu.org/git/?group=mdk&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>MiniMicro</title>
      <link>https://tedneward.github.io/Research/platforms/minimicro/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">platforms/minimicro/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://miniscript.org/MiniMicro/index.html&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/JoeStrout/MiniMicro2&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>GrapheneOS</title>
      <link>https://tedneward.github.io/Research/platforms/mobile/grapheneos/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">platforms/mobile/grapheneos/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://grapheneos.org/&quot;&gt;Website&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Monaca</title>
      <link>https://tedneward.github.io/Research/platforms/monaca/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">platforms/monaca/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://monaca.io/&quot;&gt;Website&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Commercial--no source. Cloud-hosted IDEs.&lt;/p&gt; 
&lt;p&gt;Supports both &lt;a href=&quot;/presentation/onsenui&quot;&gt;Onsen UI&lt;/a&gt; and &lt;a href=&quot;/presentation/cordova&quot;&gt;Cordova&lt;/a&gt; projects?&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>NeXTSpace</title>
      <link>https://tedneward.github.io/Research/platforms/nextspace/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">platforms/nextspace/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/trunkmaster/nextspace&quot;&gt;Source&lt;/a&gt; | &lt;a href=&quot;https://trunkmaster.github.io/&quot;&gt;Blog&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;img src=&quot;https://github.com/trunkmaster/nextspace/raw/master/Documentation/NEXTSPACE_Screenshot.png&quot; alt=&quot;NEXTSPACE Screenshot&quot;&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Ockam</title>
      <link>https://tedneward.github.io/Research/platforms/ockam/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">platforms/ockam/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.ockam.io/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/build-trust/ockam&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>OpenXava</title>
      <link>https://tedneward.github.io/Research/platforms/openxava/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">platforms/openxava/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.openxava.org/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://www.openxava.org/&quot;&gt;Source&lt;/a&gt; | &lt;a href=&quot;https://www.openxava.org/doc/&quot;&gt;Docs&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Open Source Low-Code Platform for Rapid Development of Enterprise Web Applications.&lt;/p&gt; 
&lt;p&gt;Write just the domain classes in plain Java. Get a web application ready for production.&lt;/p&gt; 
&lt;h4&gt;High productivity&lt;/h4&gt; 
&lt;p&gt;You only write the code for your data structure and business logic. You do not write HTML, JavaScript, CSS, SQL, etc. The user interface and the database logic are automatically provided.&lt;/p&gt; 
&lt;h4&gt;Short learning curve&lt;/h4&gt; 
&lt;p&gt;Learning how to write simple Java classes is enough to write complete applications. The OpenXava bundle is prepared for a rapid startup.&lt;/p&gt; 
&lt;h4&gt;Full-featured applications&lt;/h4&gt; 
&lt;p&gt;AJAX user interface with no page reloading. List mode with paging, ordering, filtering, adding / removing / moving columns, PDF reports, export to Excel, cards format, charts, etc. Detail mode with tabs, frames, dialogs, editors for references and collections, responsive layout, etc.&lt;/p&gt; 
&lt;h4&gt;Mobile user interface&lt;/h4&gt; 
&lt;p&gt;In addition to the classic web user interface for desktop you can get a mobile user interface for your application from the same code.&lt;/p&gt; 
&lt;h4&gt;Use your favorite platform&lt;/h4&gt; 
&lt;p&gt;Browsers: Internet Explorer, Chrome, Firefox and Safari. Databases: Any supported by Hibernate, that is Oracle, DB2, AS/400, Informix, PostgreSQL, MySQL, MS SQL Server and practically all relational databases. Operating systems: Any with Java 8 (or better) support, that is Windows, Linux, Mac, Unix, AS/400, z/OS, etc. Application servers: Any with support for Servlets 3.0 (or better), including Tomcat, JBoss, WebSphere, Glassfish, WebLogic, etc. Enterprise portals: Any with JSR-168 or JSR-286 support including WebSphere Portal and Liferay.&lt;/p&gt; 
&lt;h4&gt;Open source&lt;/h4&gt; 
&lt;p&gt;LGPL license that allows you to develop commercial applications without paying any fees.&lt;/p&gt; 
&lt;h4&gt;Multilingual&lt;/h4&gt; 
&lt;p&gt;The standard labels and messages included in OpenXava are in English, Spanish, German, French, Chinese, Russian, Japanese, Portuguese, Catalan, Indonesian, Italian, Polish, Serbian and Swedish. Moreover, it&apos;s pretty easy to add a new language.&lt;/p&gt; 
&lt;h4&gt;The most used Java domain-driven framework&lt;/h4&gt; 
&lt;p&gt;250,000 downloads. 60 authors. Thousands of threads in the forums. Hundreds of applications developed. Hundreds of professionals in LinkedIn with OpenXava experience.&lt;/p&gt; 
&lt;h4&gt;Exhaustive documentation&lt;/h4&gt; 
&lt;p&gt;Complete Reference Guide in English, French, Russian, Chinese and Spanish. Free online course in English and Spanish where an invoicing application is developed from scratch. Book in English and Spanish available from Amazon. Hundreds of videos on YouTube.&lt;/p&gt; 
&lt;h4&gt;Quality support&lt;/h4&gt; 
&lt;p&gt;Free support in community forums, though they have thousands of threads all questions are answered. Moreover, there is professional support available.&lt;/p&gt; 
&lt;h4&gt;Based on Java standards&lt;/h4&gt; 
&lt;p&gt;Thus you can migrate your current Java code easily to OpenXava, and vice versa. You can use any Java tool for OpenXava. Your Java developers are already OpenXava developers. OpenXava supports: JSR-338, JSR-317, JSR-303, JSR-330, JSR-220, JSR-153, JSR-311, JSR-339, JSR-370, JSR-168 and JSR-286.&lt;/p&gt; 
&lt;h4&gt;Third party tools&lt;/h4&gt; 
&lt;p&gt;MinuteProject: Generates an OpenXava application from an already existing database. Mogwai ERDesigner: An entity relationship modeling/design tool(ERD) that generates OpenXava applications. Moskitt: A CASE tool, built on Eclipse, that generates OpenXava applications from UML models.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Outsystems</title>
      <link>https://tedneward.github.io/Research/platforms/outsystems/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">platforms/outsystems/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.outsystems.com/&quot;&gt;Website&lt;/a&gt;&lt;/p&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;OutSystems is a modern application platform designed to dramatically accelerate the development of your most critical applications while also delivering unprecedented levels of flexibility and efficiency. Address your top digital transformation priorities with applications that make a difference across all areas of the business—from customer experience transformation and workplace innovation to process automation and application modernization.&lt;/p&gt; 
&lt;/blockquote&gt; 
&lt;h4&gt;Personal conversation with @devhammer (7/1/2021):&lt;/h4&gt; 
&lt;p&gt;Suports either a cloud (AWS)-based deployment model, or a &quot;self-service&quot; deployment model.&lt;/p&gt; 
&lt;p&gt;Considers itself very &quot;low-code&quot;--a tool that developers will recognize and find useful, but not for people with no programming background. &quot;Brought back all the power/love of using VB, but keeps people in that visual model/mindset longer than VB does.&quot;&lt;/p&gt; 
&lt;p&gt;Uses Apache Cordova for multiplatform application client. Recently moved from ASP.NET WebForms-based UI to a React one. (Will continue to support WebForms for a &quot;long time to come&quot;.)&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Platformatic</title>
      <link>https://tedneward.github.io/Research/platforms/platformatic/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">platforms/platformatic/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://docs.platformatic.dev/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/platformatic&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Platformatic’s Open Source toolkit helps you build modern Node.js applications without the endless loop of setup and maintenance.&lt;br&gt; Break free from repetitive tasks, accelerate deployments and improve your Node.js development experience with our:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Opinionated structures and composable templates&lt;/li&gt; 
 &lt;li&gt;Batteries-included API setup&lt;/li&gt; 
 &lt;li&gt;Out-of-the-box documentation, logs and metrics&lt;/li&gt; 
 &lt;li&gt;Shareable and reusable configurations&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;&lt;strong&gt;Platformatic for Teams&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;Node.js promises speed, agility, and scalability. In practice however, doing Node right has been a challenge for engineering teams, costing their companies cloud spend, downtime, and time-to-market.&lt;br&gt; Time and time again, we’ve seen companies stumble when dealing with the same 5 issues:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Scaling based on CPU and memory.&lt;/li&gt; 
 &lt;li&gt;Preview environment limitations&lt;/li&gt; 
 &lt;li&gt;Getting the right Node.js metrics&lt;/li&gt; 
 &lt;li&gt;Not knowing what will break or which teams you’ll impact when deploying APIs&lt;/li&gt; 
 &lt;li&gt;Figuring out which logger is right for you&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>PowerLoom</title>
      <link>https://tedneward.github.io/Research/platforms/powerloom/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">platforms/powerloom/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.isi.edu/isd/LOOM/PowerLoom/&quot;&gt;Website&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Puter</title>
      <link>https://tedneward.github.io/Research/platforms/puter/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">platforms/puter/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://puter.com/&quot;&gt;Website/live platform&lt;/a&gt; | &lt;a href=&quot;https://docs.puter.com/#/&quot;&gt;SDK Docs&lt;/a&gt; | &lt;a href=&quot;https://github.com/HeyPuter/&quot;&gt;Source&lt;/a&gt; (examples)&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>QuickBase</title>
      <link>https://tedneward.github.io/Research/platforms/quickbase/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">platforms/quickbase/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.quickbase.com/&quot;&gt;Website&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>ReactOS</title>
      <link>https://tedneward.github.io/Research/platforms/reactos/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">platforms/reactos/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://reactos.org/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/reactos/reactos&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Windows might be the most used operating system for home users, but what if you don&apos;t want to use Microsoft&apos;s OS but do want to use the apps written to run on it? Before SteamOS and the Proton compatibility layer added that functionality to Linux, ReactOS was the only answer to that question. It&apos;s an open-source clone of Windows NT that is fully compatible with any app, driver, and service that also runs on Windows NT.&lt;/p&gt; 
&lt;p&gt;As such, it&apos;s probably the easiest retro-feeling OS to install and use because it feels familiar while offering modern conveniences and stability. It can also be run from a live USB, so you don&apos;t even have to install it on your internal hard drive if you prefer to test-drive things before proceeding.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Retool</title>
      <link>https://tedneward.github.io/Research/platforms/retool/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">platforms/retool/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://retool.com/&quot;&gt;Website&lt;/a&gt; Commercial with a free tier.&lt;/p&gt; 
&lt;p&gt;All internal tools are made up of the building blocks: Tables, Lists, Charts, Forms, Wizards, Maps and so on. Retool provides a complete set of powerful building blocks out of the box. Spend your time getting UI in front of stakeholders, not hunting down the best React table library. Assemble your app in 30 seconds by dragging and dropping from our pre-built &lt;a href=&quot;https://retool.com/components&quot;&gt;components&lt;/a&gt;.&lt;/p&gt; 
&lt;p&gt;Retool has 4 fundamental pieces to it:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Connect your data sources, like PostgreSQL, Salesforce, Firebase, and 20+ more&lt;/li&gt; 
 &lt;li&gt;Build your queries and logic in SQL or Javascript&lt;/li&gt; 
 &lt;li&gt;Connect your queries and logic to prebuilt components like tables, text inputs, and buttons&lt;/li&gt; 
 &lt;li&gt;Organize and connect your components into an app&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;Retool isn&apos;t just a front end, though – we take care of a lot of the pesky logic that internal tools tend to require, like scheduling queries, updating and writing data, and triggers. Retool apps are easy to share with your teammates and stakeholders, and we offer granular access management and audit logs to keep things secure.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>RubyMotion</title>
      <link>https://tedneward.github.io/Research/platforms/rubymotion/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">platforms/rubymotion/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;http://www.rubymotion.com/&quot;&gt;Website&lt;/a&gt;&lt;/p&gt; 
&lt;h3&gt;Examples&lt;/h3&gt; 
&lt;p&gt;Android HelloWorld&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-ruby&quot;&gt;class MainActivity &amp;lt; Android::App::Activity
  def onCreate(savedInstanceState)
    puts &quot;Hello World!&quot;
    super
    view = Android::Widget::TextView.new(self)
    view.text = &quot;Hello World!&quot;
    self.contentView = view
  end
end
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;iOS HelloWorld&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-ruby&quot;&gt;class AppDelegate
  def application(application, didFinishLaunchingWithOptions:launchOptions)
    true
  end
end

class AppDelegate
  def application(application, didFinishLaunchingWithOptions:launchOptions)
    alert = UIAlertView.new
    alert.message = &quot;Hello World!&quot;
    alert.show
    true
  end
end
&lt;/code&gt;&lt;/pre&gt;
	</description>
    </item>
    <item>
      <title>SerenityOS</title>
      <link>https://tedneward.github.io/Research/platforms/serenity/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">platforms/serenity/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://serenityos.org/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/SerenityOS/serenity&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Skyve</title>
      <link>https://tedneward.github.io/Research/platforms/skyve/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">platforms/skyve/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://skyve.org/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;&quot;&gt;Source&lt;/a&gt;&lt;a href=&quot;https://github.com/skyvers/skyve&quot;&gt;https://github.com/skyvers/skyve&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Strapi</title>
      <link>https://tedneward.github.io/Research/platforms/strapi/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">platforms/strapi/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://strapi.io/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/strapi/strapi&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Tabris</title>
      <link>https://tedneward.github.io/Research/platforms/tabris/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">platforms/tabris/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://tabris.com/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/eclipsesource/tabris-js/&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;(Looks like it builds on top of Apache Cordova somewhere/how?)&lt;/p&gt; 
&lt;p&gt;Hello, world in Tabris:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;import {Button, contentView, TextView} from &apos;tabris&apos;;

// in JS

new Button({top: 16, centerX: true, text: &apos;Use native UI&apos;})
  .onSelect(() =&amp;gt; $(TextView).only().text = &apos;Powered by Tabris.js&apos;)
  .appendTo(contentView);
new TextView({top: &apos;prev() 16&apos;, centerX: true})
  .appendTo(contentView);

// or in JSX

contentView.append(
  &amp;lt;$&amp;gt;
    &amp;lt;Button top={16} centerX text=&apos;Use native UI&apos;
            onSelect={() =&amp;gt; $(TextView).only().text = &apos;Powered by Tabris.js&apos;}/&amp;gt;
    &amp;lt;TextView top=&apos;prev() 16&apos; centerX/&amp;gt;
  &amp;lt;/$&amp;gt;
);
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;yields&lt;br&gt; &lt;img src=&quot;https://github.com/eclipsesource/tabris-js/raw/master/doc/img/hello-example.png&quot; alt=&quot;&quot;&gt;&lt;br&gt; and&lt;br&gt; ~&lt;a href=&quot;https://github.com/eclipsesource/tabris-js/raw/master/doc/img/hello-example.png&quot;&gt;&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;The code of the application is loaded dynamically - nothing is precompiled. JavaScript is executed Just-in-Time and passed via a native bridge to the device. Tabris.js accesses native controls and does not depend on webviews to render the app&apos;s UI.&lt;/p&gt; 
&lt;p&gt;A Compiled Tabris.js app is written in JavaScript or TypeScript and offers support for the latest EcmaScript features and JSX. It is recommended for more complex Tabris.js projects. The only downside of this setup is that the code needs to be transformed before execution, which is done automatically when using the Tabris CLI or build service.&lt;/p&gt; 
&lt;p&gt;A Vanilla Tabris.js app is written in plain JavaScript that is executed as-is in the JavaScript engine. As a result there may be minor differences between the platforms.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Tink</title>
      <link>https://tedneward.github.io/Research/platforms/tink/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">platforms/tink/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://tink.com/&quot;&gt;Website&lt;/a&gt;&lt;/p&gt; 
&lt;h3&gt;Products&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt; &lt;p&gt;Transactions: Access up-to-date transaction data from thousands of banks across Europe – already standardised and categorised so you can extract real value and insights.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Account Check: Confirm account ownership with real-time data straight from a user’s bank account, creating a quick and simple payment setup process.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Income Check: Optimise credit decisions and understand your customers’ true financial capacity by instantly verifying income using real-time data.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Payment Initiation: Increase engagement and conversion by giving your customers a fully embedded payments experience – at a fraction of the cost.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Money Manager: Build smart, intuitive personal finance management applications that give your customers tools and personalised insights to better manage their money.&lt;/p&gt; &lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>UEFI (Unified Extensible Firmware Interface)</title>
      <link>https://tedneward.github.io/Research/platforms/uefi/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">platforms/uefi/index.html</guid>
      	<description>
	&lt;p&gt;The replacement for BIOS on PCs and servers. An operating system in its own right, comparable in complexity to DOS.&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://uefi.org/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://uefi.org/sites/default/files/resources/UEFI%20Spec%202_6.pdf&quot;&gt;UEFI Specification&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://uefi.org/sites/default/files/resources/UEFI_Shell_2_2.pdf&quot;&gt;Shell Specification&lt;/a&gt; | &lt;a href=&quot;https://manuais.iessanclemente.net/images/a/a6/EFI-ShellCommandManual.pdf&quot;&gt;Intel Shell Command Reference Manual&lt;/a&gt; | &lt;a href=&quot;https://www.intel.com/content/dam/support/us/en/documents/motherboards/server/sb/efi_instructions.pdf&quot;&gt;Intel Basic Instructions for Using the&lt;br&gt; Extensible Firmware Interface (EFI)&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://kb.stonegroup.co.uk/index.php?View=entry&amp;amp;EntryID=84&quot;&gt;&quot;How to Access the EFI Shell to carry out Systems Diagnostics or Updates&quot;&lt;/a&gt;: Turns out the shell can read USB-key drives and execute .EFI executable files--which is interesting in of itself--and this article describes how to boot into an Intel machine and use the UEFI shell to do that.&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://www.rodsbooks.com/efi-programming/index.html&quot;&gt;Programming for EFI&lt;/a&gt;: Building programs for the EFI environment.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>macOS (OS) usage</title>
      <link>https://tedneward.github.io/Research/platforms/macos/usage/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">platforms/macos/usage/index.html</guid>
      	<description>
	&lt;h2&gt;Network utilities&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://cyberhost.uk/the-hidden-macos-speedtest-tool-networkquality/&quot;&gt;&quot;networkQuality&quot;&lt;/a&gt;: &quot;The networkQuality tool is a built-in tool released in macOS Monterey that can help diagnose network issues and measure network performance.&quot;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Terminal Tricks&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://josh.works/shell-script-basics-change-mac-address&quot;&gt;&quot;Change your MAC address with a shell script&quot;&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://www.techrepublic.com/article/macos-terminal-commands-every-mac-user-should-know/&quot;&gt;&quot;macOS terminal commands every mac user should know&quot;&lt;/a&gt;:&lt;/p&gt; 
  &lt;ul&gt; 
   &lt;li&gt; &lt;p&gt;Update macOS via SoftwareUpdate in the terminal: &lt;code&gt;softwareupdate -i -a&lt;/code&gt;&lt;/p&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;Copy output of a command to the clipboard: &lt;code&gt;cat ~/Desktop/myfile.txt | pbcopy&lt;/code&gt;&lt;/p&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;View system utilization: &lt;code&gt;top&lt;/code&gt;&lt;/p&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;Keep Mac from turning off/sleeping: &lt;code&gt;caffeinate&lt;/code&gt;&lt;/p&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;Clear the DNS cache: &lt;code&gt;sudo killall -HUP mDNSResponder;sudo killall mDNSResponderHelper;sudo dscacheutil -flushcache&lt;/code&gt;&lt;/p&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;Find diffs in files: &lt;code&gt;opendiff ~/Desktop/text1.txt ~/Desktop/text2.txt&lt;/code&gt;&lt;/p&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;Find out how long the Mac has been on: &lt;code&gt;uptime&lt;/code&gt;&lt;/p&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;Force macOS to shut down: &lt;code&gt;shutdown -r now&lt;/code&gt;&lt;/p&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;Get a QuickLook preview of a file: &lt;code&gt;qlmanage -p ~/Desktop/text.txt&lt;/code&gt;&lt;/p&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://www.techrepublic.com/article/16-terminal-commands-every-user-should-know/&quot;&gt;&quot;16 Terminal commands every user should know&quot;&lt;/a&gt;:&lt;/p&gt; 
  &lt;ul&gt; 
   &lt;li&gt; &lt;p&gt;Copy contents of a folder to a new folder: &lt;code&gt;ditto&lt;/code&gt;&lt;/p&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;Get one-line description for a command: &lt;code&gt;whatis&lt;/code&gt;&lt;/p&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;Keep the Mac from hibernating/sleeping: &lt;code&gt;caffeinate&lt;/code&gt;&lt;/p&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;a href=&quot;https://www.makeuseof.com/tag/useful-mac-osx-shortcuts-pdf/&quot;&gt;&quot;Useful macOS shortcuts&quot;&lt;/a&gt;:&lt;/p&gt; &lt;p&gt;Startup: Intel&lt;/p&gt; 
  &lt;table&gt; 
   &lt;thead&gt; 
    &lt;tr&gt;
     &lt;th&gt;Action &lt;/th&gt;
     &lt;th&gt; Keystroke(s)&lt;/th&gt;
    &lt;/tr&gt; 
   &lt;/thead&gt; 
   &lt;tbody&gt; 
    &lt;tr&gt;
     &lt;td&gt;Boot without automatic login &lt;/td&gt;
     &lt;td&gt; Left shift (Press and hold when macOS progress indicator appears)&lt;/td&gt;
    &lt;/tr&gt; 
    &lt;tr&gt;
     &lt;td&gt;Boot in Safe Mode (Intel) &lt;/td&gt;
     &lt;td&gt; Shift (Press and hold)&lt;/td&gt;
    &lt;/tr&gt; 
    &lt;tr&gt;
     &lt;td&gt;Boot in Single User Mode (Intel, unavailable in macOS Mojave and later) &lt;/td&gt;
     &lt;td&gt; Cmd + S&lt;/td&gt;
    &lt;/tr&gt; 
    &lt;tr&gt;
     &lt;td&gt;Boot in Verbose Mode (Intel) &lt;/td&gt;
     &lt;td&gt; Cmd + V&lt;/td&gt;
    &lt;/tr&gt; 
    &lt;tr&gt;
     &lt;td&gt;Boot in Target Disk Mode (Intel) &lt;/td&gt;
     &lt;td&gt; T&lt;/td&gt;
    &lt;/tr&gt; 
    &lt;tr&gt;
     &lt;td&gt;Boot from a NetBoot network server &lt;/td&gt;
     &lt;td&gt; N&lt;/td&gt;
    &lt;/tr&gt; 
    &lt;tr&gt;
     &lt;td&gt;Boot to Startup Manager (Intel) &lt;/td&gt;
     &lt;td&gt; Option&lt;/td&gt;
    &lt;/tr&gt; 
    &lt;tr&gt;
     &lt;td&gt;Load macOS Recovery (Intel) &lt;/td&gt;
     &lt;td&gt; Cmd + R&lt;/td&gt;
    &lt;/tr&gt; 
    &lt;tr&gt;
     &lt;td&gt;Load macOS Recovery over the internet (Intel) &lt;/td&gt;
     &lt;td&gt; Option + Cmd + R&lt;/td&gt;
    &lt;/tr&gt; 
    &lt;tr&gt;
     &lt;td&gt;Enter Apple Diagnostics (Intel) &lt;/td&gt;
     &lt;td&gt; D&lt;/td&gt;
    &lt;/tr&gt; 
    &lt;tr&gt;
     &lt;td&gt;Load Apple Diagnostics over the internet &lt;/td&gt;
     &lt;td&gt; Option + D&lt;/td&gt;
    &lt;/tr&gt; 
    &lt;tr&gt;
     &lt;td&gt;Reset NVRAM or PRAM (Intel, unnecessary on Apple Silicon Macs) &lt;/td&gt;
     &lt;td&gt; Option + Cmd + P + R&lt;/td&gt;
    &lt;/tr&gt; 
    &lt;tr&gt;
     &lt;td&gt;Eject removable media &lt;/td&gt;
     &lt;td&gt; F12&lt;/td&gt;
    &lt;/tr&gt; 
   &lt;/tbody&gt; 
  &lt;/table&gt; &lt;p&gt;Startup: Apple Silicon&lt;/p&gt; 
  &lt;table&gt; 
   &lt;thead&gt; 
    &lt;tr&gt;
     &lt;th&gt;Action &lt;/th&gt;
     &lt;th&gt; Keystroke(s)&lt;/th&gt;
    &lt;/tr&gt; 
   &lt;/thead&gt; 
   &lt;tbody&gt; 
    &lt;tr&gt;
     &lt;td&gt;Boot without automatic login &lt;/td&gt;
     &lt;td&gt; Left shift (Press and hold when macOS progress indicator appears)&lt;/td&gt;
    &lt;/tr&gt; 
    &lt;tr&gt;
     &lt;td&gt;Boot in Safe Mode (Apple Silicon) &lt;/td&gt;
     &lt;td&gt; Power (Press and hold), then select a volume, then hold Shift while clicking Continue in Safe Mode&lt;/td&gt;
    &lt;/tr&gt; 
    &lt;tr&gt;
     &lt;td&gt;Boot to Startup Manager (Apple Silicon) &lt;/td&gt;
     &lt;td&gt; Power&lt;/td&gt;
    &lt;/tr&gt; 
    &lt;tr&gt;
     &lt;td&gt;Enter Apple Diagnostics (Apple Silicon) &lt;/td&gt;
     &lt;td&gt; Cmd + D&lt;/td&gt;
    &lt;/tr&gt; 
    &lt;tr&gt;
     &lt;td&gt;Load macOS Recovery (Apple Silicon) &lt;/td&gt;
     &lt;td&gt; Power, then select Options, then click Continue&lt;/td&gt;
    &lt;/tr&gt; 
    &lt;tr&gt;
     &lt;td&gt;Load Apple Diagnostics over the internet &lt;/td&gt;
     &lt;td&gt; Option + D&lt;/td&gt;
    &lt;/tr&gt; 
    &lt;tr&gt;
     &lt;td&gt;Boot from a NetBoot network server &lt;/td&gt;
     &lt;td&gt; N&lt;/td&gt;
    &lt;/tr&gt; 
    &lt;tr&gt;
     &lt;td&gt;Eject removable media &lt;/td&gt;
     &lt;td&gt; F12&lt;/td&gt;
    &lt;/tr&gt; 
   &lt;/tbody&gt; 
  &lt;/table&gt; &lt;p&gt;Finder&lt;/p&gt; 
  &lt;table&gt; 
   &lt;thead&gt; 
    &lt;tr&gt;
     &lt;th&gt;Action &lt;/th&gt;
     &lt;th&gt; Keystroke(s)&lt;/th&gt;
    &lt;/tr&gt; 
   &lt;/thead&gt; 
   &lt;tbody&gt; 
    &lt;tr&gt;
     &lt;td&gt;Go to folder &lt;/td&gt;
     &lt;td&gt; Cmd + Shift + G&lt;/td&gt;
    &lt;/tr&gt; 
    &lt;tr&gt;
     &lt;td&gt;Show/hide the Path Bar &lt;/td&gt;
     &lt;td&gt; Option + Cmd + P&lt;/td&gt;
    &lt;/tr&gt; 
    &lt;tr&gt;
     &lt;td&gt;Show/hide the Status Bar &lt;/td&gt;
     &lt;td&gt; Option + Cmd + / (Slash)&lt;/td&gt;
    &lt;/tr&gt; 
   &lt;/tbody&gt; 
  &lt;/table&gt; &lt;p&gt;General&lt;/p&gt; 
  &lt;table&gt; 
   &lt;thead&gt; 
    &lt;tr&gt;
     &lt;th&gt;Action &lt;/th&gt;
     &lt;th&gt; Keystroke(s)&lt;/th&gt;
    &lt;/tr&gt; 
   &lt;/thead&gt; 
   &lt;tbody&gt; 
    &lt;tr&gt;
     &lt;td&gt;Lock the screen &lt;/td&gt;
     &lt;td&gt; Cmd + Control + Q&lt;/td&gt;
    &lt;/tr&gt; 
    &lt;tr&gt;
     &lt;td&gt;Log out &lt;/td&gt;
     &lt;td&gt; Shift + Cmd + Q&lt;/td&gt;
    &lt;/tr&gt; 
    &lt;tr&gt;
     &lt;td&gt;Log out without confirmation &lt;/td&gt;
     &lt;td&gt; Option + Shift + Cmd + Q&lt;/td&gt;
    &lt;/tr&gt; 
    &lt;tr&gt;
     &lt;td&gt;Display the macOS screenshotting tools &lt;/td&gt;
     &lt;td&gt; Cmd + 5&lt;/td&gt;
    &lt;/tr&gt; 
    &lt;tr&gt;
     &lt;td&gt;Take a screenshot of the entire screen &lt;/td&gt;
     &lt;td&gt; Shift + Cmd + 3&lt;/td&gt;
    &lt;/tr&gt; 
    &lt;tr&gt;
     &lt;td&gt;Take a screenshot of a portion of the screen &lt;/td&gt;
     &lt;td&gt; Shift + Cmd + 4 (then hold Space to drag the selection, if needed)&lt;/td&gt;
    &lt;/tr&gt; 
    &lt;tr&gt;
     &lt;td&gt;Take a screenshot of a specific window or menu &lt;/td&gt;
     &lt;td&gt; Cmd + Shift + 4, then Space&lt;/td&gt;
    &lt;/tr&gt; 
    &lt;tr&gt;
     &lt;td&gt;Close all windows &lt;/td&gt;
     &lt;td&gt; Option + Cmd + W&lt;/td&gt;
    &lt;/tr&gt; 
    &lt;tr&gt;
     &lt;td&gt;Paste and delete original items &lt;/td&gt;
     &lt;td&gt; Option + Cmd + V&lt;/td&gt;
    &lt;/tr&gt; 
    &lt;tr&gt;
     &lt;td&gt;Paste and match style &lt;/td&gt;
     &lt;td&gt; Shift + Option + Cmd + V&lt;/td&gt;
    &lt;/tr&gt; 
    &lt;tr&gt;
     &lt;td&gt;Zoom in &lt;/td&gt;
     &lt;td&gt; Cmd + + (Plus)&lt;/td&gt;
    &lt;/tr&gt; 
    &lt;tr&gt;
     &lt;td&gt;Zoom out &lt;/td&gt;
     &lt;td&gt; Cmd + - (Minus)&lt;/td&gt;
    &lt;/tr&gt; 
    &lt;tr&gt;
     &lt;td&gt;Open preferences for the current app &lt;/td&gt;
     &lt;td&gt; Cmd + , (Comma)&lt;/td&gt;
    &lt;/tr&gt; 
    &lt;tr&gt;
     &lt;td&gt;Open Spotlight search &lt;/td&gt;
     &lt;td&gt; Cmd + Space&lt;/td&gt;
    &lt;/tr&gt; 
    &lt;tr&gt;
     &lt;td&gt;Hide/show the Dock &lt;/td&gt;
     &lt;td&gt; Option + Cmd + D&lt;/td&gt;
    &lt;/tr&gt; 
    &lt;tr&gt;
     &lt;td&gt;Show the Character Viewer &lt;/td&gt;
     &lt;td&gt; Control + Cmd + Space&lt;/td&gt;
    &lt;/tr&gt; 
    &lt;tr&gt;
     &lt;td&gt;Show the emoji picker &lt;/td&gt;
     &lt;td&gt; Fn&lt;/td&gt;
    &lt;/tr&gt; 
    &lt;tr&gt;
     &lt;td&gt;Show desktop icons as stacks &lt;/td&gt;
     &lt;td&gt; Cmd + Control + 0&lt;/td&gt;
    &lt;/tr&gt; 
    &lt;tr&gt;
     &lt;td&gt;Switch the current app to fullscreen mode &lt;/td&gt;
     &lt;td&gt; Control + Cmd + F&lt;/td&gt;
    &lt;/tr&gt; 
    &lt;tr&gt;
     &lt;td&gt;Quit the selected app in the app switcher &lt;/td&gt;
     &lt;td&gt; Cmd + Shift, then Q&lt;/td&gt;
    &lt;/tr&gt; 
    &lt;tr&gt;
     &lt;td&gt;Force quit apps &lt;/td&gt;
     &lt;td&gt; Option + Cmd + Esc&lt;/td&gt;
    &lt;/tr&gt; 
    &lt;tr&gt;
     &lt;td&gt;Switch to the next window in the current app &lt;/td&gt;
     &lt;td&gt; Cmd + ~ (Tilde)&lt;/td&gt;
    &lt;/tr&gt; 
    &lt;tr&gt;
     &lt;td&gt;Put display(s) to sleep &lt;/td&gt;
     &lt;td&gt; Shift + Control + Eject&lt;/td&gt;
    &lt;/tr&gt; 
    &lt;tr&gt;
     &lt;td&gt;Put your computer to sleep &lt;/td&gt;
     &lt;td&gt; Option + Cmd + Eject&lt;/td&gt;
    &lt;/tr&gt; 
    &lt;tr&gt;
     &lt;td&gt;Quit all apps and restart &lt;/td&gt;
     &lt;td&gt; Control + Cmd + Eject&lt;/td&gt;
    &lt;/tr&gt; 
    &lt;tr&gt;
     &lt;td&gt;Quit all apps and shut down &lt;/td&gt;
     &lt;td&gt; Control + Option + Cmd + Power&lt;/td&gt;
    &lt;/tr&gt; 
    &lt;tr&gt;
     &lt;td&gt;Choose from Sleep, Restart, and Shutdown options &lt;/td&gt;
     &lt;td&gt; Control + Eject&lt;/td&gt;
    &lt;/tr&gt; 
   &lt;/tbody&gt; 
  &lt;/table&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;A/V Tricks&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://macreports.com/record-face-screen-mac/&quot;&gt;&quot;How to Record Your Face and Screen&quot;&lt;/a&gt;: 
  &lt;ol&gt; 
   &lt;li&gt; &lt;p&gt;1-Launch QuickTime player. It can be found in the applications folder.&lt;/p&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;Select File &amp;gt; New Movie Recording.&lt;/p&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;Select View &amp;gt; Float on top so that your camera window will be on top of any other application anywhere on your screen. If you do not select this, your video may not record you.&lt;/p&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;Now you can resize the camera window. You can move this camera view anywhere you want (left, right, top, bottom, etc).&lt;/p&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;Now again, in QuickTime Player, select File &amp;gt; New Screen Recording. You can change some settings by clicking the arrow next to the Record button. You can record your full screen or part of your Mac screen. You may want to arrange your screen (where will your camera be etc?) before you start your recording.&lt;/p&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;When you are ready to start recording, click the red record button. You have two options: (a) if you want to record your entire screen, click anywhere on your screen to start the actual recording (b) or you may drag to select an area.&lt;/p&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;Now you are recording your screen and your camera view (e.g. your face). When you are done recording you may press the Command-Control-Esc keys. After you done, you may also edit your video using Quicktime. For instance, you may go to QuickTime &amp;gt; Edit &amp;gt; Trim to remove the unwanted parts of your video.&lt;/p&gt; &lt;/li&gt; 
  &lt;/ol&gt; &lt;p&gt;Additional notes:&lt;/p&gt; 
  &lt;ul&gt; 
   &lt;li&gt;You can also press Shift-Command (⌘)-5 to create video and capture still images of your screen.&lt;/li&gt; 
   &lt;li&gt;Please note that if your Mac does not have a built-in camera, you can use an external camera.&lt;/li&gt; 
   &lt;li&gt;You can use an iOS device connected to your Mac to record a video on your device.&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Mendix</title>
      <link>https://tedneward.github.io/Research/platforms/mendix/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">platforms/mendix/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.mendix.com/&quot;&gt;Website&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Minix</title>
      <link>https://tedneward.github.io/Research/platforms/minix/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">platforms/minix/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;http://www.minix3.org/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;http://git.minix3.org/?p=minix.git;a=summary&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;From the book &lt;a href=&quot;https://www.amazon.com/Operating-Systems-Design-Implementat-Implementation/dp/9332550514/ref=sr_1_1&quot;&gt;&quot;Operating Systems: Design and Implementation&quot;&lt;/a&gt; (3rd Ed) by Tanenbaum&lt;/p&gt; 
&lt;p&gt;Generally considered the starting point for most classic operating systems study. At some point I want to pull down the Minix ISO and install it into a VirtualBox so that I can hack on an OS for a while. &lt;em&gt;sigh&lt;/em&gt; Someday....&lt;/p&gt; 
&lt;p&gt;Dormant since 2018.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>LineageOS</title>
      <link>https://tedneward.github.io/Research/platforms/mobile/lineageos/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">platforms/mobile/lineageos/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.lineageos.org/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://gitlab.com/LineageOS&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Article: &lt;a href=&quot;https://thenewleafjournal.com/installing-lineageos-on-a-2013-nexus-7-wi-fi/&quot;&gt;Installing LineageOS on a 2013 Nexus 7&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>NativeScript</title>
      <link>https://tedneward.github.io/Research/platforms/nativescript/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">platforms/nativescript/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.nativescript.org/&quot;&gt;Website&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>NodeJS (platform)</title>
      <link>https://tedneward.github.io/Research/platforms/nodejs/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">platforms/nodejs/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://nodejs.org/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/nodejs/node&quot;&gt;Github&lt;/a&gt;&lt;/p&gt; 
&lt;h2&gt;Libraries&lt;/h2&gt; 
&lt;p&gt;&lt;a href=&quot;https://www.prisma.io/&quot;&gt;Prisma&lt;/a&gt;: helps app developers build faster and make fewer errors with an open source database toolkit for PostgreSQL, MySQL, SQL Server, and SQLite. &lt;a href=&quot;https://softwareengineeringdaily.com/2020/06/04/prisma-modern-database-tooling-with-johannes-schickling/&quot;&gt;Software Engineering Daily interview&lt;/a&gt;&lt;/p&gt; 
&lt;h2&gt;Debugging&lt;/h2&gt; 
&lt;p&gt;&lt;a href=&quot;https://github.com/GoogleChromeLabs/ndb&quot;&gt;ndb&lt;/a&gt;: improved debugging experience for NodeJS&lt;/p&gt; 
&lt;h2&gt;Interoperability&lt;/h2&gt; 
&lt;p&gt;&lt;a href=&quot;https://github.com/microsoft/node-api-dotnet&quot;&gt;node-api-dotnet&lt;/a&gt;: Advanced interoperability between .NET and JavaScript in the same process.&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=G36lrPrF09c&amp;amp;ab_channel=NearForm&quot;&gt;Node.js startup performance&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>OpenFin</title>
      <link>https://tedneward.github.io/Research/platforms/openfin/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">platforms/openfin/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.openfin.co/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/openfin&quot;&gt;Source&lt;/a&gt; | &lt;a href=&quot;https://developers.openfin.co/of-docs&quot;&gt;Docs&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Basically looks like a unified Web &quot;workspace&quot; concept. May be low-code, hard to tell without diving into it more deeply. Dev environment appears to rely on NodeJS.&lt;/p&gt; 
&lt;h2&gt;What is OpenFin?&lt;/h2&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;OpenFin is a web runtime and operating environment designed for enterprise app development. Built on web standards, OpenFin dramatically enhances the capabilities of web apps, enabling end-user experience and enterprise controls well beyond what is possible with browsers like Chrome and Edge or with frameworks like Electron and Chromium Embedded Framework.&lt;/p&gt; 
 &lt;p&gt;We offer an out of the box platform solution through OpenFin Workspace or the ability to build from scratch using APIs provided by OpenFin Container. Whichever path you choose, OpenFin dramatically improves the desktop experience by securely connecting disparate apps and content in intuitive, efficient, and meaningful ways.&lt;/p&gt; 
&lt;/blockquote&gt; 
&lt;p&gt;Architecture diagram:&lt;br&gt; &lt;img src=&quot;https://files.readme.io/3f54afa-Architecture_Diagram_v3.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt; 
&lt;p&gt;Sounds like a portal/&quot;work canvas&quot;/Smalltalk-browser-like experience inside a web browser. &quot;Notification Center&quot; seems to imply a messaging-based backplane. Architecture diagram shows Electron and Chromium, possibly to allow for desktop apps?&lt;/p&gt; 
&lt;h2&gt;Workspace apps&lt;/h2&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;Workspace apps organize and connect content across the desktop with Home, Browser, Notification Center &amp;amp; Content Store.&lt;/p&gt; 
 &lt;p&gt;OpenFin Workspace is a unified space for work, powered by an extensive set of tools designed to help your firm increase productivity and deliver exceptional employee experiences. Key components of Workspace include a keyboard-driven digital assistant for app discovery and search; a browser for displaying content with complex layouts and shared context; and a rich, actionable notification center, experiences that accelerate time to market, and easy-to-use APIs for hyper-customization.&lt;/p&gt; 
 &lt;p&gt;&lt;strong&gt;Built by OpenFin.&lt;/strong&gt; Workspace components are built and managed by OpenFin. We enable customization through configuration. &lt;strong&gt;Component Hosting.&lt;/strong&gt; Workspace components are hosted securely on OpenFin’s CDN. &lt;strong&gt;Desktop Owner Settings.&lt;/strong&gt; Workspace can be configured using the OpenFin Desktop Owner Settings file. For example, this allows you to point Workspace at your own Content Store. &lt;strong&gt;Content Discovery Service.&lt;/strong&gt; By default, Workspace components are configured to point at OpenFin’s Content Discovery Service, which powers the OpenFin Content Store. You can point Workspace at your own Content Discovery Service hosted on your own infrastructure. &lt;strong&gt;Versioning.&lt;/strong&gt; Each release of Workspace is versioned. You can lock the version of Workspace that you run via Desktop Owner Settings.&lt;/p&gt; 
&lt;/blockquote&gt; 
&lt;h2&gt;What is OpenFin Container?&lt;/h2&gt; 
&lt;p&gt;OpenFin Container is a desktop runtime application environment that enables communication between all of your apps (web, legacy, third-party) for the enterprise desktop. It is built on top of Google Chromium and GitHub Electron and combines advanced interoperability, lightning-fast distribution, and robust security with an agile web development and deployment model.&lt;/p&gt; 
&lt;p&gt;Any web app that runs in Google Chrome can run on OpenFin OS unmodified and in a matter of seconds. With OpenFin, developers write 99% of their code with standard HTML5 and the JavaScript frameworks of their choice, including React and Angular. OpenFin APIs (usually &amp;lt;1% of code) enable windowing, interoperability and system access.&lt;/p&gt; 
&lt;h3&gt;Platform Provider&lt;/h3&gt; 
&lt;p&gt;The Platform Provider is the main application window which is the communication hub that coordinates between all the windows in a Platform Application. The provider runs in a hidden window and enables application providers to extend or overwrite default Platform behavior through Platform Overrides. This is where you can control how your application will look and feel to create a custom branded experience.&lt;/p&gt; 
&lt;h3&gt;Platform Window&lt;/h3&gt; 
&lt;p&gt;Platform Windows act as a “frame” for your Platform Views and can be leveraged to display UI controllers such as Minimize, Maximize and Close. These are child windows of the Provider and may contain 1 or many Platform Views.&lt;/p&gt; 
&lt;h3&gt;Platform View&lt;/h3&gt; 
&lt;p&gt;Platform Views are your applications content and they reside within a Platform Window. The content (a web application) is loaded into a view and attached to a Platform Window. Views have their own JavaScript context that is distinct and unconnected to the window’s context, that have no DOM representation within the window. This allows views to move between windows without refreshing or otherwise destroying the context. Views can be tabbed/tabless and provide the end-user ease to arrange the layout of a Platform Window. For optimal performances, it is worth noting that views can be split into as many render processes as needed through processAffinity.&lt;/p&gt; 
&lt;h3&gt;Layout Management&lt;/h3&gt; 
&lt;p&gt;Layout management enables applications providers to programmatically embed multiple views or “web apps” in a single Platform Window.&lt;/p&gt; 
&lt;h3&gt;Snapshot&lt;/h3&gt; 
&lt;p&gt;A Snapshot defines the Platform Window and View configuration to be launched into a Platform. When added as a top-level option in your Platform manifest, the Platform will launch with that Snapshot by default. Snapshots also enable application providers the ability to replenish/restore saved configurations while the Platform is running.&lt;/p&gt; 
&lt;h3&gt;Platform Manifest&lt;/h3&gt; 
&lt;p&gt;This is the file that defines how an OpenFin Platform works and tells the OpenFin Runtime what your workspace will look like at Launch.&lt;/p&gt; 
&lt;h3&gt;Process Affinity&lt;/h3&gt; 
&lt;p&gt;By default, all child windows of a Platform Provider share a single renderer process, based on same-origin policy. Views can be separated into further processes by providing a processAffinity option. This enables application providers to have two or more views share a process separate from other views. This can be quite useful in architecting your application for views that have a heavier memory profile.&lt;/p&gt; 
&lt;hr&gt; 
&lt;p&gt;&lt;strong&gt;Content Discovery Service.&lt;/strong&gt; &quot;Implements the GET methods of the FDC3 App Directory specification, with some additional optional properties for defining the content items. A content discovery service can provide apps or workspaces.&quot;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Oqtane</title>
      <link>https://tedneward.github.io/Research/platforms/oqtane/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">platforms/oqtane/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.oqtane.org/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/oqtane/framework&quot;&gt;Github&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>PhotonOS</title>
      <link>https://tedneward.github.io/Research/platforms/photonos/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">platforms/photonos/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://vmware.github.io/photon/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/vmware/photon&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Play</title>
      <link>https://tedneward.github.io/Research/platforms/play/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">platforms/play/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.createwithplay.com/&quot;&gt;Website&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Prefect</title>
      <link>https://tedneward.github.io/Research/platforms/prefect/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">platforms/prefect/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.prefect.io/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/prefecthq/prefect&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Hello world&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;from prefect import task, Flow

@task
def say_hello():
    print(&quot;Hello, World!&quot;)

with Flow(&quot;My First Flow&quot;) as flow:
    say_hello()

flow.run() # &quot;Hello, world!&quot;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Source appears to be &lt;a href=&quot;https://www.prefect.io/core/&quot;&gt;PrefectCore&lt;/a&gt; (Python library), which suggests a &quot;freemium&quot; open-source model.&lt;/p&gt; 
&lt;p&gt;Features described:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Realtime UI: The Prefect UI updates in realtime so you&apos;re never behind.&lt;/li&gt; 
 &lt;li&gt;Universal Deploy: Anywhere you can run Python, you can run Prefect. Instantly deploy your flows and monitor runs from Prefect&apos;s UI, no Docker required.&lt;/li&gt; 
 &lt;li&gt;Flow code: Prefect flows are plain old Python, so you can build and modify them however you like.&lt;/li&gt; 
 &lt;li&gt;Parameters: Add parameters to any flow for easy runtime templating and reuse.&lt;/li&gt; 
 &lt;li&gt;Robust states: Prefect handles every error, whether expected or not. Some tasks might only run if upstream tasks fail.&lt;/li&gt; 
 &lt;li&gt;Dataflow: Pass data between tasks for complex processing and advanced analytics.&lt;/li&gt; 
 &lt;li&gt;Mapping: Powerful map/reduce operators generate dynamic tasks for each element of an input. Mapped tasks can be linked to create parallel pipelines.&lt;/li&gt; 
 &lt;li&gt;Environments: A flexible environment model means flows can be deployed anywhere from a laptop to multi-cloud clusters.&lt;/li&gt; 
 &lt;li&gt;Realtime: When paired with Dask, Prefect&apos;s event-driven scheduler can execute tasks with millisecond latency.&lt;/li&gt; 
 &lt;li&gt;Time Travel: Prefect task outputs can be cached or updated at different intervals, even within the same workflow.&lt;/li&gt; 
 &lt;li&gt;Result Handlers: Serialize data in and out of your tasks with customizable result handlers, including local filesystems, S3, and GCS.&lt;/li&gt; 
 &lt;li&gt;Custom Schedules: Specify custom schedule logic including business days, offsets, and blackout windows, or fall back on good old cron.&lt;/li&gt; 
 &lt;li&gt;Looping: Loop tasks with arbitrary control logic.&lt;/li&gt; 
 &lt;li&gt;Depth-First Execution: Race through mapped pipelines by allowing tasks to start before all tasks of the previous stage have finished.&lt;/li&gt; 
 &lt;li&gt;COMING SOON -- Event-Driven Flows: Fire off flow runs in response to external events of any frequency.&lt;/li&gt; 
 &lt;li&gt;COMING SOON -- Task Affinity: Run each of a flow&apos;s tasks in a completely different environment, including new dependencies or platforms.&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Qemu</title>
      <link>https://tedneward.github.io/Research/platforms/qemu/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">platforms/qemu/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://airbus-seclab.github.io/qemu_blog/&quot;&gt;Qemu Internals&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Quix</title>
      <link>https://tedneward.github.io/Research/platforms/quix/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">platforms/quix/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://quix.io/docs/get-started/welcome.html&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/quixio&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Redox</title>
      <link>https://tedneward.github.io/Research/platforms/redox/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">platforms/redox/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.redox-os.org/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://gitlab.redox-os.org/redox-os/redox/&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Rhodes (RhoMobile, RhoConnect, RhoStudio, RhoSuite, ...)</title>
      <link>https://tedneward.github.io/Research/platforms/rhodes/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">platforms/rhodes/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://tau-platform.com/en/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/rhomobile&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;h2&gt;Overview&lt;/h2&gt; 
&lt;p&gt;The Rhodes framework is a platform for building locally executing, device-optimized mobile applications for all major smartphone devices.&lt;/p&gt; 
&lt;h3&gt;Installation&lt;/h3&gt; 
&lt;p&gt;&lt;a href=&quot;http://docs.tau-platform.com/en/7.5/guide/rhomobile-install#windows-first-time-install-32--and-64-bit&quot;&gt;Windows First-time Install (32- and 64-bit)&lt;/a&gt; - How to install RhoMobile Suite on Windows (32- and 64-bit).&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;http://docs.tau-platform.com/en/7.5/guide/rhomobile-install#mac-os-x-first-time-install&quot;&gt;Mac OS X First-time Install&lt;/a&gt; - How to install RhoMobile Suite on Mac OS.&lt;/p&gt; 
&lt;h3&gt;Building apps&lt;/h3&gt; 
&lt;p&gt;&lt;a href=&quot;http://docs.tau-platform.com/en/7.5/guide/build_android&quot;&gt;Build for Android&lt;/a&gt; - How to build apps for Android.&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;http://docs.tau-platform.com/en/7.5/guide/build_ios&quot;&gt;Build for iOS&lt;/a&gt; - How to build apps for iOS.&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;http://docs.tau-platform.com/en/7.5/guide/build_win&quot;&gt;Building for Windows&lt;/a&gt; - How to build apps for Windows.&lt;/p&gt; 
&lt;h3&gt;RhoConnect Push Synchronization&lt;/h3&gt; 
&lt;p&gt;&lt;a href=&quot;http://docs.tau-platform.com/en/7.5/rhoconnect/push&quot;&gt;Introduction to Push&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;http://docs.tau-platform.com/en/7.5/rhoconnect/push-client-setup-android&quot;&gt;Set up Google Cloud Messaging on client and server for Rhodes Android Device&lt;/a&gt; - Setting Up RhoConnect Push-Based Synchronization with Google Cloud Messaging.&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;http://docs.tau-platform.com/en/7.5/rhoconnect/push-client-setup-ios&quot;&gt;Set up Apple Push Notification Service on client and server for Rhodes iOS Device&lt;/a&gt; - Setting Up RhoConnect Push-Based Synchronization with Apple Push Notification Service.&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;http://docs.tau-platform.com/en/7.5/rhoconnect/push-client-setup-rps&quot;&gt;Set up RhoConnect Push Service on client and server for Rhodes Android and Windows Mobile/CE Devices&lt;/a&gt; - Setting Up for RhoConnect Push Service on Client Application for Windows Mobile/CE Devices.&lt;/p&gt; 
&lt;h3&gt;Android Docs&lt;/h3&gt; 
&lt;p&gt;&lt;a href=&quot;https://github.com/rhomobile/rhodes/blob/master/doc/oss/Barcode_support_doc.md&quot;&gt;Guidelines To Support Barcode API On Android JellyBean Devices&lt;/a&gt; - Lists the Zebra Android devices capable of barcode scanning, their OS image versions and steps for activating the feature.&lt;/p&gt; 
&lt;h3&gt;Repositories Released as Open Source&lt;/h3&gt; 
&lt;p&gt;Clone these repo(s) as required for your needs to generate a copy of the open source code to the local development machine.&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://github.com/rhomobile/rhodes/&quot;&gt;Rhodes&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://github.com/rhomobile/rhoconnect/&quot;&gt;RhoConnect&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://github.com/rhomobile/rhoconnect-client/&quot;&gt;RhoConnect Client&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://github.com/rhomobile/rhoconnect-push&quot;&gt;RhoConnect Push&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://github.com/rhomobile/rhoconnect-push-service&quot;&gt;RhoConnect Push Service&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://github.com/rhomobile/rhostudio/&quot;&gt;RhoStudio&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://github.com/rhomobile/rhoinstaller/&quot;&gt;RhoInstaller&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://github.com/rhomobile/RMS-Testing&quot;&gt;RMS-Testing&lt;/a&gt;&lt;/p&gt; 
&lt;h2&gt;Reading&lt;/h2&gt; 
&lt;p&gt;&lt;a href=&quot;https://reintech.io/blog/developing-cross-platform-mobile-apps-with-ruby&quot;&gt;Developing Cross-platform mobile apps with Ruby&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Saltcorn</title>
      <link>https://tedneward.github.io/Research/platforms/saltcorn/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">platforms/saltcorn/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://saltcorn.com/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/saltcorn/saltcorn&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Sharemind</title>
      <link>https://tedneward.github.io/Research/platforms/sharemind/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">platforms/sharemind/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://sharemind.cyber.ee/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/sharemind-sdk/sharemind-sdk.github.io&quot;&gt;SDK&lt;/a&gt; | &lt;a href=&quot;https://github.com/sharemind-sdk/vm_m4&quot;&gt;VM&lt;/a&gt;&lt;/p&gt; 
&lt;h2&gt;Tools:&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/sharemind-sdk/sbdump&quot;&gt;sbdump&lt;/a&gt;: Sharemind Executable Disassembler tool&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/sharemind-sdk/secrec&quot;&gt;secrec&lt;/a&gt;: Sharemind SecreC Compiler and Analyzer&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/sharemind-sdk/secrec-stdlib&quot;&gt;secrec-stdlib&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Space Cloud</title>
      <link>https://tedneward.github.io/Research/platforms/spacecloud/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">platforms/spacecloud/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://space-cloud.io/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/spacecloud-io/space-cloud&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Sulu</title>
      <link>https://tedneward.github.io/Research/platforms/sulu/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">platforms/sulu/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://sulu.io/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/sulu/sulu&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Tangled</title>
      <link>https://tedneward.github.io/Research/platforms/tangled/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">platforms/tangled/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://tangled.sh/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://tangled.sh/@tangled.sh/core&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;h2&gt;Reading&lt;/h2&gt; 
&lt;p&gt;&lt;a href=&quot;https://anil.recoil.org/notes/disentangling-git-with-bluesky&quot;&gt;Socially self-hosting source code with Tangled on Bluesky&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Tooljet</title>
      <link>https://tedneward.github.io/Research/platforms/tooljet/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">platforms/tooljet/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://tooljet.io/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/tooljet/tooljet&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;You can connect to your data sources such as databases ( like PostgreSQL, MongoDB, Elasticsearch, etc ), API endpoints ( ToolJet supports importing OpenAPI spec &amp;amp; OAuth2 authorization) and external services ( like Stripe, Slack, Google Sheets, Airtable ) and use our pre-built UI widgets to build internal tools.&lt;/p&gt; 
&lt;/blockquote&gt; 
&lt;p&gt;Features&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Visual app builder with widgets such as tables, charts, modals, buttons, dropdowns and more&lt;/li&gt; 
 &lt;li&gt;Mobile 📱 &amp;amp; desktop layouts 🖥&lt;/li&gt; 
 &lt;li&gt;Connect to databases, APIs and external services&lt;/li&gt; 
 &lt;li&gt;Deploy on-premise ( supports docker, kubernetes, heroku and more )&lt;/li&gt; 
 &lt;li&gt;Granular access control on organization level and app level&lt;/li&gt; 
 &lt;li&gt;Write JS code almost anywhere in the builder&lt;/li&gt; 
 &lt;li&gt;Query editors for all supported data sources&lt;/li&gt; 
 &lt;li&gt;Transform query results using JS code&lt;/li&gt; 
 &lt;li&gt;Import endpoints from OpenAPI specs&lt;/li&gt; 
 &lt;li&gt;All the credentials are securely encrypted using aes-256-gcm.&lt;/li&gt; 
 &lt;li&gt;ToolJet acts only as a proxy and doesn&apos;t store any data.&lt;/li&gt; 
 &lt;li&gt;Support for OAuth&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;&lt;a href=&quot;https://www.marktechpost.com/2023/10/13/meet-tooljet-an-open-source-low-code-framework-to-build-and-deploy-internal-tools-with-minimal-engineering-effort/&quot;&gt;&quot;Meet ToolJet&quot;&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>UI Bakery</title>
      <link>https://tedneward.github.io/Research/platforms/uibakery/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">platforms/uibakery/index.html</guid>
      	<description>
	&lt;p&gt;Glue your databases, APIs, and third-party services together with beautiful UI components. Write custom JavaScript code if needed almost anywhere inside your web app.&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://uibakery.io/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/akveo&quot;&gt;Github links&lt;/a&gt; (not sure it&apos;s source to UIBakery)&lt;/p&gt; 
&lt;p&gt;Features:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Autogenerate UI components: Automatically configure Tables, Forms, Charts, Maps. Mirror a data structure into UI components.&lt;/li&gt; 
 &lt;li&gt;Connect, read and write your data: Natively connect a UI to data sources. Read, write, search data using built-in functions, SQL queries, HTTP requests.&lt;/li&gt; 
 &lt;li&gt;Create workflows and business logic: Add sequences and conditions, create advanced business logic for your internal app. Modify everything visually.&lt;/li&gt; 
 &lt;li&gt;Add custom code &amp;amp; create new components: Connect JavaScript libraries. Add custom code to map data. Build components using React or jQuery.&lt;/li&gt; 
 &lt;li&gt;Debug and test your app: Debug app state, handle runtime errors in the development stage. Get error notifications – we’ll help you fix them.&lt;/li&gt; 
 &lt;li&gt;Publish your internal tool: No manual app deployment, hosting, and environment setup. Publish an app securely, invite your end-users.&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>macOS (OS)</title>
      <link>https://tedneward.github.io/Research/platforms/macos/index/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">platforms/macos/index/index.html</guid>
      	<description>
	&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;../macos/usage&quot;&gt;Usage&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;../macos/vm&quot;&gt;Virtual machine images&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;../macos/development&quot;&gt;Development&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Miscellaneous tools&lt;/h2&gt; 
&lt;p&gt;&lt;a href=&quot;https://github.com/HamburgChimps/apple-notes-liberator&quot;&gt;Apple Notes Liberator&lt;/a&gt;: Free your Apple Notes data from Notes.app&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>macOS (OS) Virtual Machine Notes</title>
      <link>https://tedneward.github.io/Research/platforms/macos/vm/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">platforms/macos/vm/index.html</guid>
      	<description>
	&lt;h1&gt;Docker&lt;/h1&gt; 
&lt;p&gt;&lt;a href=&quot;https://github.com/sickcodes&quot;&gt;sick.codes&lt;/a&gt;: collection of interesting macOS-related repositories&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/sickcodes/Docker-OSX&quot;&gt;Docker-OSX&lt;/a&gt;: Run macOS VM in a Docker! Run near native OSX-KVM in Docker! X11 Forwarding! CI/CD for OS X Security Research! Docker mac Containers. 
  &lt;ul&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/sickcodes/Docker-eyeOS&quot;&gt;Docker-eyeOS&lt;/a&gt;: Run iPhone (xnu-arm64) in a Docker container! Supports KVM + iOS kernel debugging (GDB)! Run xnu-qemu-arm64 in Docker! Works on ANY device.&lt;/li&gt; 
   &lt;li&gt;&lt;a href=&quot;https://github.com/sickcodes/osx-optimizer&quot;&gt;osx-optimizer&lt;/a&gt;: OSX Optimizer: Optimize MacOS - Shell scripts to speed up your mac boot time, accelerate loading, and prevent unnecessary throttling.&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h1&gt;VirtualBox&lt;/h1&gt; 
&lt;p&gt;&lt;a href=&quot;https://www.xda-developers.com/how-install-macos-virtualbox/&quot;&gt;&quot;How to install macOS in VirtualBox&quot;&lt;/a&gt;&lt;/p&gt; 
&lt;h2&gt;Running macOS in a VirtualBox VM&lt;/h2&gt; 
&lt;p&gt;(Some details swiped from &lt;a href=&quot;https://techsviewer.com/install-macos-10-15-catalina-on-virtualbox-on-windows-pc/&quot;&gt;https://techsviewer.com/install-macos-10-15-catalina-on-virtualbox-on-windows-pc/&lt;/a&gt;)&lt;/p&gt; 
&lt;p&gt;Basic steps:&lt;br&gt; * Make sure Virtual Box Extension Pack is installed. Necessary (?) for USB setting below.&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt; &lt;p&gt;&lt;em&gt;Obtain a macOS ISO.&lt;/em&gt; The most &quot;legal&quot; thing to do seems to be to download the &quot;Install macOS {version}&quot; where &quot;{version}&quot; is Catalina, High Sierra, whatever, and then convert the installer application into an ISO via &lt;a href=&quot;https://gist.github.com/tedneward/5d4710983caf55906f834dc7c576a418&quot;&gt;this Gist&lt;/a&gt;.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;em&gt;Create the VBox Guest.&lt;/em&gt; Select &quot;Type: macOS&quot; and &quot;Version: (Latest macOS version)&quot;, where the latest macOS version offered was High Sierra when I tried this. Set RAM to be high--I chose 16GB on my 64GB MBP--and create a hard disk--I chose 100GB dynamic. Then set the following options:&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt;&quot;System&quot;/&quot;Motherboard&quot;: set &quot;Chipset: PIIX 3&quot;; set &quot;Enable EFI&quot; on.&lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&quot;System&quot;/&quot;Processor&quot;: set &quot;Cores&quot; to 2 (or 4, if you can); set &quot;Enable PAE/NX&quot; on.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&quot;Display&quot;/&quot;Screen&quot;: set &quot;Video Memory&quot; to 128MB; set &quot;Graphics Controller&quot; to &quot;VMSVGA&quot;. (On my running VBox right now, it&apos;s set to VBoxVGA, and wouldn&apos;t be set to anything else, so this may only be required for Windows machines. Verify.); I left 3D and 2D acceleration turned off.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&quot;Ports&quot;/&quot;USB&quot;: set &quot;Enable USB Controller&quot; on; select &quot;USB 3.0 (xHCI) Controller&quot;. Apparently macOS doesn&apos;t support USB 2.0 or 1.1 Controllers.&lt;/p&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;Then mount the macOS ISO as the ISO image.&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;em&gt;Tweak the VBox settings by hand.&lt;/em&gt; Next run the following shell commands (with VirtualBox on the command-line path):&lt;/li&gt; 
&lt;/ul&gt; 
&lt;pre&gt;&lt;code&gt;VBoxManage modifyvm &quot;Your VM Name&quot; --cpuidset 00000001 000106e5 00100800 0098e3fd bfebfbff
VBoxManage setextradata &quot;Your VM Name&quot; &quot;VBoxInternal/Devices/efi/0/Config/DmiSystemProduct&quot; &quot;iMac11,3&quot;
VBoxManage setextradata &quot;Your VM Name&quot; &quot;VBoxInternal/Devices/efi/0/Config/DmiSystemVersion&quot; &quot;1.0&quot;
VBoxManage setextradata &quot;Your VM Name&quot; &quot;VBoxInternal/Devices/efi/0/Config/DmiBoardProduct&quot; &quot;Iloveapple&quot;
VBoxManage setextradata &quot;Your VM Name&quot; &quot;VBoxInternal/Devices/smc/0/Config/DeviceKey&quot; &quot;ourhardworkbythesewordsguardedpleasedontsteal(c)AppleComputerInc&quot;
VBoxManage setextradata &quot;Your VM Name&quot; &quot;VBoxInternal/Devices/smc/0/Config/GetKeyFromRealSMC&quot; 1
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;No clue what these do but they appear to be necessary. I suspect they&apos;re Apple anti-piracy settings.&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt; &lt;p&gt;&lt;em&gt;Boot the ISO.&lt;/em&gt; The ISO won&apos;t immediately install to the created hard drive because it needs to be formatted first. From the &quot;macOS Utilities&quot; dialog select &quot;Disk Utility&quot; and Erase the VirtualBox hard drive as &quot;Format: MacOS Extended (Journaled)&quot; and &quot;Scheme: GUID Partition Map&quot;. Name can be whatever. When that&apos;s done, quit &quot;Disk Utility&quot; and &quot;Install macOS&quot; to the VBox hard drive.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;em&gt;Finish the macOS install.&lt;/em&gt; Remove the ISO, boot the VBox, and it should begin the installation process as per normal installation procedures. Create an account, and by the time that&apos;s all done, it should be good to go.&lt;/p&gt; &lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Meteor</title>
      <link>https://tedneward.github.io/Research/platforms/meteor/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">platforms/meteor/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.meteor.com/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://docs.meteor.com/#/full/&quot;&gt;Docs&lt;/a&gt; | &lt;a href=&quot;https://github.com/meteor/meteor&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Meteor is a full-stack JavaScript platform for developing modern web and mobile applications. Meteor includes a key set of technologies for building connected-client reactive applications, a build tool, and a curated set of packages from the Node.js and general JavaScript community.&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt; &lt;p&gt;Meteor allows you to develop in one language, JavaScript, in all environments: application server, web browser, and mobile device.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Meteor uses data on the wire, meaning the server sends data, not HTML, and the client renders it.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Meteor embraces the ecosystem, bringing the best parts of the extremely active JavaScript community to you in a careful and considered way.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Meteor provides full stack reactivity, allowing your UI to seamlessly reflect the true state of the world with minimal development effort.&lt;/p&gt; &lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>CaylixOS</title>
      <link>https://tedneward.github.io/Research/platforms/mobile/caylixos/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">platforms/mobile/caylixos/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://calyxos.org/&quot;&gt;Website&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Replicant</title>
      <link>https://tedneward.github.io/Research/platforms/mobile/replicant/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">platforms/mobile/replicant/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.replicant.us/&quot;&gt;Website&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Netlify CMS</title>
      <link>https://tedneward.github.io/Research/platforms/netlifycms/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">platforms/netlifycms/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.netlifycms.org/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/netlify/netlify-cms&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Seems related to &lt;a href=&quot;/clouds/netlify&quot;&gt;Netlify&lt;/a&gt;?&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>NsCDE</title>
      <link>https://tedneward.github.io/Research/platforms/nscde/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">platforms/nscde/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/NsCDE/NsCDE&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;One of the main aspects of Linux that attracts users is how much choice it offers. Not so Common Desktop Environment is a desktop environment to run over a Linux installation that looks and feels like the Common Desktop Environment (CDE) that ran on HP Unix systems. Enjoy a desktop full of 90s-era pastel shades while enjoying the modern conveniences of a recent Linux distro.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>OpenIndiana / illumos</title>
      <link>https://tedneward.github.io/Research/platforms/openindiana/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">platforms/openindiana/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://openindiana.org/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/openindiana&quot;&gt;Source&lt;/a&gt; | &lt;a href=&quot;https://docs.openindiana.org/&quot;&gt;Docs&lt;/a&gt; &lt;em&gt;(very sketchy/WIP as of August 2025)&lt;/em&gt; and &lt;a href=&quot;https://docs.openindiana.org/books/about/&quot;&gt;OpenSolaris books&lt;/a&gt;&lt;/p&gt; 
&lt;h2&gt;What is illumos?&lt;/h2&gt; 
&lt;p&gt;illumos is a collection of software that forms the core of an Operating System. It includes the kernel, device drivers, core system libraries, and utilities. Conceptually, the illumos idea of &quot;the operating system&quot; lies between something like Linux (which is the kernel only; all of userspace is delivered by vendors in a &quot;distribution&quot;) and the BSD family of operating systems, which are packaged as a complete unit (kernel, core libraries, userspace utilities, and even end-user software packages).&lt;/p&gt; 
&lt;p&gt;illumos is the home of many technologies including ZFS, DTrace, Zones, ctf, FMA, and more. We pride ourselves on having a stable, highly observable, and technologically different system. Finally, illumos has a proud engineering heritage, tracing it roots back through Sun Microsystems to the original releases of UNIX and BSD.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Oracle Apex</title>
      <link>https://tedneward.github.io/Research/platforms/oracle-apex/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">platforms/oracle-apex/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://apex.oracle.com/en/&quot;&gt;Website&lt;/a&gt; Commercial&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Plan9</title>
      <link>https://tedneward.github.io/Research/platforms/plan9/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">platforms/plan9/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;http://plan9.bell-labs.com/plan9/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;http://doc.cat-v.org/plan_9/&quot;&gt;Docs website&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;There&apos;s a lot of interesting ideas hiding out in here.&lt;/p&gt; 
&lt;h1&gt;&lt;a href=&quot;http://doc.cat-v.org/plan_9/1st_edition/&quot;&gt;First Edition&lt;/a&gt;&lt;/h1&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;http://doc.cat-v.org/plan_9/1st_edition/designing_plan_9&quot;&gt;Designing Plan 9 - Bell Labs&apos; Plan 9 research project looks to tomorrow&lt;/a&gt; by Rob Pike, Dave Presotto, Ken Thompson, and Howard Trickey.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://doc.cat-v.org/plan_9/1st_edition/help/&quot;&gt;Help: A Minimalist Global User Interface&lt;/a&gt; by Rob Pike&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://doc.cat-v.org/plan_9/1st_edition/cda/&quot;&gt;Circuit Design Aids (CDA) on Plan 9&lt;/a&gt; by A. G. Hume, M. Kahrs, T. J. Killian.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://doc.cat-v.org/plan_9/1st_edition/multiprocessor-streams&quot;&gt;Multiprocessor Streams for Plan 9&lt;/a&gt; by David Leo Presotto.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://doc.cat-v.org/plan_9/1st_edition/manual.pdf&quot;&gt;The complete Plan 9 from Bell Labs Programmer’s Manual First Edition&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h1&gt;&lt;a href=&quot;http://doc.cat-v.org/plan_9/2nd_edition/&quot;&gt;Second Edition&lt;/a&gt;&lt;/h1&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;http://doc.cat-v.org/plan_9/2nd_edition/README&quot;&gt;The &quot;README&quot;&lt;/a&gt; by Brian Kernighan - somewhat outdated, but still relevant today.&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;/languages/alef&quot;&gt;Alef&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://doc.cat-v.org/plan_9/2nd_edition/papers/panel/&quot;&gt;A Quick Introduction to the Panel Library&lt;/a&gt; by Tom Duff - used by the Mothra web browser&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://doc.cat-v.org/plan_9/2nd_edition/papers/gfx/&quot;&gt;Raster Graphics in plan9&lt;/a&gt; by Tom Duff - Ironically obsoleted the adoption in 3rd Edition of the Porter/Duff graphics model.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h1&gt;&lt;a href=&quot;http://doc.cat-v.org/plan_9/3rd_edition/&quot;&gt;Third Edition&lt;/a&gt;&lt;/h1&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;http://doc.cat-v.org/plan_9/3rd_edition/rio/&quot;&gt;Rio: Design of a Concurrent Window System&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://doc.cat-v.org/bell_labs/concurrent_window_system/&quot;&gt;A Concurrent Window System&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://doc.cat-v.org/bell_labs/transparent_wsys/&quot;&gt;Window Systems Should Be Transparent&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h1&gt;&lt;a href=&quot;http://doc.cat-v.org/plan_9/4th_edition/&quot;&gt;Fourth Edition&lt;/a&gt;&lt;/h1&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;http://doc.cat-v.org/plan_9/4th_edition/papers/&quot;&gt;Papers&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;http://man.cat-v.org/plan_9/&quot;&gt;Manual Pages&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Porter</title>
      <link>https://tedneward.github.io/Research/platforms/porter/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">platforms/porter/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://porter.run/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/porter-dev/porter&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Project Reactor</title>
      <link>https://tedneward.github.io/Research/platforms/projectreactor/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">platforms/projectreactor/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://projectreactor.io/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/reactor&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Several sub-projects:&lt;br&gt; * &lt;a href=&quot;https://github.com/reactor/reactor-core&quot;&gt;Reactor Core&lt;/a&gt;: A Reactive Streams foundation for Java 8&lt;br&gt; * &lt;a href=&quot;https://github.com/reactor/reactor-core/tree/master/reactor-test&quot;&gt;Reactor Test&lt;/a&gt;: Test utilities&lt;br&gt; * &lt;a href=&quot;https://github.com/reactor/reactor-addons/#reactor-extra&quot;&gt;Reactor Extra&lt;/a&gt;: Additional operators for Flux&lt;br&gt; * &lt;a href=&quot;https://github.com/reactor/reactor-netty&quot;&gt;Reactor Netty&lt;/a&gt;: HTTP, TCP, UDP Clients/Servers using Netty&lt;br&gt; * &lt;a href=&quot;https://github.com/reactor/reactor-addons/#reactor-adapter&quot;&gt;Reactor Adapter&lt;/a&gt;: Adapt to/from other reactive libraries&lt;br&gt; * &lt;a href=&quot;https://github.com/reactor/reactor-kafka&quot;&gt;Reactor Kafka&lt;/a&gt;: Reactive bridge to Apache Kafka&lt;br&gt; * &lt;a href=&quot;https://github.com/reactor/reactor-kotlin-extensions&quot;&gt;Reactor Kotlin Extensions&lt;/a&gt;: Kotlin extensions for all Java artifacts in Dysprosium+&lt;br&gt; * &lt;a href=&quot;https://github.com/reactor/reactor-rabbitmq&quot;&gt;Reactor RabbitMQ&lt;/a&gt;: Reactive bridge to RabbitMQ&lt;br&gt; * &lt;a href=&quot;https://github.com/reactor/reactor-pool&quot;&gt;Reactor Pool&lt;/a&gt;: Generic object pool for reactive applications&lt;br&gt; * &lt;a href=&quot;https://github.com/reactor/reactor-core-dotnet&quot;&gt;Reactor Core.NET&lt;/a&gt;: Incubating Reactive Streams foundation for .NET&lt;br&gt; * &lt;a href=&quot;https://github.com/reactor/reactor-core-js&quot;&gt;Reactor CoreJS&lt;/a&gt;: Incubating Reactive Streams foundation for JavaScript&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Qovery</title>
      <link>https://tedneward.github.io/Research/platforms/qovery/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">platforms/qovery/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.qovery.com/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/Qovery/engine&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Racket</title>
      <link>https://tedneward.github.io/Research/platforms/racket/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">platforms/racket/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://racket-lang.org/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://docs.racket-lang.org/index.html&quot;&gt;Docs&lt;/a&gt; | &lt;a href=&quot;https://github.com/racket/racket&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;General-purpose programming language, as well as ecosystem for language-oriented programming. Languages available (through the &lt;code&gt;#lang&lt;/code&gt; directive):&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;racket&lt;/li&gt; 
 &lt;li&gt;scribble/base&lt;/li&gt; 
 &lt;li&gt;typed/racket&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;datalog.html&quot;&gt;datalog&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;racket/gui&lt;/li&gt; 
 &lt;li&gt;web-server/insta&lt;/li&gt; 
 &lt;li&gt;plait (plai language with a type system close to that of ML)&lt;/li&gt; 
 &lt;li&gt;profj (ProfessorJ: Java in Racket)&lt;/li&gt; 
 &lt;li&gt;racklog (Prolog-style logic programming)&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;Really broad ecosystem; deserves much more attention than it gets.&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://docs.racket-lang.org/quick/index.html&quot;&gt;&quot;An introduction to Racket, with pictures&quot;&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Example: HelloWorld&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-lisp&quot;&gt;#lang racket/gui

(define my-language &apos;English)

(define translations
  #hash([English . &quot;Hello world&quot;]
        [French . &quot;Bonjour le monde&quot;]
        [German . &quot;Hallo Welt&quot;]
        [Greek . &quot;Γειά σου, κόσμε&quot;]
        [Portuguese . &quot;Olá mundo&quot;]
        [Spanish . &quot;Hola mundo&quot;]
        [Thai . &quot;สวัสดีชาวโลก&quot;]))

(define my-hello-world
  (hash-ref translations my-language
            &quot;hello world&quot;))

(message-box &quot;&quot; my-hello-world)
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Example: Language-Oriented Programming&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;#lang typed/racket

;; Using higher-order occurrence typing
(define-type SrN (U String Number))
(: tog ((Listof SrN) -&amp;gt; String))
(define (tog l)
  (apply string-append
         (filter string? l)))
(tog (list 5 &quot;hello &quot;
           1/2 &quot;world&quot; (sqrt -1)))
&lt;/code&gt;&lt;/pre&gt; 
&lt;pre&gt;&lt;code&gt;#lang scribble/base

@; Generate a PDF or HTML document
@(require (only-in racket ~a))
@(define N 99)
@title{Bottles: @italic{Abridged}}
@(apply
  itemlist
  (for/list ([n (in-range N 0 -1)])
    @item{@(~a n) bottles.}))
&lt;/code&gt;&lt;/pre&gt; 
&lt;pre&gt;&lt;code&gt;#lang datalog

ancestor(A, B) :- parent(A, B).
ancestor(A, B) :-
  parent(A, C), ancestor(C, B).
parent(john, douglas).
parent(bob, john).
ancestor(A, B)?
&lt;/code&gt;&lt;/pre&gt;
	</description>
    </item>
    <item>
      <title>Relate</title>
      <link>https://tedneward.github.io/Research/platforms/relate/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">platforms/relate/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://relate.app/&quot;&gt;Website&lt;/a&gt; | Commercial with free tier&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Rintagi</title>
      <link>https://tedneward.github.io/Research/platforms/rintagi/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">platforms/rintagi/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.rintagi.com/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/Rintagi/Low-Code-Development-Platform&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>SeaTable</title>
      <link>https://tedneward.github.io/Research/platforms/seatable/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">platforms/seatable/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://seatable.io/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/seatable/seatable&quot;&gt;Source&lt;/a&gt; | &lt;a href=&quot;https://manual.seatable.io/&quot;&gt;Docs&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://manual.seatable.io/docker/Developer-Edition/Deploy%20SeaTable-DE%20with%20Docker/&quot;&gt;Developer (free) Edition deployed with Docker&lt;/a&gt;&lt;/p&gt; 
&lt;h4&gt;Software components&lt;/h4&gt; 
&lt;p&gt;SeaTable consists of following component&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;dtable-web: The web site for manage tables.&lt;/li&gt; 
 &lt;li&gt;dtable-server: Store the tables and provide collaborating feature.&lt;/li&gt; 
 &lt;li&gt;dtable-events: Background tasks likes email sending and so on.&lt;/li&gt; 
 &lt;li&gt;seaf-server: Store attachments (files and images)&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Simpl</title>
      <link>https://tedneward.github.io/Research/platforms/simpl/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">platforms/simpl/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://tpso.com/repo/webdemo/start.html#0&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/tpso-src/simpl4-src&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>StackStorm</title>
      <link>https://tedneward.github.io/Research/platforms/stackstorm/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">platforms/stackstorm/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://stackstorm.com/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/StackStorm/st2&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Event-driven automation for auto-remediation, security responses, troubleshooting, deployments, and more. Includes rules engine, workflow, 160 integration packs with 6000+ actions (see &lt;a href=&quot;https://exchange.stackstorm.org&quot;&gt;https://exchange.stackstorm.org&lt;/a&gt;) and ChatOps.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Supercollider</title>
      <link>https://tedneward.github.io/Research/platforms/supercollider/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">platforms/supercollider/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;http://supercollider.github.io/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/supercollider/supercollider&quot;&gt;Source&lt;/a&gt; | &lt;a href=&quot;https://mitpress.mit.edu/9780262232692/the-supercollider-book/&quot;&gt;The Supercollider Book&lt;/a&gt; (MIT Press)&lt;/p&gt; 
&lt;p&gt;Programming language, IDE, and platform for building audio/sounds.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>TikiTrackers</title>
      <link>https://tedneward.github.io/Research/platforms/tikitrackers/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">platforms/tikitrackers/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://tiki.org/HomePage&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://gitlab.com/tikiwiki/tiki/&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://doc.tiki.org/Features&quot;&gt;Feature list&lt;/a&gt;:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Wiki pages&lt;/li&gt; 
 &lt;li&gt;Trackers (web forms and reports)&lt;/li&gt; 
 &lt;li&gt;Blogs&lt;/li&gt; 
 &lt;li&gt;Forums&lt;/li&gt; 
 &lt;li&gt;RSS Syndication&lt;/li&gt; 
 &lt;li&gt;WYSIWYG Editing&lt;/li&gt; 
 &lt;li&gt;Calendars and Events&lt;/li&gt; 
 &lt;li&gt;File and Image Galleries&lt;/li&gt; 
 &lt;li&gt;User and Group Management&lt;/li&gt; 
 &lt;li&gt;Surveys, Quizzes, and Polls&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>TotalJS</title>
      <link>https://tedneward.github.io/Research/platforms/totaljs/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">platforms/totaljs/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.totaljs.com/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/totaljs/&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Competitor to &lt;a href=&quot;/languages/nodered/&quot;&gt;Node-RED&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Universe</title>
      <link>https://tedneward.github.io/Research/platforms/universe/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">platforms/universe/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.onuniverse.com/&quot;&gt;Website&lt;/a&gt; Looks to be iOS/macOS-specific.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>macOS Open Source</title>
      <link>https://tedneward.github.io/Research/platforms/macos/oss/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">platforms/macos/oss/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://opensource.apple.com/releases/&quot;&gt;Apple Open Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Mastodon</title>
      <link>https://tedneward.github.io/Research/platforms/mastodon/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">platforms/mastodon/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://joinmastodon.org/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/tootsuite/mastodon&quot;&gt;Source&lt;/a&gt; or &lt;a href=&quot;https://github.com/mastodon/mastodon&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;A Vagrant configuration is included for development purposes. To use it, complete following steps:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Install Vagrant and Virtualbox&lt;/li&gt; 
 &lt;li&gt;Run &lt;code&gt;vagrant up&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;Run &lt;code&gt;vagrant ssh -c &quot;cd /vagrant &amp;amp;&amp;amp; foreman start&quot;&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;Open &lt;a href=&quot;http://mastodon.local&quot;&gt;http://mastodon.local&lt;/a&gt; in your browser&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>MingW32</title>
      <link>https://tedneward.github.io/Research/platforms/mingw32/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">platforms/mingw32/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;http://www.mingw.org/&quot;&gt;Website&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>&quot;/e/&quot; OS</title>
      <link>https://tedneward.github.io/Research/platforms/mobile/e/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">platforms/mobile/e/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://e.foundation&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://gitlab.e.foundation/e&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Article: &lt;a href=&quot;https://thenewleafjournal.com/review-of-e-an-android-alternative-for-mobile-phones/&quot;&gt;Review of /e/ -- An Android Alternative for Mobile Phones&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Ubuntu Touch</title>
      <link>https://tedneward.github.io/Research/platforms/mobile/ubuntutouch/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">platforms/mobile/ubuntutouch/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://ubuntu-touch.io/&quot;&gt;Website&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>NWJS (previously known as node-webkit)</title>
      <link>https://tedneward.github.io/Research/platforms/newjs/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">platforms/newjs/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://nwjs.io/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/nwjs/nw.js&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;h2&gt;Getting Started&lt;/h2&gt; 
&lt;p&gt;NW.js is based on &lt;a href=&quot;http://www.chromium.org&quot;&gt;Chromium&lt;/a&gt; and &lt;a href=&quot;http://nodejs.org/&quot;&gt;Node.js&lt;/a&gt;. It lets you call Node.js code and modules directly from browser and also use Web technologies in your app. Further, you can easily package a web application to a native application.&lt;/p&gt; 
&lt;h3&gt;Get NW.js&lt;/h3&gt; 
&lt;p&gt;You can get the latest binaries from official website &lt;a href=&quot;http://nwjs.io&quot;&gt;http://nwjs.io&lt;/a&gt;.&lt;/p&gt; 
&lt;h3&gt;Write NW.js App&lt;/h3&gt; 
&lt;h4&gt;Example 1 - Hello World&lt;/h4&gt; 
&lt;p&gt;This the basic example shows how to write an NW.js app.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Step 1.&lt;/strong&gt; Create &lt;code&gt;package.json&lt;/code&gt;:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-json&quot;&gt;{
  &quot;name&quot;: &quot;helloworld&quot;,
  &quot;main&quot;: &quot;index.html&quot;
}
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;&lt;code&gt;package.json&lt;/code&gt; is the manifest file in your app. It is written in &lt;a href=&quot;http://www.json.org/&quot;&gt;JSON format&lt;/a&gt;. The &lt;code&gt;main&lt;/code&gt; field figures out the first page opened by the NW.js, i.e. &lt;code&gt;&quot;index.html&quot;&lt;/code&gt; in this example. And the &lt;code&gt;name&lt;/code&gt; field is the unique name used among NW.js apps. See [Manifest Format](../References/Manifest Format.md) for more details.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Step 2.&lt;/strong&gt; Create &lt;code&gt;index.html&lt;/code&gt;:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-html&quot;&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html&amp;gt;
  &amp;lt;head&amp;gt;
    &amp;lt;title&amp;gt;Hello World!&amp;lt;/title&amp;gt;
  &amp;lt;/head&amp;gt;
  &amp;lt;body&amp;gt;
    &amp;lt;h1&amp;gt;Hello World!&amp;lt;/h1&amp;gt;
  &amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;This is the normal HTML file. You can use any web technologies supported by latest browsers.&lt;/p&gt; 
&lt;p&gt;!!! note &quot;Chromium Specific Features&quot;&lt;br&gt; NW.js is based on Chromium, which also enables you to use Chrome specific features. Such as &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/File_System_API&quot;&gt;File System API&lt;/a&gt;, experimental CSS styles with &lt;code&gt;-webkit-&lt;/code&gt; prefix. &lt;strong&gt;Be careful with these non-standard features since they may be deprecated shortly.&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Step 3.&lt;/strong&gt; Run your app&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;cd /path/to/your/app
/path/to/nw .
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;&lt;code&gt;/path/to/nw&lt;/code&gt; is the binary file of NW.js. On Windows, it&apos;s &lt;code&gt;nw.exe&lt;/code&gt;; On Linux, it&apos;s &lt;code&gt;nw&lt;/code&gt;; On Mac, it&apos;s &lt;code&gt;nwjs.app/Contents/MacOS/nwjs&lt;/code&gt;.&lt;/p&gt; 
&lt;p&gt;!!! tip &quot;Drag &amp;amp; Drop on Windows&quot;&lt;br&gt; On Windows, you can drag the &lt;code&gt;folder containing package.json&lt;/code&gt; to &lt;code&gt;nw.exe&lt;/code&gt; to run your app.&lt;/p&gt; 
&lt;h4&gt;Example 2 - Using NW.js APIs&lt;/h4&gt; 
&lt;p&gt;All NW.js APIs are loaded in &lt;code&gt;nw&lt;/code&gt; object globally and can be used directly in JavaScript files.&lt;/p&gt; 
&lt;p&gt;This example shows how to create a native context menu in your NW.js app. You can create &lt;code&gt;index.html&lt;/code&gt; with following content:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-html&quot;&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html&amp;gt;
&amp;lt;head&amp;gt;
  &amp;lt;title&amp;gt;Context Menu&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body style=&quot;width: 100%; height: 100%;&quot;&amp;gt;

&amp;lt;p&amp;gt;&apos;Right click&apos; to show context menu.&amp;lt;/p&amp;gt;

&amp;lt;script&amp;gt;
// Create an empty context menu
var menu = new nw.Menu();

// Add some items with label
menu.append(new nw.MenuItem({
  label: &apos;Item A&apos;,
  click: function(){
    alert(&apos;You have clicked at &quot;Item A&quot;&apos;);
  }
}));
menu.append(new nw.MenuItem({ label: &apos;Item B&apos; }));
menu.append(new nw.MenuItem({ type: &apos;separator&apos; }));
menu.append(new nw.MenuItem({ label: &apos;Item C&apos; }));

// Hooks the &quot;contextmenu&quot; event
document.body.addEventListener(&apos;contextmenu&apos;, function(ev) {
  // Prevent showing default context menu
  ev.preventDefault();
  // Popup the native context menu at place you click
  menu.popup(ev.x, ev.y);

  return false;
}, false);

&amp;lt;/script&amp;gt;  
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;... then run your app:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;cd /path/to/your/app
/path/to/nw .
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;!!! tip &quot;require(&apos;nw.gui&apos;)&quot;&lt;br&gt; The legacy way of loading NW.js APIs using &lt;code&gt;require(&apos;nw.gui&apos;)&lt;/code&gt; is also supported. It returns the same &lt;code&gt;nw&lt;/code&gt; object.&lt;/p&gt; 
&lt;h4&gt;Example 3 - Using Node.js API&lt;/h4&gt; 
&lt;p&gt;You can call node.js and modules directly from the DOM. So it enables endless possibilities for writing apps with nw.js.&lt;/p&gt; 
&lt;p&gt;This example shows how to query the OS platform with &lt;code&gt;os&lt;/code&gt; module of Node.js. Simply create the &lt;code&gt;index.html&lt;/code&gt; file with following content and run it with NW.js.&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-html&quot;&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html&amp;gt;
&amp;lt;head&amp;gt;
  &amp;lt;title&amp;gt;My OS Platform&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
&amp;lt;script&amp;gt;
// get the system platform using node.js
var os = require(&apos;os&apos;);
document.write(&apos;You are running on &apos;, os.platform());
&amp;lt;/script&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;You could also use the modules installed by &lt;a href=&quot;https://www.npmjs.com/&quot;&gt;&lt;code&gt;npm&lt;/code&gt;&lt;/a&gt; with NW.js.&lt;/p&gt; 
&lt;p&gt;!!! note &quot;Native Node Modules&quot;&lt;br&gt; Native Node modules, built when running &lt;code&gt;npm install&lt;/code&gt;, are not compatible with NW.js ABI. To use them, you have to rebuild it from source code with &lt;a href=&quot;https://github.com/nwjs/nw-gyp&quot;&gt;&lt;code&gt;nw-gyp&lt;/code&gt;&lt;/a&gt;. See [Use Native Node Modules](Advanced/Use Native Node Modules.md) for details.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Objective-C (Platform)</title>
      <link>https://tedneward.github.io/Research/platforms/objc/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">platforms/objc/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Introduction/Introduction.html&quot;&gt;Objective-C Runtime Guide&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>OpenResty</title>
      <link>https://tedneward.github.io/Research/platforms/openresty/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">platforms/openresty/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://openresty.com/en/&quot;&gt;Website&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Products:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;OpenResty Plus: &quot;A premium Web application server that covers all your needs. An enterprise-ready Web server solution with rich built-in support features and better than ever programmability and compatibility.&quot;&lt;/li&gt; 
 &lt;li&gt;OpenResty Edge: &quot;Gateway management platform built to maximize your productivity. A gateway software best to manage distributed web traffic in the multi-cloud and service mesh era.&quot;&lt;/li&gt; 
 &lt;li&gt;OpenResty Xray: &quot;An all-in-one troubleshooting and profiling tool built for OSS. A real-time, lightweight, non-invasive monitoring tool that helps you optimize resources and quickly troubleshoot and resolve complex issues.&quot;&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Operating System Implementation</title>
      <link>https://tedneward.github.io/Research/platforms/os-implementation/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">platforms/os-implementation/index.html</guid>
      	<description>
	&lt;h2&gt;Reading&lt;/h2&gt; 
&lt;h3&gt;Articles/Blogs/Essays&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://popovicu.com/posts/writing-an-operating-system-kernel-from-scratch/&quot;&gt;Writing an Operating System Kernel from Scratch&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.howtogeek.com/what-is-an-agentic-os-and-why-microsoft-thinks-windows-will-soon-do-your-work-for-you/&quot;&gt;How agentic OS will change the way you use Windows&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Implementations&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://github.com/jgarzik/hk&quot;&gt;hk&lt;/a&gt;: an operating system kernel written in Rust&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Plasmic</title>
      <link>https://tedneward.github.io/Research/platforms/plasmic/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">platforms/plasmic/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.plasmic.app/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/plasmicapp/plasmic&quot;&gt;Source&lt;/a&gt; | &lt;a href=&quot;https://docs.plasmic.app/learn/&quot;&gt;Docs&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Looks like it basically generates a &lt;a href=&quot;../presentation/react&quot;&gt;React&lt;/a&gt; component that can then be referenced from React pages.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Microsoft PowerApps</title>
      <link>https://tedneward.github.io/Research/platforms/powerapps/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">platforms/powerapps/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://powerapps.microsoft.com/en-us/&quot;&gt;Website&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>PumpkinOS</title>
      <link>https://tedneward.github.io/Research/platforms/pumpkinos/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">platforms/pumpkinos/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/migueletto/PumpkinOS&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Quarkly</title>
      <link>https://tedneward.github.io/Research/platforms/quarkly/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">platforms/quarkly/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://quarkly.io/&quot;&gt;Website&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;../presentation/react&quot;&gt;React&lt;/a&gt;-based (using React components).&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>ravynOS</title>
      <link>https://tedneward.github.io/Research/platforms/ravynos/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">platforms/ravynos/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://ravynos.com/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/ravynsoft/ravynos&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Remult</title>
      <link>https://tedneward.github.io/Research/platforms/remult/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">platforms/remult/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://remult.dev/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/remult/remult&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Remult is a full-stack CRUD framework that uses your TypeScript model types to provide Secure REST API (highly configurable); Type-safe frontend API client; Type-safe backend query builder.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Rowy</title>
      <link>https://tedneward.github.io/Research/platforms/rowy/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">platforms/rowy/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.rowy.io/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/rowyio/rowy&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Selfie</title>
      <link>https://tedneward.github.io/Research/platforms/selfie/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">platforms/selfie/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;http://selfie.cs.uni-salzburg.at/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/cksystemsteaching/selfie&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;The Selfie Project provides an educational platform for teaching undergraduate and graduate students the design and implementation of programming languages and runtime systems. The focus is on the construction of compilers, libraries, operating systems, and even virtual machine monitors. The common theme is to identify and resolve self-reference in systems code which is seen as the key challenge when teaching systems engineering, hence the name.&lt;/p&gt; 
&lt;h2&gt;Installing Selfie&lt;/h2&gt; 
&lt;p&gt;Selfie runs in the cloud and natively on Linux, macOS, and Windows machines and possibly other systems that have a terminal and a C compiler installed. However, even if there is no C compiler installed on your machine or you only have access to a web browser you can still run selfie.&lt;/p&gt; 
&lt;p&gt;There are at least three ways to install and run selfie, from real simple to a bit more difficult:&lt;/p&gt; 
&lt;ol&gt; 
 &lt;li&gt; &lt;p&gt;In the cloud: if you only have access to a web browser, just click &lt;a href=&quot;https://replit.com/new/github/cksystemsteaching/selfie&quot;&gt;here&lt;/a&gt;. Alternatively, create a &lt;a href=&quot;https://github.com&quot;&gt;github&lt;/a&gt; account, unless you already have one, and fork &lt;a href=&quot;https://github.com/cksystemsteaching/selfie&quot;&gt;selfie&lt;/a&gt; into your github account. Then, create a &lt;a href=&quot;https://c9.io&quot;&gt;cloud9&lt;/a&gt; student account, connect it to your github account, verify your email address and set a password (important!), and finally clone your fork of selfie into a new cloud9 workspace.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;In docker on your machine: if you have access to a Linux, macOS, or Windows machine download and install &lt;a href=&quot;https://docker.com&quot;&gt;docker&lt;/a&gt;. Then, open a terminal window and type &lt;code&gt;docker run -it cksystemsteaching/selfie&lt;/code&gt;. Besides simplicity, the key advantage of using docker is that you can run selfie out of the box on your machine but also on QEMU as well as on spike. Both emulators and the SMT solver boolector are pre-installed in the &lt;a href=&quot;https://hub.docker.com/r/cksystemsteaching/selfie&quot;&gt;selfie docker image&lt;/a&gt;.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Natively on your machine: instead of using docker, you may also just download and unzip &lt;a href=&quot;https://github.com/cksystemsteaching/selfie/archive/main.zip&quot;&gt;selfie&lt;/a&gt;, and then open a terminal window to run selfie natively on your machine. However, for this to work you need to have a C compiler installed on your machine. We recommend using &lt;a href=&quot;https://clang.llvm.org&quot;&gt;clang&lt;/a&gt; or &lt;a href=&quot;https://gcc.gnu.org&quot;&gt;gcc&lt;/a&gt; (with &lt;a href=&quot;https://www.cygwin.com&quot;&gt;cygwin&lt;/a&gt; on Windows).&lt;/p&gt; &lt;/li&gt; 
&lt;/ol&gt; 
&lt;p&gt;At this point we assume that you have a system that supports running selfie. Below we use the &lt;code&gt;make&lt;/code&gt; command assuming it is installed on your system which is usually the case. However, we also show the command invoked by &lt;code&gt;make&lt;/code&gt; so that you can always invoke that command manually if your system does not have &lt;code&gt;make&lt;/code&gt; installed.&lt;/p&gt; 
&lt;p&gt;The next step is to produce a selfie binary. To do that &lt;code&gt;cd&lt;/code&gt; to the selfie folder in your terminal and then type &lt;code&gt;make&lt;/code&gt;. With docker, the system will respond &lt;code&gt;make: &apos;selfie&apos; is up to date&lt;/code&gt; since there is already a selfie binary pre-installed. Without docker, &lt;code&gt;make&lt;/code&gt; will invoke the C compiler on your machine or in the cloud9 workspace:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;cc -Wall -Wextra -O3 -D&apos;uint64_t=unsigned long&apos; selfie.c -o selfie
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;and then compile &lt;code&gt;selfie.c&lt;/code&gt; into an executable called &lt;code&gt;selfie&lt;/code&gt; as directed by the &lt;code&gt;-o&lt;/code&gt; option. The executable contains the C* compiler, the mipster emulator, and the hypster hypervisor. The &lt;code&gt;-Wall&lt;/code&gt; and &lt;code&gt;-Wextra&lt;/code&gt; options enable all compiler warnings which is useful during further development of selfie. The &lt;code&gt;-O3&lt;/code&gt; option instructs the compiler to generate optimized code. The &lt;code&gt;-D&apos;uint64_t=unsigned long&apos;&lt;/code&gt; option is needed to bootstrap the code. It defines the data type &lt;code&gt;uint64_t&lt;/code&gt; which would otherwise be undefined since C* does not include the necessary definitions. If your system supports compiling and executing 32-bit binaries you may also try &lt;code&gt;make selfie-32&lt;/code&gt; which will produce a 32-bit system that in turn generates and executes 32-bit binaries.&lt;/p&gt; 
&lt;h2&gt;Running Selfie&lt;/h2&gt; 
&lt;p&gt;Once you have successfully compiled &lt;code&gt;selfie.c&lt;/code&gt; you may invoke &lt;code&gt;selfie&lt;/code&gt; without any arguments as follows:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;$ ./selfie
./selfie { -c { source } | -o binary | [ -s | -S ] assembly | -l binary } [ ( -m | -d | -r | -y ) 0-4096 ... ]
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;In this case, &lt;code&gt;selfie&lt;/code&gt; responds with its usage pattern.&lt;/p&gt; 
&lt;p&gt;The order in which the options are provided matters for taking full advantage of self-referentiality.&lt;/p&gt; 
&lt;p&gt;The &lt;code&gt;-c&lt;/code&gt; option invokes the C* compiler on the given list of &lt;code&gt;source&lt;/code&gt; files compiling and linking them into RISC-U code that is stored internally. For example, &lt;code&gt;selfie&lt;/code&gt; may be used to compile its own source code &lt;code&gt;selfie.c&lt;/code&gt; as follows:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;$ ./selfie -c selfie.c
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;The &lt;code&gt;-o&lt;/code&gt; option writes RISC-U code produced by the most recent compiler invocation to the given &lt;code&gt;binary&lt;/code&gt; file. For example, &lt;code&gt;selfie&lt;/code&gt; may be instructed to compile itself and then output the generated RISC-U code into a RISC-U binary file called &lt;code&gt;selfie.m&lt;/code&gt;:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;$ ./selfie -c selfie.c -o selfie.m
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;The &lt;code&gt;-s&lt;/code&gt; option writes RISC-U assembly of the RISC-U code produced by the most recent compiler invocation to the given &lt;code&gt;assembly&lt;/code&gt; file while the &lt;code&gt;-S&lt;/code&gt; option additionally includes approximate line numbers and the binary representation of the instructions. Similarly as before, &lt;code&gt;selfie&lt;/code&gt; may be instructed to compile itself and then output the generated RISC-U code into a RISC-U assembly file called &lt;code&gt;selfie.s&lt;/code&gt;:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;$ ./selfie -c selfie.c -s selfie.s
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;The &lt;code&gt;-l&lt;/code&gt; option loads RISC-U code from the given &lt;code&gt;binary&lt;/code&gt; file. The &lt;code&gt;-o&lt;/code&gt; and &lt;code&gt;-s&lt;/code&gt; options can also be used after the &lt;code&gt;-l&lt;/code&gt; option. However, in this case the &lt;code&gt;-s&lt;/code&gt; option does not generate approximate source line numbers. For example, the previously generated RISC-U binary file &lt;code&gt;selfie.m&lt;/code&gt; may be loaded as follows:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;$ ./selfie -l selfie.m
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;The &lt;code&gt;-m&lt;/code&gt; option invokes the mipster emulator to execute RISC-U code most recently loaded or produced by a compiler invocation. The emulator creates a machine instance with &lt;code&gt;0-4096&lt;/code&gt; MB of memory. The &lt;code&gt;source&lt;/code&gt; or &lt;code&gt;binary&lt;/code&gt; name of the RISC-U code and any remaining &lt;code&gt;...&lt;/code&gt; arguments are passed to the main function of the code. For example, the following invocation executes &lt;code&gt;selfie.m&lt;/code&gt; using mipster:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;$ ./selfie -l selfie.m -m 1
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;This is in fact semantically equivalent to executing &lt;code&gt;selfie&lt;/code&gt; without any arguments:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;$ ./selfie
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;The &lt;code&gt;-d&lt;/code&gt; option is similar to the &lt;code&gt;-m&lt;/code&gt; option except that mipster outputs each executed instruction, its approximate source line number, if available, and the relevant machine state. Alternatively, the &lt;code&gt;-r&lt;/code&gt; option limits the amount of output created with the &lt;code&gt;-d&lt;/code&gt; option by having mipster merely replay code execution when runtime errors such as division by zero occur. In this case, mipster outputs only the instructions that were executed right before the error occurred.&lt;/p&gt; 
&lt;p&gt;If you are using docker you can also execute &lt;code&gt;selfie.m&lt;/code&gt; directly on spike and pk as follows:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;$ spike pk selfie.m
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;which is again semantically equivalent to executing &lt;code&gt;selfie&lt;/code&gt; without any arguments.&lt;/p&gt; 
&lt;p&gt;The &lt;code&gt;-y&lt;/code&gt; option invokes the hypster hypervisor to execute RISC-U code similar to the mipster emulator. The difference to mipster is that hypster creates RISC-U virtual machines rather than a RISC-U emulator to execute the code. See below for an example.&lt;/p&gt; 
&lt;h3&gt;Self-compilation&lt;/h3&gt; 
&lt;p&gt;Here is an example of how to perform self-compilation of &lt;code&gt;selfie.c&lt;/code&gt; and then check if the RISC-U code &lt;code&gt;selfie1.m&lt;/code&gt; generated for &lt;code&gt;selfie.c&lt;/code&gt; by executing the &lt;code&gt;./selfie&lt;/code&gt; binary is equivalent to the code &lt;code&gt;selfie2.m&lt;/code&gt; generated by executing the just generated &lt;code&gt;selfie1.m&lt;/code&gt; binary:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;$ ./selfie -c selfie.c -o selfie1.m -m 2 -c selfie.c -o selfie2.m
$ diff -s selfie1.m selfie2.m
Files selfie1.m and selfie2.m are identical
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Note that at least 2MB of memory is required for this to work.&lt;/p&gt; 
&lt;h3&gt;Self-execution&lt;/h3&gt; 
&lt;p&gt;The following example shows how to perform self-execution of the mipster emulator. In this case we invoke mipster to invoke itself to execute &lt;code&gt;selfie&lt;/code&gt;:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;$ ./selfie -c selfie.c -o selfie.m -m 2 -l selfie.m -m 1
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;which is again semantically equivalent to executing &lt;code&gt;selfie&lt;/code&gt; without any arguments but this time with &lt;code&gt;selfie&lt;/code&gt; printing its usage pattern much slower since there is a mipster running on top of another mipster.&lt;/p&gt; 
&lt;h3&gt;Self-hosting&lt;/h3&gt; 
&lt;p&gt;The previous example can also be done by running hypster on mipster. This is significantly faster and requires less memory since hypster does not create a second emulator instance on top of the first emulator instance. Instead, hypster creates a virtual machine to execute selfie that runs concurrently to hypster on the first emulator instance:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;$ ./selfie -c selfie.c -o selfie.m -m 1 -l selfie.m -y 1
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;We may even run hypster on hypster on mipster which is still reasonably fast since there is still only one emulator instance involved and hypster itself does not add much overhead:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;$ ./selfie -c selfie.c -o selfie.m -m 2 -l selfie.m -y 1 -l selfie.m -y 1
&lt;/code&gt;&lt;/pre&gt; 
&lt;h3&gt;Workflow&lt;/h3&gt; 
&lt;p&gt;To compile any C* source code and execute it right away in a single invocation of &lt;code&gt;selfie&lt;/code&gt; without generating a RISC-U binary use:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;$ ./selfie -c any-cstar-file.c -m 1 &quot;arguments for any-cstar-file.c&quot;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Equivalently, you may also use a selfie-compiled version of &lt;code&gt;selfie&lt;/code&gt; and have the mipster emulator execute selfie to compile any C* source code and then execute it right away with hypster on the same emulator instance:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;$ ./selfie -c selfie.c -m 1 -c any-cstar-file.c -y 1 &quot;arguments for any-cstar-file.c&quot;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;You may also generate RISC-U binaries both ways which will then be identical:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;$ ./selfie -c any-cstar-file.c -o any-cstar-file1.m
$ ./selfie -c selfie.c -m 1 -c any-cstar-file.c -o any-cstar-file2.m
$ diff -s any-cstar-file1.m any-cstar-file2.m
Files any-cstar-file1.m and any-cstar-file2.m are identical
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;This can also be done in a single invocation of &lt;code&gt;selfie&lt;/code&gt;:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;$ ./selfie -c any-cstar-file.c -o any-cstar-file1.m -c selfie.c -m 1 -c any-cstar-file.c -o any-cstar-file2.m
$ diff -s any-cstar-file1.m any-cstar-file2.m
Files any-cstar-file1.m and any-cstar-file2.m are identical
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;The generated RISC-U binaries can then be loaded and executed as follows:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;$ ./selfie -l any-cstar-file1.m -m 1 &quot;arguments for any-cstar-file1.m&quot;
&lt;/code&gt;&lt;/pre&gt; 
&lt;h4&gt;Linking&lt;/h4&gt; 
&lt;p&gt;To compile and link any C* source code from multiple source files use:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;$ ./selfie -c any-cstar-file1.c any-cstar-file2.c ... -m 1
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;For example, to make the source code of &lt;code&gt;selfie.c&lt;/code&gt; available as library code in any C* source code use:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;$ ./selfie -c any-cstar-file.c selfie.c -m 1
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Note that multiple definitions of symbols are ignored by the compiler with a warning.&lt;/p&gt; 
&lt;h4&gt;Debugging&lt;/h4&gt; 
&lt;p&gt;Selfie&apos;s console messages always begin with the name of the source or binary file currently running. The mipster emulator also shows the amount of memory allocated for its machine instance and how execution terminated (exit code).&lt;/p&gt; 
&lt;p&gt;As discussed before, RISC-U assembly for &lt;code&gt;selfie&lt;/code&gt; and any other C* file is generated as follows:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;$ ./selfie -c selfie.c -s selfie.s
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;If the assembly code is generated from a binary generated by the compiler (and not loaded from a file) approximate source line numbers are included in the assembly file.&lt;/p&gt; 
&lt;p&gt;Verbose debugging information is printed with the &lt;code&gt;-d&lt;/code&gt; option, for example:&lt;/p&gt; 
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;$ ./selfie -c selfie.c -d 1
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;Similarly, if the executed binary is generated by the compiler (and not loaded from a file) approximate source line numbers are included in the debug information.&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Singularity</title>
      <link>https://tedneward.github.io/Research/platforms/singularity/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">platforms/singularity/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://github.com/lastweek/source-singularity&quot;&gt;Source&lt;/a&gt; | &lt;a href=&quot;https://www.microsoft.com/en-us/research/wp-content/uploads/2005/10/tr-2005-135.pdf&quot;&gt;Overview&lt;/a&gt; (PDF) | &lt;a href=&quot;https://www.microsoft.com/en-us/research/project/singularity/&quot;&gt;Official site&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;Discontinued since 2008, it seems like?&lt;/p&gt; 
&lt;h2&gt;Reading&lt;/h2&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://codingkaiser.blog/2021/07/23/operating-systems-are-more-exciting-than-you-think/&quot;&gt;&quot;Operating Systems are More Exciting Than You Think&quot;&lt;/a&gt; -- good overview of Singularity and how it provides isolation/security&lt;/li&gt; 
 &lt;li&gt;&lt;a href=&quot;https://www.microsoft.com/en-us/research/wp-content/uploads/2016/02/osr2007_rethinkingsoftwarestack.pdf&quot;&gt;&quot;Rethinking the software stack&quot;&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Stirling-PDF</title>
      <link>https://tedneward.github.io/Research/platforms/stirling-pdf/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">platforms/stirling-pdf/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.stirling.com/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/Stirling-Tools/Stirling-PDF&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>SvarDOS</title>
      <link>https://tedneward.github.io/Research/platforms/svardos/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">platforms/svardos/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;http://svardos.org/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/SvarDOS/edrdos&quot;&gt;GitHub&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Tina</title>
      <link>https://tedneward.github.io/Research/platforms/tina/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">platforms/tina/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://tina.io/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/tinacms/tinacms&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Tsuru</title>
      <link>https://tedneward.github.io/Research/platforms/tsuru/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">platforms/tsuru/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://tsuru.io/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/tsuru/tsuru&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>HackerOS</title>
      <link>https://tedneward.github.io/Research/platforms/linux/distros/hackeros/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">platforms/linux/distros/hackeros/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;&quot;&gt;Website&lt;/a&gt;&lt;/p&gt; 
&lt;h2&gt;Resources&lt;/h2&gt; 
&lt;h3&gt;Articles, Blogs, Essays&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;a href=&quot;https://thenewstack.io/hackeros-is-what-a-linux-enthusiasts-os-should-be/&quot;&gt;HackerOS is what a Linux Enthusiast&apos;s OS Should Be&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>Linux Tools</title>
      <link>https://tedneward.github.io/Research/platforms/linux/tools/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">platforms/linux/tools/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;./PerfObsTools.jpeg&quot;&gt;Performance Observability Tools&lt;/a&gt; (JPEG)&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://www.howtogeek.com/how-to-add-terminal-completion-to-your-command-line-apps/&quot;&gt;&quot;How to Add Terminal Completion to your Command-Line Apps&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>LLVM</title>
      <link>https://tedneward.github.io/Research/platforms/llvm/index/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">platforms/llvm/index/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://llvm.org/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/llvm/llvm-project&quot;&gt;Github&lt;/a&gt;&lt;/p&gt; 
&lt;h3&gt;Implementations&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;.NET: &lt;a href=&quot;https://github.com/dotnet/llvmsharp/&quot;&gt;LLVMSharp&lt;/a&gt;&lt;/li&gt; 
 &lt;li&gt;JVM: &lt;a href=&quot;https://github.com/davidar/lljvm&quot;&gt;LLJVM&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Articles/Books&lt;/h3&gt; 
&lt;p&gt;&lt;a href=&quot;http://www.aosabook.org/en/llvm.html&quot;&gt;LLVM&lt;/a&gt; - Chris Lattner, The Architecture of Open Source Applications&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://llvm.org/docs/GarbageCollection.html&quot;&gt;Garbage Collection with LLVM&lt;/a&gt; | &lt;a href=&quot;https://llvm.org/docs/Statepoints.html&quot;&gt;Garbage Collection Safepoints in LLVM&lt;/a&gt;&lt;/p&gt; 
&lt;h3&gt;Tutorials&lt;/h3&gt; 
&lt;p&gt;&lt;a href=&quot;https://llvm.org/docs/tutorial/MyFirstLanguageFrontend/index.html&quot;&gt;My First Language Frontend with LLVM Tutorial&lt;/a&gt; | &lt;a href=&quot;http://llvm.org/docs/tutorial/&quot;&gt;Kaleidoscope&lt;/a&gt; or &lt;a href=&quot;http://www.stephendiehl.com/llvm/&quot;&gt;in Haskell&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://mukulrathi.com/create-your-own-programming-language/llvm-ir-cpp-api-tutorial/&quot;&gt;A Complete Guide to LLVM for Programming Language Creators&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=OhkwPSvyBu0&quot;&gt;Make your own LLVM compiler&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;http://adriansampson.net/blog/llvm.html&quot;&gt;LLVM for Grad Students&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;https://jonathan2251.github.io/lbd/&quot;&gt;Tutorial: Creating an LLVM Backend for the Cpu0 Architecture&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;http://jonathan2251.github.io/lbt/&quot;&gt;Tutorial: Creating an LLVM Toolchain for the Cpu0 Architecture&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;http://blog.regehr.org/archives/1453&quot;&gt;A Tourist’s Guide to the LLVM Source Code&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;http://eli.thegreenplace.net/2012/11/24/life-of-an-instruction-in-llvm&quot;&gt;Life of an instruction in LLVM&lt;/a&gt; | &lt;a href=&quot;https://github.com/thegameg/llvm-life/&quot;&gt;in Clang/LLVM&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;http://blog.regehr.org/archives/1450&quot;&gt;Testing LLVM&lt;/a&gt;&lt;/p&gt; 
&lt;h3&gt;Related&lt;/h3&gt; 
&lt;p&gt;&lt;a href=&quot;https://github.com/decomp/decomp&quot;&gt;Decompilation pipeline&lt;/a&gt; project: &quot;The aim of this project is to implement a decompilation pipeline composed of independent components interacting through well-defined interfaces.&quot;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>Lowdefy</title>
      <link>https://tedneward.github.io/Research/platforms/lowdefy/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">platforms/lowdefy/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://lowdefy.com/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/lowdefy/lowdefy&quot;&gt;Source&lt;/a&gt; | &lt;a href=&quot;https://docs.lowdefy.com/&quot;&gt;Docs&lt;/a&gt;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>VanillaOS</title>
      <link>https://tedneward.github.io/Research/platforms/linux/distros/vanillaos/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">platforms/linux/distros/vanillaos/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://vanillaos.org/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/vanilla-os&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&quot;At the first start you can choose which package format to use in Vanilla OS (Flatpak, Snap, Appimage ..), you choose and Vanilla OS will take care of the rest, putting you in the situation to start without problems.&lt;/p&gt; 
&lt;p&gt;&quot;Vanilla OS is an immutable operating system, core parts of the system are locked down to prevent unwanted changes and corruption from third-party applications or a faulty update. Some paths are still writable, such as the home and configurations directories, this allows the user to keep their files and ensure the normal functioning of applications.&lt;/p&gt; 
&lt;p&gt;&quot;Core components are only updated via controlled and atomic transactions, which are applied only on success and made available on reboot.&quot;&lt;/p&gt;
	</description>
    </item>
    <item>
      <title>WinBoat</title>
      <link>https://tedneward.github.io/Research/platforms/linux/winboat/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">platforms/linux/winboat/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://www.winboat.app/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://github.com/TibixDev/winboat&quot;&gt;Source&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;The developer released a few new versions since last covering it, some highlights of what&apos;s been added recently:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Custom install path.&lt;/li&gt; 
 &lt;li&gt;The ability to share your /home folder.&lt;/li&gt; 
 &lt;li&gt;It will remember where it was when you close the app.&lt;/li&gt; 
 &lt;li&gt;Multi-monitor support with MultiMon.&lt;/li&gt; 
 &lt;li&gt;An option to auto-start a container.&lt;/li&gt; 
 &lt;li&gt;A warning on disk space if you&apos;re getting full.&lt;/li&gt; 
 &lt;li&gt;Some improvements to the general flow and user help for the app itself.&lt;/li&gt; 
 &lt;li&gt;Added noVNC as a preset app if you want to access WinBoat from the browser.&lt;/li&gt; 
 &lt;li&gt;Experimental Dynamic USB pass-through.&lt;/li&gt; 
&lt;/ul&gt;
	</description>
    </item>
    <item>
      <title>MLIR</title>
      <link>https://tedneward.github.io/Research/platforms/llvm/mlir/index.html</link>
      <pubDate>Mon, 13 Apr 2026 14:04:55 +0000</pubDate>
      <guid isPermaLink="false">platforms/llvm/mlir/index.html</guid>
      	<description>
	&lt;p&gt;&lt;a href=&quot;https://mlir.llvm.org/&quot;&gt;Website&lt;/a&gt; | &lt;a href=&quot;https://mlir.llvm.org/users/&quot;&gt;Users&lt;/a&gt; -- that is to say, projects and languages that use MLIR&lt;/p&gt; 
&lt;p&gt;MLIR is intended to be a hybrid IR which can support multiple different requirements in a unified infrastructure. For example, this includes:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;The ability to represent dataflow graphs (such as in TensorFlow), including dynamic shapes, the user-extensible op ecosystem, TensorFlow variables, etc.&lt;/li&gt; 
 &lt;li&gt;Optimizations and transformations typically done on such graphs (e.g. in Grappler).&lt;/li&gt; 
 &lt;li&gt;Ability to host high-performance-computing-style loop optimizations across kernels (fusion, loop interchange, tiling, etc.), and to transform memory layouts of data.&lt;/li&gt; 
 &lt;li&gt;Code generation “lowering” transformations such as DMA insertion, explicit cache management, memory tiling, and vectorization for 1D and 2D register architectures.&lt;/li&gt; 
 &lt;li&gt;Ability to represent target-specific operations, e.g. accelerator-specific high-level operations.&lt;/li&gt; 
 &lt;li&gt;Quantization and other graph transformations done on a Deep-Learning graph.&lt;/li&gt; 
 &lt;li&gt;Polyhedral primitives.&lt;/li&