8,037 Matching Annotations
  1. Jul 2023
    1. ```html

      <script> let counter = 0; let evens = 0; $: { if (counter > 10) { break $; } if (counter % 2 === 0) { evens++; } } </script>

      <button on:click={() => (counter++)}> Increment </button>

      Counter: {counter}, evens before 10: {evens}

      ```

    1. ```js / * twitter-entities.js * This function converts a tweet with "entity" metadata * from plain text to linkified HTML. * * See the documentation here: http://dev.twitter.com/pages/tweet_entities * Basically, add ?include_entities=true to your timeline call * * Copyright 2010, Wade Simmons * Licensed under the MIT license * http://wades.im/mons * * Requires jQuery /

      function escapeHTML(text) { return $('<div/>').text(text).html() }

      function linkify_entities(tweet) { if (!(tweet.entities)) { return escapeHTML(tweet.text) }

      // This is very naive, should find a better way to parse this
      var index_map = {}
      
      $.each(tweet.entities.urls, function(i,entry) {
          index_map[entry.indices[0]] = [entry.indices[1], function(text) {return "<a href='"+escapeHTML(entry.url)+"'>"+escapeHTML(text)+"</a>"}]
      })
      
      $.each(tweet.entities.hashtags, function(i,entry) {
          index_map[entry.indices[0]] = [entry.indices[1], function(text) {return "<a href='http://twitter.com/search?q="+escape("#"+entry.text)+"'>"+escapeHTML(text)+"</a>"}]
      })
      
      $.each(tweet.entities.user_mentions, function(i,entry) {
          index_map[entry.indices[0]] = [entry.indices[1], function(text) {return "<a title='"+escapeHTML(entry.name)+"' href='http://twitter.com/"+escapeHTML(entry.screen_name)+"'>"+escapeHTML(text)+"</a>"}]
      })
      
      var result = ""
      var last_i = 0
      var i = 0
      
      // iterate through the string looking for matches in the index_map
      for (i=0; i < tweet.text.length; ++i) {
          var ind = index_map[i]
          if (ind) {
              var end = ind[0]
              var func = ind[1]
              if (i > last_i) {
                  result += escapeHTML(tweet.text.substring(last_i, i))
              }
              result += func(tweet.text.substring(i, end))
              i = end - 1
              last_i = end
          }
      }
      
      if (i > last_i) {
          result += escapeHTML(tweet.text.substring(last_i, i))
      }
      
      return result
      

      } ```

    1. ```js if (navigator.mediaDevices) { console.log("getUserMedia supported.");

      const constraints = { audio: true }; let chunks = [];

      navigator.mediaDevices .getUserMedia(constraints) .then((stream) => { const mediaRecorder = new MediaRecorder(stream);

        visualize(stream);
      
        record.onclick = () => {
          mediaRecorder.start();
          console.log(mediaRecorder.state);
          console.log("recorder started");
          record.style.background = "red";
          record.style.color = "black";
        };
      
        stop.onclick = () => {
          mediaRecorder.stop();
          console.log(mediaRecorder.state);
          console.log("recorder stopped");
          record.style.background = "";
          record.style.color = "";
        };
      
        mediaRecorder.onstop = (e) => {
          console.log("data available after MediaRecorder.stop() called.");
      
          const clipName = prompt("Enter a name for your sound clip");
      
          const clipContainer = document.createElement("article");
          const clipLabel = document.createElement("p");
          const audio = document.createElement("audio");
          const deleteButton = document.createElement("button");
      
          clipContainer.classList.add("clip");
          audio.setAttribute("controls", "");
          deleteButton.textContent = "Delete";
          clipLabel.textContent = clipName;
      
          clipContainer.appendChild(audio);
          clipContainer.appendChild(clipLabel);
          clipContainer.appendChild(deleteButton);
          soundClips.appendChild(clipContainer);
      
          audio.controls = true;
          const blob = new Blob(chunks, { type: "audio/ogg; codecs=opus" });
          chunks = [];
          const audioURL = URL.createObjectURL(blob);
          audio.src = audioURL;
          console.log("recorder stopped");
      
          deleteButton.onclick = (e) => {
            const evtTgt = e.target;
            evtTgt.parentNode.parentNode.removeChild(evtTgt.parentNode);
          };
        };
      
        mediaRecorder.ondataavailable = (e) => {
          chunks.push(e.data);
        };
      })
      .catch((err) => {
        console.error(`The following error occurred: ${err}`);
      });
      

      } ```

    1. ```js const canvas = document.querySelector("canvas");

      // Optional frames per second argument. const stream = canvas.captureStream(25); const recordedChunks = [];

      console.log(stream); const options = { mimeType: "video/webm; codecs=vp9" }; const mediaRecorder = new MediaRecorder(stream, options);

      mediaRecorder.ondataavailable = handleDataAvailable; mediaRecorder.start();

      function handleDataAvailable(event) { console.log("data-available"); if (event.data.size > 0) { recordedChunks.push(event.data); console.log(recordedChunks); download(); } else { // … } } function download() { const blob = new Blob(recordedChunks, { type: "video/webm", }); const url = URL.createObjectURL(blob); const a = document.createElement("a"); document.body.appendChild(a); a.style = "display: none"; a.href = url; a.download = "test.webm"; a.click(); window.URL.revokeObjectURL(url); }

      // demo: to download after 9sec setTimeout((event) => { console.log("stopping"); mediaRecorder.stop(); }, 9000); ```

    1. That is because React.StrictMode renders the component twice (as it is intentional), that causes 2 connections get created. Create a ws connection inside useEffect and close on the effect cleanup would help or remove StrictMode from index file.

      It's not a bug, it's a feature - they say.

      React DX is so special...

    1. A labeled statement is any statement that is prefixed with an identifier. You can jump to this label using a break or continue statement nested within the labeled statement
      Using a labeled continue with for loops

      ``js // The first for statement is labeled "loop1" loop1: for (let i = 0; i < 3; i++) { // The second for statement is labeled "loop2" loop2: for (let j = 0; j < 3; j++) { if (i === 1 && j === 1) { continue loop1; } console.log(i = ${i}, j = ${j}`); } }

      // Logs: // i = 0, j = 0 // i = 0, j = 1 // i = 0, j = 2 // i = 1, j = 0 // i = 2, j = 0 // i = 2, j = 1 // i = 2, j = 2 ```

      Using a labeled break with for loops

      ```js let i, j;

      // The first for statement is labeled "loop1" loop1: for (i = 0; i < 3; i++) { // The second for statement is labeled "loop2" loop2: for (j = 0; j < 3; j++) { if (i === 1 && j === 1) { break loop1; } console.log(i = ${i}, j = ${j}); } }

      // Logs: // i = 0, j = 0 // i = 0, j = 1 // i = 0, j = 2 // i = 1, j = 0 ```

      Using a labeled continue statement

      ```js // Numbers from 1 to 100 const items = Array.from({ length: 100 }, (_, i) => i + 1)); const tests = [ { pass: (item) => item % 2 === 0 }, { pass: (item) => item % 3 === 0 }, { pass: (item) => item % 5 === 0 }, ]; let itemsPassed = 0;

      itemIteration: for (const item of items) { for (const test of tests) { if (!test.pass(item)) { continue itemIteration; } }

      itemsPassed++; } js // Numbers from 1 to 100 const items = Array.from({ length: 100 }, (_, i) => i + 1)); const tests = [ { pass: (item) => item % 2 === 0 }, { pass: (item) => item % 3 === 0 }, { pass: (item) => item % 5 === 0 }, ]; let itemsPassed = 0;

      for (const item of items) { let passed = true; for (const test of tests) { if (!test.pass(item)) { passed = false; break; } } if (passed) { itemsPassed++; } } ```

      Using a labeled break statement

      ```js // Numbers from 1 to 100 const items = Array.from({ length: 100 }, (_, i) => i + 1)); const tests = [ { pass: (item) => item % 2 === 0 }, { pass: (item) => item % 3 === 0 }, { pass: (item) => item % 5 === 0 }, ]; let allPass = true;

      itemIteration: for (const item of items) { for (const test of tests) { if (!test.pass(item)) { allPass = false; break itemIteration; } } } ```

      Using a labeled block with break

      ```js foo: { console.log("face"); break foo; console.log("this will not be executed"); } console.log("swap");

      // Logs: // "face" // "swap" ```

    1. Adds "previousslide" and "nextslide" actions to the existing Media Session API.

      This will enable developers of video conferencing websites to handle these actions from browser UI. For example, if the user puts their slides presentation into a picture-in-picture window, the browser could display buttons for navigating through slides. When the user clicks those, the website handles them through the Media Session API.

    1. ```js let slideNumber = 1;

      togglePipButton.addEventListener("click", async () => { try { if (video !== document.pictureInPictureElement) await video.requestPictureInPicture(); else await document.exitPictureInPicture(); } catch (error) { log(> Argh! ${error}); } });

      try { navigator.mediaSession.setActionHandler("previousslide", () => { log('> User clicked "Previous Slide" icon.'); if (slideNumber > 1) slideNumber--; updateSlide(); }); } catch (error) { log('Warning! The "previousslide" media session action is not supported.'); }

      try { navigator.mediaSession.setActionHandler("nextslide", () => { log('> User clicked "Next Slide" icon.'); slideNumber++; updateSlide(); }); } catch (error) { log('Warning! The "nextslide" media session action is not supported.'); }

      / Picture-in-Picture canvas /

      const canvas = document.querySelector("canvas"); canvas.width = 1024; canvas.height = 512; updateSlide();

      const video = document.createElement("video"); video.srcObject = canvas.captureStream(); video.muted = true; video.play();

      / Utils /

      function updateSlide() { const ctx = canvas.getContext("2d"); ctx.fillStyle = "grey"; ctx.fillRect(0, 0, canvas.width, canvas.height); ctx.fillStyle = "white"; ctx.font = "100px Google Sans,arial,sans-serif"; ctx.textAlign = "center"; ctx.textBaseline = "middle"; ctx.fillText(slide ${slideNumber}, canvas.width / 2, canvas.height / 2, canvas.width); } ```

    1. ```python from flask import Flask, request from collections import defaultdict import re import random

      GREEN ="🟩" YELLOW ="🟨" WHITE ="⬜"

      def get_answers(): with open("allowed_answers.txt") as f: answers = set(l for l in f.read().splitlines() if l) return answers

      def get_guesses(): guesses = get_answers() with open("allowed_guesses.txt") as f: for l in f.read().splitlines(): if l: guesses.add(l) return guesses

      app = Flask(name, static_folder="static") app.answers = get_answers() app.guesses = get_guesses() word = random.choice(list(app.answers)) print(f"The word is {word}")

      def with_header(content): return f"""

      <html> <head> <link rel="search" type="application/opensearchdescription+xml" title="searchGame" href="http://searchgame:5000/static/opensearch.xml" /> </head> <body> {content} </body></html>

      """

      @app.route("/") def home(): return with_header("

      Right click on the address bar to install the search engine.

      ")

      @app.route("/search") def search(): return with_header(f"Content: {request.args.get('q')}")

      def to_result(guess, answer): chars = [WHITE] * 5 count = defaultdict(int) for idx, (g, a) in enumerate(zip(guess, answer)): if g == a: chars[idx] = GREEN else: count[a] += 1

      for idx, g in enumerate(guess):
          if g in count and count[g] > 0 and chars[idx] == WHITE:
              chars[idx] = YELLOW
              count[g] -= 1
      
      return "".join(chars)
      

      def maybe_error(guess): if len(guess) < 5: return f"less than 5 characters" if len(guess) > 5: return f"greater than 5 characters" if guess not in app.guesses: return f"not in wordlist" return None

      @app.route("/game") def game(): query = request.args.get("q") guesses = [x for x in re.split("[. ]", query) if x] response = [] if not guesses: response.append("Enter 5-letter guesses separated by spaces") else: most_recent = guesses[-1] # Don't show "too short" error for most recent guess if len(most_recent) < 5: guesses = guesses[:-1] if not guesses: response.append("Enter a wordle guess") for guess in guesses[::-1]: error = maybe_error(guess) if error is None: result = to_result(guess, word) s = f"{guess} | {result}" if result == GREEN * 5: s = f"{s} | CORRECT!" response.append(s) else: response.append(f"{guess} | ERROR: {error}")

      return [query, response]
      

      ```

    1. ```js // Getting details on a Threads user and outputting it to the console

      const getUserDetails = async (username) => { let userInfo = await threads.getUserData(username); console.log( "", Name: ${userInfo.full_name}\n, Bio: ${userInfo.biography}\n, ID: ${userInfo.user_id}\n, Followers: ${userInfo.follower_count}\n, Website: ${userInfo.bio_links[0].url} ); } getUserDetails("Gisgar3"); ```