<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: kandz</title>
    <description>The latest articles on DEV Community by kandz (@kandz).</description>
    <link>https://dev.to/kandz</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4010024%2Fba5408f9-0a6c-4392-8632-b33b6c9bb4df.jpg</url>
      <title>DEV Community: kandz</title>
      <link>https://dev.to/kandz</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/kandz"/>
    <language>en</language>
    <item>
      <title>Under the Hood: Building a 100% Client-Side CSV Deduplicator with Angular 18+ Signals</title>
      <dc:creator>kandz</dc:creator>
      <pubDate>Mon, 10 Aug 2026 10:35:32 +0000</pubDate>
      <link>https://dev.to/kandz/under-the-hood-building-a-100-client-side-csv-deduplicator-with-angular-18-signals-4fjo</link>
      <guid>https://dev.to/kandz/under-the-hood-building-a-100-client-side-csv-deduplicator-with-angular-18-signals-4fjo</guid>
      <description>&lt;p&gt;Tabular data cleaning is one of the most common prep steps in data engineering and business ops. However, pasting a CSV containing sensitive emails, customer IDs, or corporate financials into a third-party server poses massive security risks. &lt;/p&gt;

&lt;p&gt;To solve this, we built a 100% client-side &lt;strong&gt;CSV Row Deduplicator&lt;/strong&gt; on &lt;code&gt;tools.kandz.me&lt;/code&gt;. By processing everything in the browser sandbox, your data never touches a server. &lt;/p&gt;

&lt;p&gt;But parsing and deduplicating CSV format reliably in raw JavaScript is trickier than a simple &lt;code&gt;string.split(',')&lt;/code&gt;. Here is a deep dive into how it works under the hood.&lt;/p&gt;




&lt;h2&gt;
  
  
  1. The Core Architecture &amp;amp; Challenges
&lt;/h2&gt;

&lt;p&gt;At first glance, splitting CSV lines seems trivial. But standard production CSVs present major parsing edge cases:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Quoted Values with Commas&lt;/strong&gt;: A field like &lt;code&gt;"Doe, John"&lt;/code&gt; shouldn't be split at the comma.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Header Preservation&lt;/strong&gt;: The column names (first row) must remain at the top and never get removed as "duplicates," even if an identical row appears deep inside the dataset (e.g., if multiple CSV files were merged together).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Whitespace Variations&lt;/strong&gt;: &lt;code&gt;John Doe, john@example.com&lt;/code&gt; and &lt;code&gt;John Doe,john@example.com&lt;/code&gt; (notice the space) should be evaluated as duplicate rows if white spaces are trimmed.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  2. Breaking Down the Parser
&lt;/h2&gt;

&lt;p&gt;To handle quoted cells containing commas, we implement a stateful parser loop instead of a basic &lt;code&gt;.split(',')&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;parseCSVLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;line&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;current&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;inQuotes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;line&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;char&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;line&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;char&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;"&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;inQuotes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;inQuotes&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Toggle quotes state&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;char&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;,&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;inQuotes&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="nx"&gt;current&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;current&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="nx"&gt;char&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  3. Protecting the Header &amp;amp; Cleaning Merged Files
&lt;/h2&gt;

&lt;p&gt;A major logical bug in naive deduplicators is how they handle the &lt;strong&gt;First Row is Header&lt;/strong&gt; flag. If you shift the header row out of the array before processing, its key signature is never tracked. If an accidental duplicate of that header appears later in the body (very common when concatenating tables), it gets processed as a unique data row.&lt;/p&gt;

&lt;p&gt;To fix this, we generate the key signature of the shifted header and add it to our &lt;code&gt;seen&lt;/code&gt; tracking set &lt;em&gt;before&lt;/em&gt; processing the body:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;seen&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Set&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;hasHeader&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;headersRow&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;headerKey&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;colIdx&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;headerKey&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;isTrim&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;headersRow&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;colIdx&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;trim&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;headersRow&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;colIdx&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;cleanHeader&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;isTrim&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;headersRow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;c&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;trim&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;headersRow&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;headerKey&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;cleanHeader&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;|||&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nx"&gt;seen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;headerKey&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toLowerCase&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This ensures any repeated headers inside the data rows are instantly stripped out, keeping only the true, anchored header at the top of the output.&lt;/p&gt;




&lt;h2&gt;
  
  
  4. Reactive State management with Angular Signals
&lt;/h2&gt;

&lt;p&gt;We use Angular 18+ reactive Signals and &lt;code&gt;computed&lt;/code&gt; properties to keep calculations fast and clean. When the user changes any parameter (such as toggling case-sensitivity or choosing to deduplicate by a specific column), the engine automatically recalculates the output without manual event listeners or dirty DOM rendering.&lt;/p&gt;

&lt;p&gt;By using native input bindings (&lt;code&gt;[value]="csvInput()"&lt;/code&gt; and custom target update events) we bypass standard latency, ensuring smooth performance even with large files.&lt;/p&gt;




&lt;h2&gt;
  
  
  5. Summary
&lt;/h2&gt;

&lt;p&gt;By keeping everything client-side, we combine ultimate data privacy with rapid execution. If you need to clean up messy datasets, give the tool a run.&lt;/p&gt;

&lt;p&gt;Try the live tool: &lt;a href="https://tools.kandz.me/csv-deduplicator" rel="noopener noreferrer"&gt;tools.kandz.me/csv-deduplicator&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>angular</category>
      <category>javascript</category>
      <category>programming</category>
    </item>
    <item>
      <title>Stop Uploading Proprietary Graphics to Cloud Image Resizers 🖼️🚀</title>
      <dc:creator>kandz</dc:creator>
      <pubDate>Sat, 08 Aug 2026 10:15:26 +0000</pubDate>
      <link>https://dev.to/kandz/stop-uploading-proprietary-graphics-to-cloud-image-resizers-1nig</link>
      <guid>https://dev.to/kandz/stop-uploading-proprietary-graphics-to-cloud-image-resizers-1nig</guid>
      <description>&lt;p&gt;When optimizing image sizes for web deployments, preparing blog screenshots, or cropping user avatars, pasting them into random online resizers is a common routine. &lt;/p&gt;

&lt;p&gt;But there’s a major compliance and privacy catch.&lt;/p&gt;

&lt;p&gt;If you are uploading product mockups, proprietary design assets, or sensitive screenshots to cloud-dependent resizers, &lt;strong&gt;you are leaking your private graphics and brand assets to third-party databases.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To prevent this data vulnerability, we built a 100% secure, browser-isolated &lt;strong&gt;HTML Canvas Image Resizer&lt;/strong&gt; on &lt;code&gt;tools.kandz.me&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;👉 &lt;strong&gt;Try the Live Tool:&lt;/strong&gt; &lt;a href="https://tools.kandz.me/canvas-resizer" rel="noopener noreferrer"&gt;https://tools.kandz.me/canvas-resizer&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  🧠 How It Works Under the Hood
&lt;/h3&gt;

&lt;p&gt;This resizer processes your assets entirely on the client side. Here is the technical architecture that allows it to securely scale, crop, and convert image formats in local memory:&lt;/p&gt;

&lt;h4&gt;
  
  
  1. Zero-Upload Off-Screen Canvas Buffering
&lt;/h4&gt;

&lt;p&gt;We bypass remote servers completely by allocating a virtual, off-screen HTML5 &lt;code&gt;&amp;lt;canvas&amp;gt;&lt;/code&gt; element. When you drag and drop an image, the file is read as a local data URL and loaded into a native &lt;code&gt;Image()&lt;/code&gt; element. Once the target dimensions are set, we draw the image directly onto the canvas:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;canvas&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;canvas&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;canvas&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;width&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;targetWidth&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;canvas&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;height&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;targetHeight&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ctx&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;canvas&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getContext&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;2d&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;drawImage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;rawImageElement&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;targetWidth&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;targetHeight&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  2. Hardware-Accelerated Bicubic Resampling
&lt;/h4&gt;

&lt;p&gt;To prevent pixelation, jagged lines, and blurring artifacts when reducing image dimensions, our engine utilizes the browser's hardware-accelerated, high-fidelity interpolation filters:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;imageSmoothingEnabled&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;imageSmoothingQuality&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;high&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This forces the browser to apply advanced bicubic and bilinear resampling algorithms, computing a weighted average of adjacent pixel colors based on distance ratios to maintain crisp details and smooth gradients.&lt;/p&gt;

&lt;h4&gt;
  
  
  3. Format-Aware Binary Blobs
&lt;/h4&gt;

&lt;p&gt;Exporting the resized image is handled by converting the off-screen canvas buffer directly into high-precision binary blobs using the native &lt;code&gt;toBlob&lt;/code&gt; method:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;canvas&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toBlob&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;blob&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;URL&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createObjectURL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;blob&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;link&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;href&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;link&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;click&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;image/webp&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;0.92&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This allows us to dynamically convert and compress images on the fly—exporting lossy JPEGs, lossless PNGs, or modern compressed WebPs with custom quality ratios, saving massive bandwidth on your servers.&lt;/p&gt;




&lt;h3&gt;
  
  
  🛠️ Give it a spin
&lt;/h3&gt;

&lt;p&gt;Keep your private brand assets, interface mockups, and corporate screenshots secure on your own machine. &lt;/p&gt;

&lt;p&gt;🔗 &lt;strong&gt;Link to Tool:&lt;/strong&gt; &lt;a href="https://tools.kandz.me/canvas-resizer" rel="noopener noreferrer"&gt;https://tools.kandz.me/canvas-resizer&lt;/a&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>canvas</category>
      <category>security</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Why You Shouldn't Paste Production SQL Into Cloud Formaters 💾🚀</title>
      <dc:creator>kandz</dc:creator>
      <pubDate>Thu, 06 Aug 2026 08:58:59 +0000</pubDate>
      <link>https://dev.to/kandz/why-you-shouldnt-paste-production-sql-into-cloud-formaters-3g9b</link>
      <guid>https://dev.to/kandz/why-you-shouldnt-paste-production-sql-into-cloud-formaters-3g9b</guid>
      <description>&lt;p&gt;When optimizing slow-running database queries, pasting them into raw online formatters is a common routine. &lt;/p&gt;

&lt;p&gt;But there’s a major compliance and security catch.&lt;/p&gt;

&lt;p&gt;SQL queries are blueprints of your database architecture. They contain sensitive table definitions, index structures, column keys, and private schemas. Uploading these details to random cloud formatters is a &lt;strong&gt;massive security leak that exposes your backend topology.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To fix this risk, we built a 100% secure, browser-isolated &lt;strong&gt;SQL Formatter &amp;amp; Query Optimizer&lt;/strong&gt; on &lt;code&gt;tools.kandz.me&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;👉 &lt;strong&gt;Try the Live Tool:&lt;/strong&gt; &lt;a href="https://tools.kandz.me/sql-formatter-optimizer" rel="noopener noreferrer"&gt;https://tools.kandz.me/sql-formatter-optimizer&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  🧠 How It Works Under the Hood
&lt;/h3&gt;

&lt;p&gt;This optimizer evaluates queries completely on the client side. Here is the technical architecture that allows it to securely beautify schemas and run query performance heuristics:&lt;/p&gt;

&lt;h4&gt;
  
  
  1. Regex Token-Based Beautifier
&lt;/h4&gt;

&lt;p&gt;Instead of sending SQL blocks to remote parsers, our engine tokenizes queries line-by-line using a regex clause boundary. It matches major clauses (e.g., &lt;code&gt;SELECT&lt;/code&gt;, &lt;code&gt;FROM&lt;/code&gt;, &lt;code&gt;WHERE&lt;/code&gt;, &lt;code&gt;LEFT JOIN&lt;/code&gt;, &lt;code&gt;ON&lt;/code&gt;, &lt;code&gt;AND&lt;/code&gt;) and formats them on-the-fly:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;clauses&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;SELECT&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;FROM&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;WHERE&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;LEFT JOIN&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ON&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;AND&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="nx"&gt;clauses&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;clause&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;regex&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;RegExp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;b&lt;/span&gt;&lt;span class="se"&gt;\$&lt;/span&gt;&lt;span class="s2"&gt;{clause}&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;b`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;gi&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;clean&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;clean&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;regex&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;`\n&lt;/span&gt;&lt;span class="se"&gt;\$&lt;/span&gt;&lt;span class="s2"&gt;{clause}`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It then dynamically indents nested statements (like &lt;code&gt;AND&lt;/code&gt; or &lt;code&gt;ON&lt;/code&gt; operators) to create beautiful, highly readable visual layouts.&lt;/p&gt;

&lt;h4&gt;
  
  
  2. Sargability Heuristics &amp;amp; Index Alerts
&lt;/h4&gt;

&lt;p&gt;The optimizer runs local heuristics to scan for index-bypassing database bottlenecks:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Uncapped SELECTs:&lt;/strong&gt; Warns when &lt;code&gt;LIMIT&lt;/code&gt; thresholds are missing, preventing massive datasets from crashing browser buffers.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Non-Sargable WHERE Functions:&lt;/strong&gt; Detects functions applied to column filters (e.g. &lt;code&gt;WHERE YEAR(created_at) = 2026&lt;/code&gt;) which prevent B-tree index usage. It suggests date range rewrites:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;  &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;created_at&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="s1"&gt;'2026-01-01'&lt;/span&gt; &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="n"&gt;created_at&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="s1"&gt;'2026-12-31'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Leading Wildcard Scans:&lt;/strong&gt; Flags leading wildcard queries (e.g. &lt;code&gt;LIKE '%search%'&lt;/code&gt;) which trigger slow, linear full-table scans ($O(N)$) and bypass standard index structures ($O(\log N)$).&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  3. Automatic CREATE INDEX Compilation
&lt;/h4&gt;

&lt;p&gt;When the parser identifies joining keys (in &lt;code&gt;JOIN ON&lt;/code&gt;) or filters (in &lt;code&gt;WHERE&lt;/code&gt; clauses), it automatically filters out standard primary keys (like &lt;code&gt;id&lt;/code&gt;) and compiles targeted index commands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;INDEX&lt;/span&gt; &lt;span class="n"&gt;idx_user_id&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="k"&gt;table_name&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This gives backend developers a copy-ready DDL script to instantly boost database query speeds.&lt;/p&gt;




&lt;h3&gt;
  
  
  🛠️ Give it a spin
&lt;/h3&gt;

&lt;p&gt;Keep your private database schemas and log audits secure on your own machine. &lt;/p&gt;

&lt;p&gt;🔗 &lt;strong&gt;Link to Tool:&lt;/strong&gt; &lt;a href="https://tools.kandz.me/sql-formatter-optimizer" rel="noopener noreferrer"&gt;https://tools.kandz.me/sql-formatter-optimizer&lt;/a&gt;&lt;/p&gt;

</description>
      <category>sql</category>
      <category>database</category>
      <category>performance</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Why You Shouldn't Paste Private Logs Into Cloud Regex Testers 🔍</title>
      <dc:creator>kandz</dc:creator>
      <pubDate>Tue, 04 Aug 2026 10:09:52 +0000</pubDate>
      <link>https://dev.to/kandz/why-you-shouldnt-paste-private-logs-into-cloud-regex-testers-c6e</link>
      <guid>https://dev.to/kandz/why-you-shouldnt-paste-private-logs-into-cloud-regex-testers-c6e</guid>
      <description>&lt;p&gt;When debugging a complex regular expression—whether you're parsing user emails, server transaction logs, or customer database records—having a visual tester is essential. &lt;/p&gt;

&lt;p&gt;But there is a major security catch. &lt;/p&gt;

&lt;p&gt;Most popular online regex tools stream your raw test data straight to remote backends for compilation. If you are testing patterns against real production logs, &lt;strong&gt;you are leaking sensitive user data and credentials to third-party databases.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To prevent this data vulnerability, we built a 100% secure, browser-isolated &lt;strong&gt;JS Regex Match Visualizer&lt;/strong&gt; on &lt;code&gt;tools.kandz.me&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;👉 &lt;strong&gt;Try the Live Tool:&lt;/strong&gt; &lt;a href="https://tools.kandz.me/regex-visualizer" rel="noopener noreferrer"&gt;https://tools.kandz.me/regex-visualizer&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  🧠 How It Works Under the Hood
&lt;/h3&gt;

&lt;p&gt;This visualizer runs strictly within your browser's private memory sandbox. Here is the technical architecture that allows it to securely render and inspect matches on the fly:&lt;/p&gt;

&lt;h4&gt;
  
  
  1. Dynamic Local Compilation
&lt;/h4&gt;

&lt;p&gt;We compile your regex inputs using standard browser JavaScript engines, bypassing external server API runs completely. The regex is instantiated with selected modifier flags:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;flags&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;flagGlobal&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nx"&gt;flags&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;g&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;flagIgnoreCase&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nx"&gt;flags&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;i&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;flagMultiline&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nx"&gt;flags&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;m&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;regex&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;RegExp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;pattern&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;flags&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  2. HTML-Escaped Highlight Tokenizer
&lt;/h4&gt;

&lt;p&gt;Rendering visual highlights securely is critical. If we injected raw matches directly as HTML, it would trigger Cross-Site Scripting (XSS) errors. &lt;/p&gt;

&lt;p&gt;To ensure complete safety, our parser first sanitizes the entire source string. It then calculates the exact offset coordinates of each match, wraps the matched indices in highlighted &lt;code&gt;&amp;lt;span&amp;gt;&lt;/code&gt; blocks, and trusts the final computed string:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Safely wraps matched coordinate slices&lt;/span&gt;
&lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="s2"&gt;`&amp;lt;span class="bg-indigo-100 rounded cursor-pointer border-b-2" onclick="window.dispatchRegexMatchClick(&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;idx&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;)"&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nf"&gt;escapeHtml&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;m&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fullText&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;/span&amp;gt;`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  3. Global Event Dispatching
&lt;/h4&gt;

&lt;p&gt;We mapped dynamic click listeners onto individual highlighted DOM spans. Clicking any highlighted match in your browser triggers a global scoped callback that immediately inspects and displays that match's specific capture groups (&lt;code&gt;$1&lt;/code&gt;, &lt;code&gt;$2&lt;/code&gt;, etc.) in the active panel—making large data array audits incredibly fast.&lt;/p&gt;




&lt;h3&gt;
  
  
  🛠️ Keep Your Log Audits Secure
&lt;/h3&gt;

&lt;p&gt;Protect your database dumps and user logs from external API tracking. Try the visualizer on your local machine:&lt;/p&gt;

&lt;p&gt;🔗 &lt;strong&gt;Link to Tool:&lt;/strong&gt; &lt;a href="https://tools.kandz.me/regex-visualizer" rel="noopener noreferrer"&gt;https://tools.kandz.me/regex-visualizer&lt;/a&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>regex</category>
      <category>security</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Stop Writing Laravel Migrations by Hand. Convert Raw SQL Instantly! 🚀</title>
      <dc:creator>kandz</dc:creator>
      <pubDate>Sun, 02 Aug 2026 18:06:08 +0000</pubDate>
      <link>https://dev.to/kandz/stop-writing-laravel-migrations-by-hand-convert-raw-sql-instantly-1d7b</link>
      <guid>https://dev.to/kandz/stop-writing-laravel-migrations-by-hand-convert-raw-sql-instantly-1d7b</guid>
      <description>&lt;p&gt;If you are migrating a legacy application to Laravel, setting up local databases from existing production SQL dumps, or converting raw DDL to PHP schemas—you know the pain.&lt;/p&gt;

&lt;p&gt;Translating raw &lt;code&gt;CREATE TABLE&lt;/code&gt; statements into Laravel's fluent Blueprint migrations by hand is tedious, slow, and highly prone to syntax typos. &lt;/p&gt;

&lt;p&gt;To solve this developer bottleneck, we built a 100% local, instant &lt;strong&gt;SQL Schema to Laravel Migration Converter&lt;/strong&gt; on &lt;code&gt;tools.kandz.me&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;👉 &lt;strong&gt;Try the Live Tool:&lt;/strong&gt; &lt;a href="https://tools.kandz.me/sql-laravel" rel="noopener noreferrer"&gt;https://tools.kandz.me/sql-laravel&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  🧠 How It Works Under the Hood
&lt;/h3&gt;

&lt;p&gt;This converter is built strictly on browser-first Web APIs. It parses database layouts and translates schemas on the fly without ever exposing your sensitive schema models to a backend database:&lt;/p&gt;

&lt;h4&gt;
  
  
  1. DDL Pattern-Matching Parser
&lt;/h4&gt;

&lt;p&gt;Our core parsing pipeline reads the raw SQL string line-by-line using a regex DDL tokenizer. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Table Extraction:&lt;/strong&gt; It identifies database table labels using the &lt;code&gt;CREATE TABLE&lt;/code&gt; matching syntax:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;tableMatch&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;rawSql&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;match&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/CREATE&lt;/span&gt;&lt;span class="se"&gt;\s&lt;/span&gt;&lt;span class="sr"&gt;+TABLE&lt;/span&gt;&lt;span class="se"&gt;\s&lt;/span&gt;&lt;span class="sr"&gt;+`&lt;/span&gt;&lt;span class="se"&gt;?([&lt;/span&gt;&lt;span class="sr"&gt;a-zA-Z0-9_&lt;/span&gt;&lt;span class="se"&gt;]&lt;/span&gt;&lt;span class="sr"&gt;+&lt;/span&gt;&lt;span class="se"&gt;)&lt;/span&gt;&lt;span class="sr"&gt;`&lt;/span&gt;&lt;span class="se"&gt;?&lt;/span&gt;&lt;span class="sr"&gt;/i&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Type Mapping Dictionary:&lt;/strong&gt; It loops through column declarations, strips backticks, and maps common SQL database types (and constraints) directly into Laravel’s corresponding schema methods:

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;VARCHAR(255) NOT NULL UNIQUE&lt;/code&gt; ➔ &lt;code&gt;$table-&amp;gt;string('column', 255)-&amp;gt;unique();&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;BIGINT AUTO_INCREMENT PRIMARY KEY&lt;/code&gt; ➔ &lt;code&gt;$table-&amp;gt;id();&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;TINYINT(1)&lt;/code&gt; or &lt;code&gt;BOOLEAN&lt;/code&gt; ➔ &lt;code&gt;$table-&amp;gt;boolean('column');&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  2. Automatic Modifier Chaining
&lt;/h4&gt;

&lt;p&gt;Standard database modifiers like &lt;code&gt;DEFAULT&lt;/code&gt; values or nullability are captured by scanning line contexts. If &lt;code&gt;NOT NULL&lt;/code&gt; is absent, the parser automatically appends the fluent nullable chain:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$table&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'bio'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;nullable&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It also checks for typical timestamp fields and appends &lt;code&gt;$table-&amp;gt;timestamps();&lt;/code&gt; automatically if missing, ensuring compliance with modern Laravel standards.&lt;/p&gt;

&lt;h4&gt;
  
  
  3. 100% Client-Side Privacy Sandbox
&lt;/h4&gt;

&lt;p&gt;Database schemas and index names represent the blueprint of your system's architecture—uploading DDL files to external servers introduces huge security risks. &lt;/p&gt;

&lt;p&gt;Our converter uses &lt;strong&gt;100% local browser execution&lt;/strong&gt;. The entire parsing loop and PHP class generation run exclusively inside your browser's private memory thread. Your schema definitions never leave your device.&lt;/p&gt;




&lt;h3&gt;
  
  
  🛠️ Give it a spin
&lt;/h3&gt;

&lt;p&gt;Accelerate your migration workflows and stop translating database columns manually. &lt;/p&gt;

&lt;p&gt;🔗 &lt;strong&gt;Link to Tool:&lt;/strong&gt; &lt;a href="https://tools.kandz.me/sql-laravel" rel="noopener noreferrer"&gt;https://tools.kandz.me/sql-laravel&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Let me know your feedback in the comments, and if there are specific complex custom database constraints (like foreign key lookups) you would like me to add support for next!&lt;/em&gt;&lt;/p&gt;

</description>
      <category>laravel</category>
      <category>php</category>
      <category>database</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Stop Uploading Proprietary Binaries to Cloud Hex Viewers</title>
      <dc:creator>kandz</dc:creator>
      <pubDate>Fri, 31 Jul 2026 11:19:22 +0000</pubDate>
      <link>https://dev.to/kandz/stop-uploading-proprietary-binaries-to-cloud-hex-viewers-498f</link>
      <guid>https://dev.to/kandz/stop-uploading-proprietary-binaries-to-cloud-hex-viewers-498f</guid>
      <description>&lt;p&gt;When you are debugging binary structures, analyzing network packets, or checking compiled firmware artifacts, a solid Hex Viewer is an essential tool. &lt;/p&gt;

&lt;p&gt;But there’s a massive security catch. &lt;/p&gt;

&lt;p&gt;Many popular online hex dumpers require you to upload your files to their remote servers. If your binaries contain proprietary code, credentials, embedded API keys, or private salts, &lt;strong&gt;you are leaking your secrets to the cloud.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To fix this risk, I wanted a secure, robust alternative that runs completely in a local memory sandbox.&lt;/p&gt;

&lt;p&gt;Say hello to the &lt;strong&gt;Binary File Hex Viewer&lt;/strong&gt; on &lt;code&gt;tools.kandz.me&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;👉 &lt;strong&gt;Use the Live Tool:&lt;/strong&gt; &lt;a href="https://tools.kandz.me/hex-viewer" rel="noopener noreferrer"&gt;https://tools.kandz.me/hex-viewer&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  🧠 How It Works Under the Hood
&lt;/h3&gt;

&lt;p&gt;Unlike traditional cloud converters, this app processes everything client-side. Here is the core architecture that makes it work smoothly and securely in the browser:&lt;/p&gt;

&lt;h4&gt;
  
  
  1. Zero-Upload Sandbox with &lt;code&gt;FileReader&lt;/code&gt;
&lt;/h4&gt;

&lt;p&gt;We completely bypass remote servers by using the browser's native HTML5 &lt;code&gt;FileReader&lt;/code&gt; API. When you load a binary file, we execute:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;reader&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;readAsArrayBuffer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;file&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This transfers the raw bytes directly into the client's local memory space as a static &lt;code&gt;Uint8Array&lt;/code&gt;. No network packets containing your file ever leave your device.&lt;/p&gt;

&lt;h4&gt;
  
  
  2. Dynamic Endianness Decoding via &lt;code&gt;DataView&lt;/code&gt;
&lt;/h4&gt;

&lt;p&gt;Reconstructing multi-byte numbers (like &lt;code&gt;Int32&lt;/code&gt; or &lt;code&gt;Float32&lt;/code&gt;) from contiguous bytes is notoriously tricky because different processor architectures store data differently (Little Endian vs. Big Endian). &lt;/p&gt;

&lt;p&gt;To solve this, the byte inspector utilizes JavaScript's low-level &lt;code&gt;DataView&lt;/code&gt; API. Because we point the view directly at our localized array buffer, we can perform instant endianness flips simply by toggling a boolean argument:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Little Endian&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;littleVal&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;dataView&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getFloat32&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;offset&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Big Endian&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;bigVal&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;dataView&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getFloat32&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;offset&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  3. Protecting the DOM with Chunking
&lt;/h4&gt;

&lt;p&gt;Trying to render a 1MB binary file as individual DOM tables will immediately freeze your browser's paint cycles. &lt;/p&gt;

&lt;p&gt;To ensure a smooth 60fps experience, the layout operates on a pagination model driven by modern reactivity. Instead of rendering the full array, we calculate a dynamic slice based on a small chunk size (e.g., 512 bytes):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;pageStart&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;currentPage&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;pageSize&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;currentChunk&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;fileBuffer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;slice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;pageStart&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;pageStart&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;pageSize&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This keeps the rendered element tree incredibly small, ensuring instant load times and lightweight touch scrolling on mobile viewports.&lt;/p&gt;




&lt;h3&gt;
  
  
  🛠️ Give it a spin
&lt;/h3&gt;

&lt;p&gt;Keep your files where they belong—on your own machine. Try the viewer for yourself and see how easy it is to analyze binary layouts:&lt;/p&gt;

&lt;p&gt;🔗 &lt;a href="https://tools.kandz.me/hex-viewer" rel="noopener noreferrer"&gt;https://tools.kandz.me/hex-viewer&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Let me know your feedback in the comments, and what primitive types or endian formats you'd like decoded next!&lt;/em&gt;&lt;/p&gt;

</description>
      <category>security</category>
      <category>webdev</category>
      <category>tools</category>
      <category>devops</category>
    </item>
    <item>
      <title>Data Serialization: The Mechanics of List Delimiter Conversion and String Wrapping</title>
      <dc:creator>kandz</dc:creator>
      <pubDate>Wed, 29 Jul 2026 09:30:22 +0000</pubDate>
      <link>https://dev.to/kandz/data-serialization-the-mechanics-of-list-delimiter-conversion-and-string-wrapping-2dal</link>
      <guid>https://dev.to/kandz/data-serialization-the-mechanics-of-list-delimiter-conversion-and-string-wrapping-2dal</guid>
      <description>&lt;p&gt;In database administration, backend development, and systems auditing, one of the most common manual bottlenecks is preparing raw, unformatted datasets for software imports or SQL queries. Whether handling log exports, spreadsheet columns, or raw text blocks, developers must frequently restructure plain-text boundaries.&lt;/p&gt;

&lt;p&gt;This process is governed by the principles of &lt;strong&gt;Data Serialization and Tokenization&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Let's explore the mechanics of delimiter parsing, the performance advantages of linear deduplication, and how to build a highly optimized, client-side list-reformatting engine.&lt;/p&gt;




&lt;h2&gt;
  
  
  1. The Anatomy of plain-text Delimiters
&lt;/h2&gt;

&lt;p&gt;In computer science, a delimiter is a sequence of one or more characters used to specify the boundary between separate, independent regions in a plain-text stream. Standard delimiters include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Newlines (&lt;code&gt;\n&lt;/code&gt; or &lt;code&gt;\r\n&lt;/code&gt;):&lt;/strong&gt; Used primarily to separate database rows or spreadsheet records.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Commas (&lt;code&gt;,&lt;/code&gt;):&lt;/strong&gt; The universal separator for CSV files.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Semicolons (&lt;code&gt;;&lt;/code&gt;):&lt;/strong&gt; Common in European localized data exports.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Spaces (&lt;code&gt;&lt;/code&gt;):&lt;/strong&gt; Used to delimit command-line arguments or token streams.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  The Wrapping Challenge (SQL Arrays)
&lt;/h3&gt;

&lt;p&gt;If you copy a column of 100 usernames from a spreadsheet, they arrive separated by newlines:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;user_1
user_2
user_3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To run a query against these users in SQL (e.g., using an &lt;code&gt;IN&lt;/code&gt; clause), you cannot paste them as-is. You must convert them into a comma-separated list and wrap each string token in single quotes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;'user_1', 'user_2', 'user_3'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Applying these quote wrappers and re-delimiting thousands of items manually is highly tedious and prone to missing-character syntax errors.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. Algorithmic Data Cleaning and Sanitization
&lt;/h2&gt;

&lt;p&gt;An optimized delimiter converter must perform three sequential operations on a raw string:&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Tokenization (Splitting)
&lt;/h3&gt;

&lt;p&gt;The raw string is split into an array of tokens based on the designated input delimiter. To handle multiple carriage return standards across Windows and Unix filesystems, newline splitting should normalize &lt;code&gt;\r\n&lt;/code&gt; and &lt;code&gt;\n&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;tokens&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;rawInput&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;\r?\n&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 2: Sanitization (Trimming &amp;amp; Deduplication)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Trimming&lt;/strong&gt;: Stripping leading and trailing whitespace from each token prevents trailing-space bugs in downstream database indices.&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Deduplication&lt;/strong&gt;: In database auditing, ensuring unique keys is vital. We can filter out duplicates in &lt;strong&gt;linear time $O(N)$&lt;/strong&gt; using a JavaScript &lt;code&gt;Set&lt;/code&gt; data structure:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;uniqueTokens&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;tokens&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;t&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;trim&lt;/span&gt;&lt;span class="p"&gt;()).&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;t&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step 3: Wrapping &amp;amp; Re-assembling
&lt;/h3&gt;

&lt;p&gt;Each unique, sanitized token is wrapped in the user's chosen quote style (single quotes, double quotes, or square brackets) and joined back together using the target output delimiter.&lt;/p&gt;




&lt;h2&gt;
  
  
  3. Implementing the Re-Formatter in TypeScript
&lt;/h2&gt;

&lt;p&gt;Here is a clean, non-recursive TypeScript function that processes, sanitizes, wraps, and re-delimits any raw list dataset:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;reformatList&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;inputDelim&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;outputDelim&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;wrapStyle&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;none&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;single&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;double&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;bracket&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;trim&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;boolean&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;deduplicate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;boolean&lt;/span&gt;
&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;trim&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;tokens&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;inputDelim&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;trim&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;tokens&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;tokens&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;t&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;trim&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;tokens&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;tokens&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;t&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;deduplicate&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;tokens&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;tokens&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;wrapped&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;tokens&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;token&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;wrapStyle&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;single&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;`'&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;token&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;'`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;wrapStyle&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;double&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;`"&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;token&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;wrapStyle&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;bracket&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;`[&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;token&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;]`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;token&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;joinSeparator&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;outputDelim&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;outputDelim&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; `&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;wrapped&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;joinSeparator&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  4. Absolute Client-Side Privacy for Database Exports
&lt;/h2&gt;

&lt;p&gt;Database exports, server logs, and user lists regularly contain highly sensitive, proprietary information—including usernames, internal emails, server IP logs, or system keys. Uploading these raw lists to cloud-logged remote text formatters presents severe data privacy and compliance risks.&lt;/p&gt;

&lt;p&gt;We enforce a strict &lt;strong&gt;100% Client-Side Privacy Law&lt;/strong&gt; across our tool suite. All string splits, token sanitizations, and quote-wrapping operations execute locally within your browser's private memory sandbox. No data ever traverses the network, keeping your database logs and corporate lists secure.&lt;/p&gt;

&lt;p&gt;Format your datasets privately: &lt;a href="https://tools.kandz.me/delimiter-converter" rel="noopener noreferrer"&gt;List Delimiter Converter - Kandz.me&lt;/a&gt;&lt;/p&gt;

</description>
      <category>programming</category>
      <category>database</category>
      <category>data</category>
      <category>webdev</category>
    </item>
    <item>
      <title>The Trigonometry of Oblique Spaces: Solving Triangles with the Law of Sines and Cosines in Code</title>
      <dc:creator>kandz</dc:creator>
      <pubDate>Mon, 27 Jul 2026 10:25:03 +0000</pubDate>
      <link>https://dev.to/kandz/the-trigonometry-of-oblique-spaces-solving-triangles-with-the-law-of-sines-and-cosines-in-code-2iml</link>
      <guid>https://dev.to/kandz/the-trigonometry-of-oblique-spaces-solving-triangles-with-the-law-of-sines-and-cosines-in-code-2iml</guid>
      <description>&lt;p&gt;In computer graphics, spatial mapping, navigation, and structural engineering, the triangle represents the fundamental geometric simplex. While solving right-angled triangles requires only basic Pythagorean theorems and standard trigonometric ratios (sine, cosine, tangent), solving oblique (non-right) triangles requires more advanced algebraic models.&lt;/p&gt;

&lt;p&gt;To resolve these structures, we must implement the &lt;strong&gt;Law of Sines&lt;/strong&gt; and the &lt;strong&gt;Law of Cosines&lt;/strong&gt; in code.&lt;/p&gt;

&lt;p&gt;Let's break down the mathematical formulations for solving oblique triangles, handle the complex "Ambiguous Case" of trigonometry, and write clean, constant-time algorithms to resolve any triangle's dimensions.&lt;/p&gt;




&lt;h2&gt;
  
  
  1. The Trigonometric Foundations of Oblique Solvers
&lt;/h2&gt;

&lt;p&gt;A triangle consists of three sides ($a, b, c$) and three opposing angles ($A, B, C$).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;          C
         / \
      b /   \ a
       /     \
      A-------B
          c
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To solve a triangle means to calculate all unknown dimensions when given at least three known parameters (with at least one of those parameters being a side).&lt;/p&gt;




&lt;h3&gt;
  
  
  Methodology A: The Law of Cosines (SSS &amp;amp; SAS)
&lt;/h3&gt;

&lt;p&gt;The Law of Cosines is a generalization of the Pythagorean theorem. It is used to resolve triangles when we are given three sides (SSS) or two sides and their enclosed angle (SAS).&lt;/p&gt;

&lt;p&gt;The formula states:&lt;br&gt;
$$c^2 = a^2 + b^2 - 2ab \cdot \cos(C)$$&lt;/p&gt;

&lt;p&gt;To find an angle when given three sides (SSS), we can rewrite the equation as:&lt;br&gt;
$$\cos(C) = \frac{a^2 + b^2 - c^2}{2ab}$$&lt;br&gt;
$$C = \arccos\left(\frac{a^2 + b^2 - c^2}{2ab}\right)$$&lt;/p&gt;

&lt;p&gt;In programming, we must convert degrees to radians before passing values to native trigonometric functions, and convert the returned radians back to degrees:&lt;br&gt;
$$\text{Radians} = \text{Degrees} \times \frac{\pi}{180}$$&lt;/p&gt;


&lt;h3&gt;
  
  
  Methodology B: The Law of Sines (ASA &amp;amp; AAS)
&lt;/h3&gt;

&lt;p&gt;The Law of Sines establishes a constant ratio between the length of a triangle's sides and the sine of their opposing angles:&lt;br&gt;
$$\frac{a}{\sin(A)} = \frac{b}{\sin(B)} = \frac{c}{\sin(C)}$$&lt;/p&gt;

&lt;p&gt;This is used to resolve triangles when we are given two angles and a side (ASA or AAS). If we know two angles, the third angle is easily found since the sum of internal angles in a Euclidean triangle is always 180°:&lt;br&gt;
$$C = 180^{\circ} - A - B$$&lt;/p&gt;

&lt;p&gt;Once all angles are known, we can calculate any missing side:&lt;br&gt;
$$a = b \cdot \frac{\sin(A)}{\sin(B)}$$&lt;/p&gt;


&lt;h3&gt;
  
  
  Methodology C: The Ambiguous Case (SSA)
&lt;/h3&gt;

&lt;p&gt;The most mathematically complex scenario is the &lt;strong&gt;Side-Side-Angle (SSA)&lt;/strong&gt; configuration, where we are given two sides ($a, b$) and a non-enclosed angle ($A$).&lt;/p&gt;

&lt;p&gt;Depending on the relationship between side $a$, side $b$, and the height $h = b \cdot \sin(A)$, the system can yield:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;Zero Solutions:&lt;/strong&gt; If $a &amp;lt; h$ (the side is too short to reach the base line).&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;One Solution:&lt;/strong&gt; If $a \ge b$ or $a = h$.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Two Solutions (The Ambiguous Case):&lt;/strong&gt; If $h &amp;lt; a &amp;lt; b$. In this scenario, two entirely different triangles can be formed with the same given parameters—one acute and one obtuse.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;An oblique solver must calculate both possible configurations, alerting the user to this dual-coordinate state.&lt;/p&gt;


&lt;h2&gt;
  
  
  2. Implementing the Solver in TypeScript
&lt;/h2&gt;

&lt;p&gt;Here is a clean TypeScript function that parses and solves a Side-Angle-Angle (AAS) triangle, converting degrees and utilizing the Law of Sines:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;TriangleResult&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;b&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;c&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;A&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;B&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;C&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;area&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;perimeter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;solveAAS&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;knownSideValue&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;opposingAngleDeg&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;secondAngleDeg&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;
&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;TriangleResult&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;degToRad&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;PI&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;180&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;radToDeg&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;180&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;PI&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;A&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;opposingAngleDeg&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;B&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;secondAngleDeg&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;C&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;180&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;A&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;B&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;knownSideValue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sinA&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;A&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;degToRad&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sinB&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;B&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;degToRad&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sinC&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;C&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;degToRad&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sinB&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="nx"&gt;sinA&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;c&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sinC&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="nx"&gt;sinA&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;perimeter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;c&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="c1"&gt;// Area calculated using Heron's formula&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;perimeter&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;area&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sqrt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;s&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;s&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;s&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;s&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;c&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toFixed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
    &lt;span class="na"&gt;b&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toFixed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
    &lt;span class="na"&gt;c&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toFixed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
    &lt;span class="na"&gt;A&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;A&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toFixed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
    &lt;span class="na"&gt;B&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;B&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toFixed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
    &lt;span class="na"&gt;C&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;C&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toFixed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
    &lt;span class="na"&gt;area&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;area&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toFixed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
    &lt;span class="na"&gt;perimeter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;perimeter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toFixed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  3. Client-Side Security for Engineering and CAD Specifications
&lt;/h2&gt;

&lt;p&gt;Civil engineers, surveyors, and CAD draftsmen regularly calculate precise triangle dimensions for proprietary structures, land plots, or mechanical designs. Submitting these specific measurements, coordinate boundaries, or spatial specs to external cloud-logged tools presents substantial corporate intellectual property risks.&lt;/p&gt;

&lt;p&gt;We enforce a strict &lt;strong&gt;100% Client-Side Privacy Law&lt;/strong&gt; across our tool suite. Every trigonometric evaluation, radian conversion, and area calculation is computed locally inside your browser's RAM. No spatial parameters are ever transmitted over the network, keeping your engineering designs and CAD assets secure.&lt;/p&gt;

&lt;p&gt;Solve triangle dimensions privately: &lt;a href="https://tools.kandz.me/triangle-solver" rel="noopener noreferrer"&gt;Triangle (Trigonometry) Solver - Kandz.me&lt;/a&gt;&lt;/p&gt;

</description>
      <category>math</category>
      <category>geometry</category>
      <category>programming</category>
      <category>webdev</category>
    </item>
    <item>
      <title>The Mathematics of Value Decay: Modeling Asset Depreciation Schedules in Code</title>
      <dc:creator>kandz</dc:creator>
      <pubDate>Sat, 25 Jul 2026 15:00:52 +0000</pubDate>
      <link>https://dev.to/kandz/the-mathematics-of-value-decay-modeling-asset-depreciation-schedules-in-code-3dk</link>
      <guid>https://dev.to/kandz/the-mathematics-of-value-decay-modeling-asset-depreciation-schedules-in-code-3dk</guid>
      <description>&lt;p&gt;In enterprise resource planning (ERP), corporate finance, and system engineering, tracking how physical hardware assets lose value over time is a core operational requirement. Whether managing server racks, office buildings, or vehicle fleets, companies must account for this decay on their balance sheets.&lt;/p&gt;

&lt;p&gt;This process is governed by specific mathematical algorithms collectively known as &lt;strong&gt;Asset Depreciation&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Let's break down the mathematical formulations behind three standard depreciation methodologies (Straight-Line, Declining Balance, and Sum-of-the-Years' Digits), write clean code to model their schedules, and discuss the security advantages of client-side computing.&lt;/p&gt;




&lt;h2&gt;
  
  
  1. The Mathematical Models of Depreciation
&lt;/h2&gt;

&lt;p&gt;Every depreciation model operates on three base parameters:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Asset Cost ($C$):&lt;/strong&gt; The initial purchase value of the asset.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Salvage Value ($S$):&lt;/strong&gt; The estimated residual value of the asset at the end of its useful life.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Useful Life ($L$):&lt;/strong&gt; The expected duration of the asset's service, typically measured in years.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The depreciable base represents the total value to be depreciated over the asset's life:&lt;br&gt;
$$\text{Depreciable Base} = C - S$$&lt;/p&gt;


&lt;h3&gt;
  
  
  Methodology A: Straight-Line (Constant Linear Decay)
&lt;/h3&gt;

&lt;p&gt;Straight-Line is the simplest and most common depreciation model. It assumes that the asset loses an identical, constant value on every interval of its useful life.&lt;/p&gt;

&lt;p&gt;The annual depreciation rate ($R$) is constant:&lt;br&gt;
$$R = \frac{1}{L}$$&lt;/p&gt;

&lt;p&gt;The annual depreciation expense ($D$) is calculated as:&lt;br&gt;
$$D = (C - S) \times R = \frac{C - S}{L}$$&lt;/p&gt;


&lt;h3&gt;
  
  
  Methodology B: Declining Balance (Exponential Decay)
&lt;/h3&gt;

&lt;p&gt;Declining Balance is an accelerated depreciation method. It writes off a higher percentage of the asset's value in the early years of its useful life, mimicking physical assets like vehicles, which lose value rapidly immediately after purchase.&lt;/p&gt;

&lt;p&gt;It applies a constant depreciation factor ($F$, commonly $2.0$ for Double Declining Balance) to the remaining book value at the start of each year ($B_y$).&lt;/p&gt;

&lt;p&gt;The annual depreciation rate is:&lt;br&gt;
$$R = \frac{F}{L}$$&lt;/p&gt;

&lt;p&gt;For any year $y$:&lt;br&gt;
$$D_y = B_y \times R$$&lt;br&gt;
$$B_{y+1} = B_y - D_y$$&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note: The asset's book value cannot depreciate below its salvage value ($S$). The final year's calculation must be capped to ensure the final book value matches $S$ exactly.&lt;/em&gt;&lt;/p&gt;


&lt;h3&gt;
  
  
  Methodology C: Sum-of-the-Years' Digits (Accelerated Non-Linear Decay)
&lt;/h3&gt;

&lt;p&gt;Sum-of-the-Years' Digits (SYD) is another accelerated method, but unlike Declining Balance, it uses a variable fraction that decreases linearly on each interval.&lt;/p&gt;

&lt;p&gt;First, we calculate the sum of the digits of the useful years ($SYD$):&lt;br&gt;
$$\text{SYD} = 1 + 2 + 3 + \dots + L = \frac{L \times (L + 1)}{2}$$&lt;/p&gt;

&lt;p&gt;For any active year $y$ (from $1$ to $L$), the remaining useful life of the asset is:&lt;br&gt;
$$\text{Remaining Life} = L - y + 1$$&lt;/p&gt;

&lt;p&gt;The annual depreciation expense ($D_y$) is:&lt;br&gt;
$$D_y = (C - S) \times \frac{\text{Remaining Life}}{\text{SYD}}$$&lt;/p&gt;


&lt;h2&gt;
  
  
  2. Implementing the Algorithms in TypeScript
&lt;/h2&gt;

&lt;p&gt;We can model these three mathematical decay tracks cleanly in a single, non-recursive TypeScript loop that generates a complete annual depreciation schedule:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;ScheduleRow&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;year&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;expense&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;totalDepreciation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;bookValue&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;calculateDepreciationSchedule&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;cost&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;salvage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;life&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;straight-line&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;declining-balance&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;syd&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;factor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;2.0&lt;/span&gt;
&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;ScheduleRow&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;schedule&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ScheduleRow&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;bookValue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;cost&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;totalDepreciation&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;depreciableBase&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;cost&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;salvage&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;method&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;straight-line&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;annualExpense&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;depreciableBase&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="nx"&gt;life&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;y&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="nx"&gt;life&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;totalDepreciation&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="nx"&gt;annualExpense&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nx"&gt;bookValue&lt;/span&gt; &lt;span class="o"&gt;-=&lt;/span&gt; &lt;span class="nx"&gt;annualExpense&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nx"&gt;schedule&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="na"&gt;year&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;expense&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;annualExpense&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toFixed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
        &lt;span class="na"&gt;totalDepreciation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;totalDepreciation&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toFixed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
        &lt;span class="na"&gt;bookValue&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;max&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;salvage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;bookValue&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toFixed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
      &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;method&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;syd&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sydSum&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;life&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;life&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;y&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="nx"&gt;life&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;remainingLife&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;life&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;y&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;annualExpense&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;depreciableBase&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;remainingLife&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="nx"&gt;sydSum&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="nx"&gt;totalDepreciation&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="nx"&gt;annualExpense&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nx"&gt;bookValue&lt;/span&gt; &lt;span class="o"&gt;-=&lt;/span&gt; &lt;span class="nx"&gt;annualExpense&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nx"&gt;schedule&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="na"&gt;year&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;expense&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;annualExpense&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toFixed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
        &lt;span class="na"&gt;totalDepreciation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;totalDepreciation&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toFixed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
        &lt;span class="na"&gt;bookValue&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;max&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;salvage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;bookValue&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toFixed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
      &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;method&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;declining-balance&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;rate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;factor&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="nx"&gt;life&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;y&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="nx"&gt;life&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;annualExpense&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;bookValue&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;rate&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

      &lt;span class="c1"&gt;// Ensure we do not depreciate below salvage value&lt;/span&gt;
      &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;bookValue&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;annualExpense&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;salvage&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;annualExpense&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;bookValue&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;salvage&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;

      &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;y&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;life&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;annualExpense&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;bookValue&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;salvage&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;

      &lt;span class="nx"&gt;totalDepreciation&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="nx"&gt;annualExpense&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nx"&gt;bookValue&lt;/span&gt; &lt;span class="o"&gt;-=&lt;/span&gt; &lt;span class="nx"&gt;annualExpense&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nx"&gt;schedule&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="na"&gt;year&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;expense&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;annualExpense&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toFixed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
        &lt;span class="na"&gt;totalDepreciation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;totalDepreciation&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toFixed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
        &lt;span class="na"&gt;bookValue&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;max&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;salvage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;bookValue&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toFixed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
      &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;schedule&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  3. Client-Side Security for Corporate Financial Audits
&lt;/h2&gt;

&lt;p&gt;Corporate physical asset inventories, capital budgets, and salvage projections represent highly sensitive, proprietary financial plans. Uploading raw procurement data, server purchase costs, or hardware lifespans to cloud-logged web forms exposes your corporate balance sheets and infrastructure budgets to tracking and data harvesting risks.&lt;/p&gt;

&lt;p&gt;Our &lt;strong&gt;Asset Depreciation Calculator&lt;/strong&gt; enforces our strict &lt;strong&gt;100% Client-Side Privacy Law&lt;/strong&gt;. All calculation loops, matrix schedule builds, and rounding operations execute locally within your browser's private memory sandbox. No data ever traverses the network, keeping your corporate hardware inventories and balance sheets completely confidential.&lt;/p&gt;

&lt;p&gt;Audit your hardware assets securely: &lt;a href="https://tools.kandz.me/depreciation-calculator" rel="noopener noreferrer"&gt;Asset Depreciation Calculator - Kandz.me&lt;/a&gt;&lt;/p&gt;

</description>
      <category>math</category>
      <category>finance</category>
      <category>programming</category>
      <category>architecture</category>
    </item>
    <item>
      <title>Mapping Human Biology: The Bitwise Boolean Algebra of Blood Transfusion Compatibility</title>
      <dc:creator>kandz</dc:creator>
      <pubDate>Thu, 23 Jul 2026 11:21:39 +0000</pubDate>
      <link>https://dev.to/kandz/mapping-human-biology-the-bitwise-boolean-algebra-of-blood-transfusion-compatibility-3dhj</link>
      <guid>https://dev.to/kandz/mapping-human-biology-the-bitwise-boolean-algebra-of-blood-transfusion-compatibility-3dhj</guid>
      <description>&lt;p&gt;While blood transfusion is fundamentally a medical procedure, its underlying compatibility rules can be modeled as a directed graph or represented elegantly using &lt;strong&gt;bitwise Boolean algebra&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Instead of writing complex, nested conditional loops (&lt;code&gt;if/else&lt;/code&gt;) to check if Blood Type X can donate to Blood Type Y, we can represent human blood antigens as a &lt;strong&gt;3-bit binary array&lt;/strong&gt; and determine compatibility using a single bitwise operation.&lt;/p&gt;

&lt;p&gt;Let's explore the mathematics of ABO and Rh antigen matching, the Boolean matrix of transfusions, and how to write clean, constant-time compatibility algorithms.&lt;/p&gt;




&lt;h2&gt;
  
  
  1. The Antigen Vector Space
&lt;/h2&gt;

&lt;p&gt;Human red blood cells are classified by the presence or absence of specific inherited proteins (antigens) on their cell membranes. The primary typing systems are the &lt;strong&gt;ABO&lt;/strong&gt; system (A and B antigens) and the &lt;strong&gt;Rh&lt;/strong&gt; system (D antigen).&lt;/p&gt;

&lt;p&gt;We can model this as a 3-dimensional vector space where each dimension is a binary flag (0 or 1):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Bit 0 ($2^0$):&lt;/strong&gt; Presence of &lt;strong&gt;A&lt;/strong&gt; antigen (1 = Present, 0 = Absent)&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Bit 1 ($2^1$):&lt;/strong&gt; Presence of &lt;strong&gt;B&lt;/strong&gt; antigen (1 = Present, 0 = Absent)&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Bit 2 ($2^2$):&lt;/strong&gt; Presence of &lt;strong&gt;D (Rh)&lt;/strong&gt; antigen (1 = Present, 0 = Absent)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Using this 3-bit binary mask, we can map the 8 primary human blood types to integer values from 0 to 7:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Blood Type&lt;/th&gt;
&lt;th&gt;Rh (Bit 2)&lt;/th&gt;
&lt;th&gt;B (Bit 1)&lt;/th&gt;
&lt;th&gt;A (Bit 0)&lt;/th&gt;
&lt;th&gt;Binary Mask&lt;/th&gt;
&lt;th&gt;Integer Value&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;O-&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;&lt;code&gt;000&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;0&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;A-&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;&lt;code&gt;001&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;1&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;B-&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;&lt;code&gt;010&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;2&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;AB-&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;&lt;code&gt;011&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;3&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;O+&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;&lt;code&gt;100&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;4&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;A+&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;&lt;code&gt;101&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;B+&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;&lt;code&gt;110&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;6&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;AB+&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;&lt;code&gt;111&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;7&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  2. The Transfusion Compatability Equation
&lt;/h2&gt;

&lt;p&gt;The fundamental rule of blood transfusion safety is that &lt;strong&gt;a recipient’s immune system will attack any foreign antigen it does not already possess&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Therefore, a donor is only compatible with a recipient if the donor has &lt;strong&gt;zero&lt;/strong&gt; antigens that the recipient lacks. &lt;/p&gt;

&lt;p&gt;If we represent the donor's antigen mask as $D$ and the recipient's antigen mask as $R$, compatibility requires that for every bit index $i$:&lt;br&gt;
$$\text{If } D_i = 1 \text{ then } R_i \text{ must be } 1$$&lt;/p&gt;

&lt;p&gt;Logically, this means:&lt;br&gt;
$$\text{Compatible} = \neg (D_i \land \neg R_i)$$&lt;/p&gt;

&lt;p&gt;In computer science, we can express this entire evaluation across all three bits simultaneously using a single bitwise operation in &lt;strong&gt;constant time $O(1)$&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;isCompatible&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;donorMask&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;~&lt;/span&gt;&lt;span class="nx"&gt;recipientMask&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Let’s trace a few cases using this bitwise logic:
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Case A: Donor is O- (&lt;code&gt;000&lt;/code&gt;), Recipient is A+ (&lt;code&gt;101&lt;/code&gt;)
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;Invert Recipient: &lt;code&gt;~101&lt;/code&gt; = &lt;code&gt;010&lt;/code&gt; (in 3-bit space)&lt;/li&gt;
&lt;li&gt;Bitwise AND: &lt;code&gt;000 &amp;amp; 010&lt;/code&gt; = &lt;code&gt;000&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Check: &lt;code&gt;000 === 0&lt;/code&gt; is &lt;strong&gt;True&lt;/strong&gt; (O- can safely donate to A+).&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  Case B: Donor is A+ (&lt;code&gt;101&lt;/code&gt;), Recipient is B- (&lt;code&gt;010&lt;/code&gt;)
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;Invert Recipient: &lt;code&gt;~010&lt;/code&gt; = &lt;code&gt;101&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Bitwise AND: &lt;code&gt;101 &amp;amp; 101&lt;/code&gt; = &lt;code&gt;101&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Check: &lt;code&gt;101 === 0&lt;/code&gt; is &lt;strong&gt;False&lt;/strong&gt; (A+ cannot donate to B-).&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This algebraic representation eliminates the need for nesting loops and accurately models the biochemical reality of antigen matching.&lt;/p&gt;




&lt;h2&gt;
  
  
  3. Modeling the Directed Graph
&lt;/h2&gt;

&lt;p&gt;If we map these compatibilities as a directed network where a directed edge $E(D, R)$ exists only if $D$ can donate to $R$, the network forms a &lt;strong&gt;partially ordered set (poset)&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;       [AB+] (Universal Recipient)
       / │ \
     [A+]│ [B+]
     / \ │ / \
   [A-] [O+] [B-]
     \  / \  /
     [O-] (Universal Donor)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;O- (&lt;code&gt;000&lt;/code&gt;)&lt;/strong&gt; sits at the absolute bottom of the graph. Having no antigens, it has out-degree edges pointing to all nodes (Universal Donor).&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;AB+ (&lt;code&gt;111&lt;/code&gt;)&lt;/strong&gt; sits at the absolute top of the graph. Possessing all antigens, it has in-degree edges arriving from all nodes (Universal Recipient).&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  4. Absolute Client-Side Biometric Privacy
&lt;/h2&gt;

&lt;p&gt;Biological and medical metrics represent highly sensitive personal information. Uploading your specific blood typing profiles, family compatibility checks, or biometric configurations to server-dependent online calculators introduces major tracking and data-profiling vulnerabilities.&lt;/p&gt;

&lt;p&gt;Our &lt;strong&gt;Blood Donor Compatibility Calculator&lt;/strong&gt; enforces a strict &lt;strong&gt;100% Client-Side Privacy Law&lt;/strong&gt;. All bitwise calculations, directed graph mappings, and compatibility checks execute locally inside your browser's temporary memory (RAM). No biometric metrics are ever transmitted over the network, keeping your health audits secure.&lt;/p&gt;

&lt;p&gt;Evaluate your compatibility securely: &lt;a href="https://tools.kandz.me/blood-type" rel="noopener noreferrer"&gt;Blood Donor Compatibility Calculator - Kandz.me&lt;/a&gt;&lt;/p&gt;




</description>
      <category>programming</category>
      <category>javascript</category>
      <category>biology</category>
      <category>math</category>
    </item>
    <item>
      <title>The Physics of UI Depth: CSS Box-Shadow Vectors and GPU Compositing Pipelines</title>
      <dc:creator>kandz</dc:creator>
      <pubDate>Tue, 21 Jul 2026 11:19:16 +0000</pubDate>
      <link>https://dev.to/kandz/the-physics-of-ui-depth-css-box-shadow-vectors-and-gpu-compositing-pipelines-29l7</link>
      <guid>https://dev.to/kandz/the-physics-of-ui-depth-css-box-shadow-vectors-and-gpu-compositing-pipelines-29l7</guid>
      <description>&lt;p&gt;Modern user interfaces use elevation and shadows to establish a visual hierarchy of layers. On a flat 2D screen, this depth is an optical illusion created by simulating light source projections and shadow scattering. &lt;/p&gt;

&lt;p&gt;While generating a drop shadow in CSS is as simple as typing &lt;code&gt;box-shadow&lt;/code&gt;, under the hood, the browser's rendering engine executes complex coordinate vector translations and expensive pixel convolution passes.&lt;/p&gt;

&lt;p&gt;Let's break down the mathematics behind CSS depth calculations, the performance costs of rasterizing shadows, and how to optimize shadow animations for hardware acceleration.&lt;/p&gt;




&lt;h2&gt;
  
  
  1. The Coordinate Calculus of a Drop Shadow
&lt;/h2&gt;

&lt;p&gt;A standard CSS box-shadow property is declared as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;box-shadow&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;offset-x&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;offset-y&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;blur-radius&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;spread-radius&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;color&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To map this to a physical lighting model, we can treat the screen as an $(x, y)$ coordinate plane where a virtual light source is positioned at some vector direction relative to the UI element.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Offset Vector $(dx, dy)$
&lt;/h3&gt;

&lt;p&gt;The horizontal and vertical offsets determine the shadow's direction and indicate the relative angle of the light source. If the light source is located at an angle $\theta$ relative to the camera vector, the offsets are computed as:&lt;br&gt;
$$dx = d \cdot \cos(\theta)$$&lt;br&gt;
$$dy = d \cdot \sin(\theta)$$&lt;br&gt;
where $d$ represents the physical extrusion distance of the element from the background plane.&lt;/p&gt;
&lt;h3&gt;
  
  
  The Blur Radius ($r$) and Gaussian Approximation
&lt;/h3&gt;

&lt;p&gt;The blur radius determines the softness of the shadow's edges. In physics, this is known as the &lt;strong&gt;penumbra&lt;/strong&gt;—the partially shaded outer region of a shadow where the light source is only partially blocked.&lt;/p&gt;

&lt;p&gt;To render this softness, browser engines (such as Chromium’s Blink or WebKit) apply a convolution filter to the rasterized shape. While the ideal physical model uses a &lt;strong&gt;Gaussian Blur&lt;/strong&gt; filter—which calculates new pixel values based on a normal distribution curve—doing so in real-time is highly CPU-intensive.&lt;/p&gt;

&lt;p&gt;Instead, browser engines approximate a Gaussian Blur using a &lt;strong&gt;triple box blur&lt;/strong&gt; algorithm. A box blur computes the average color value of a pixel’s neighbors within a square sliding window. By applying this simple box filter three times sequentially, the engine achieves a smooth, Gaussian-like curve at a fraction of the computational cost:&lt;br&gt;
$$\text{Standard Deviation} (\sigma) \approx r \cdot \frac{\sqrt{3}}{2}$$&lt;/p&gt;


&lt;h2&gt;
  
  
  2. The GPU Rendering Pipeline: Why Shadows are Expensive
&lt;/h2&gt;

&lt;p&gt;When a browser renders a page, it progresses through a strict pipeline: &lt;strong&gt;DOM/CSSOM ➜ Layout ➜ Paint ➜ Composite&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;Applying a &lt;code&gt;box-shadow&lt;/code&gt; directly impacts the &lt;strong&gt;Paint&lt;/strong&gt; and &lt;strong&gt;Composite&lt;/strong&gt; stages, making it one of the most computationally expensive CSS properties.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[DOM/CSSOM Changes] 
       │
       ▼
   [Layout] (Calculates geometry sizing)
       │
       ▼
   [Paint] (Rasterizes elements into bitmap layers) ──► [Convolutes Shadows via CPU/GPU]
       │
       ▼
 [Composite] (Layers blended together by GPU)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  The Cost of Rasterization
&lt;/h3&gt;

&lt;p&gt;Before an element is drawn to the screen, the rendering engine must rasterize it—converting vector instructions into pixel bitmaps. To draw a shadow, the engine:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Creates an alpha-mask copy of the element's border geometry.&lt;/li&gt;
&lt;li&gt;Expands the mask using the &lt;code&gt;spread-radius&lt;/code&gt; value.&lt;/li&gt;
&lt;li&gt;Applies the triple box blur convolution across the expanded mask.&lt;/li&gt;
&lt;li&gt;Colors the mask with your shadow color and draws it at the $(dx, dy)$ offset coordinates behind the element.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Because this blur calculation must run across a large sliding window of pixels, highly blurred, large shadows require significant memory bandwidth. If the shadow is applied to an element that triggers a repaint (such as during text input or hover states), the browser must recalculate this blur convolution on every single frame.&lt;/p&gt;




&lt;h2&gt;
  
  
  3. Optimizing Shadow Animations for the Compositor Thread
&lt;/h2&gt;

&lt;p&gt;Animating &lt;code&gt;box-shadow&lt;/code&gt; directly (e.g., changing the blur or offset on hover) is a common web performance bottleneck. It forces the browser to re-rasterize and repaint the shadow layer on the main thread for every frame of the transition, causing visible frame drops on mobile devices and low-spec hardware.&lt;/p&gt;

&lt;p&gt;To achieve fluid, 60fps animations, you must bypass the &lt;strong&gt;Paint&lt;/strong&gt; stage and offload the animation entirely to the GPU's &lt;strong&gt;Compositor Thread&lt;/strong&gt;, which only handles layers that are already painted.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Optimization: Layer Opacity Blending
&lt;/h3&gt;

&lt;p&gt;Instead of transition-animating the &lt;code&gt;box-shadow&lt;/code&gt; property itself, you can paint two static layers and transition the &lt;code&gt;opacity&lt;/code&gt; of the top layer instead. The GPU can blend layer opacities extremely fast without triggering a repaint.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="c"&gt;/* Optimized Depth Animation */&lt;/span&gt;
&lt;span class="nc"&gt;.card&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;position&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;relative&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#ffffff&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;/* Base Shadow Layer (Low Elevation) */&lt;/span&gt;
&lt;span class="nc"&gt;.card&lt;/span&gt;&lt;span class="nd"&gt;::before&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;''&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;position&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;absolute&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;top&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;left&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;right&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;bottom&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;border-radius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;8px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;box-shadow&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="m"&gt;2px&lt;/span&gt; &lt;span class="m"&gt;4px&lt;/span&gt; &lt;span class="n"&gt;rgba&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0.1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nl"&gt;transition&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;opacity&lt;/span&gt; &lt;span class="m"&gt;0.3s&lt;/span&gt; &lt;span class="n"&gt;ease&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;/* Hover Shadow Layer (High Elevation) */&lt;/span&gt;
&lt;span class="nc"&gt;.card&lt;/span&gt;&lt;span class="nd"&gt;::after&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;''&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;position&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;absolute&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;top&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;left&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;right&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;bottom&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;border-radius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;8px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;box-shadow&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="m"&gt;15px&lt;/span&gt; &lt;span class="m"&gt;30px&lt;/span&gt; &lt;span class="n"&gt;rgba&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0.15&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nl"&gt;opacity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c"&gt;/* Hidden by default */&lt;/span&gt;
  &lt;span class="nl"&gt;transition&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;opacity&lt;/span&gt; &lt;span class="m"&gt;0.3s&lt;/span&gt; &lt;span class="n"&gt;ease&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;/* GPU-accelerated transition */&lt;/span&gt;
&lt;span class="nc"&gt;.card&lt;/span&gt;&lt;span class="nd"&gt;:hover::after&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;opacity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By utilizing pseudo-elements, the browser pre-rasterizes both shadow states once. On hover, the GPU simply adjusts the alpha opacity blend between the two static layer bitmaps, avoiding any expensive on-the-fly blur convolutions.&lt;/p&gt;




&lt;h2&gt;
  
  
  4. Secure, Local-First UI Development
&lt;/h2&gt;

&lt;p&gt;When prototyping UI depth and shadow levels, front-end developers regularly enter strict design palette values and system specifications. Sending these styling layouts or design tokens to third-party, server-dependent generators poses corporate data privacy risks.&lt;/p&gt;

&lt;p&gt;We developed our &lt;strong&gt;CSS Box Shadow Generator&lt;/strong&gt; to run entirely client-side. By utilizing local browser memory (RAM) to parse and render vector dimensions, your styling configurations never traverse the network, keeping your interface design tokens secure.&lt;/p&gt;

&lt;p&gt;Prototyping soft shadows, flat offsets, or inset depths can be performed with absolute local security.&lt;/p&gt;

&lt;p&gt;Try the tool: &lt;a href="https://tools.kandz.me/box-shadow" rel="noopener noreferrer"&gt;CSS Box Shadow Generator - Kandz.me&lt;/a&gt;&lt;/p&gt;

</description>
      <category>css</category>
      <category>webdev</category>
      <category>performance</category>
      <category>design</category>
    </item>
    <item>
      <title>Demystifying LLM Tokenizers: Building a Client-Side Token and API Cost Calculator</title>
      <dc:creator>kandz</dc:creator>
      <pubDate>Sun, 19 Jul 2026 11:08:14 +0000</pubDate>
      <link>https://dev.to/kandz/demystifying-llm-tokenizers-building-a-client-side-token-and-api-cost-calculator-56pn</link>
      <guid>https://dev.to/kandz/demystifying-llm-tokenizers-building-a-client-side-token-and-api-cost-calculator-56pn</guid>
      <description>&lt;p&gt;If you are building applications with large language models (LLMs) like OpenAI's GPT-4o, Anthropic's Claude 3.5, or Google's Gemini 1.5, you quickly realize that &lt;strong&gt;LLMs do not read words.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Instead, they process text in chunks called &lt;strong&gt;tokens&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;Because LLM providers charge you on a pay-per-token basis (split between input and output tokens), keeping a precise, real-time audit of your prompt tokenization is vital to prevent development budgets from ballooning.&lt;/p&gt;

&lt;p&gt;Here is how tokenization works under the hood, the rule-of-thumb mathematics behind prompt cost estimation, and how to build a 100% private, client-side tokenizer calculator in your browser.&lt;/p&gt;




&lt;h3&gt;
  
  
  What is a Token?
&lt;/h3&gt;

&lt;p&gt;In natural language processing (NLP), &lt;strong&gt;tokens&lt;/strong&gt; are the basic atomic units of text parsed by the model's neural network. &lt;/p&gt;

&lt;p&gt;Instead of splitting text by letters (too slow and lacking semantic meaning) or by complete words (too many unique words to map in a vocabulary), modern LLMs use an algorithm called &lt;strong&gt;Byte Pair Encoding (BPE)&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;BPE splits words into common sub-word fragments. For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  The word &lt;code&gt;"unbelievable"&lt;/code&gt; might be tokenized into three parts: &lt;code&gt;["un", "believ", "able"]&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;  Highly common short words (like &lt;code&gt;"the"&lt;/code&gt; or &lt;code&gt;"and"&lt;/code&gt;) typically count as a single token.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  The Rule of Thumb Math:
&lt;/h4&gt;

&lt;p&gt;While exact tokenization depends on the specific encoder used (such as OpenAI's &lt;code&gt;cl100k_base&lt;/code&gt; or &lt;code&gt;o200k_base&lt;/code&gt;), statistical linguistic averages provide a highly reliable standard for English text:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;1 Token&lt;/strong&gt; $\approx$ &lt;strong&gt;4 characters&lt;/strong&gt; of text.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;1 Token&lt;/strong&gt; $\approx$ &lt;strong&gt;0.75 words&lt;/strong&gt; (or 100 words $\approx$ 133 tokens).&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  The Mathematics of API Cost Estimation
&lt;/h3&gt;

&lt;p&gt;To estimate the cost of an LLM completion request, you must evaluate input and output pricing separately, as providers charge significantly more for output generation (due to the autoregressive, sequential processing required to generate next-tokens).&lt;/p&gt;

&lt;p&gt;The mathematical model is formulated as:&lt;/p&gt;

&lt;p&gt;$$\text{Total Cost} = \left(\frac{\text{Input Tokens}}{1,000,000} \times \text{Input Price per 1M}\right) + \left(\frac{\text{Output Tokens}}{1,000,000} \times \text{Output Price per 1M}\right)$$&lt;/p&gt;

&lt;p&gt;For example, if you run a prompt containing 10,000 input tokens and generate 2,000 output tokens on a model priced at $2.50/1M input and $10.00/1M output (like GPT-4o):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Input Cost: $(10,000 / 1,000,000) \times \$2.50 = \$0.025$&lt;/li&gt;
&lt;li&gt;  Output Cost: $(2,000 / 1,000,000) \times \$10.00 = \$0.020$&lt;/li&gt;
&lt;li&gt;  Total Cost: $\$0.025 + \$0.020 = \$0.045$&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Estimating Tokens in Client-Side JavaScript
&lt;/h3&gt;

&lt;p&gt;While fully-featured libraries like &lt;code&gt;tiktoken&lt;/code&gt; exist, importing large WASM-compiled dictionaries into a lightweight web page is heavy. For a rapid, zero-dependency client-side estimate, we can write an optimized BPE-approximation parser:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;estimateTokens&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="c1"&gt;// 1. Clean and normalize spaces&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;cleaned&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;trim&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;\s&lt;/span&gt;&lt;span class="sr"&gt;+/g&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt; &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;cleaned&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="c1"&gt;// 2. Count words and characters&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;words&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;cleaned&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt; &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;charCount&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;cleaned&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="c1"&gt;// 3. Apply standard weighted regression&lt;/span&gt;
  &lt;span class="c1"&gt;// Each space is 1 token. Alphanumeric blocks average 4 characters.&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;wordTokens&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;words&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;1.33&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;charTokens&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;charCount&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mf"&gt;4.0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="c1"&gt;// Take the mathematical average of both estimates for high-tolerance accuracy&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ceil&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;wordTokens&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;charTokens&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Example usage:&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;prompt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Please format this dataset into a clean JSON array.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;estimateTokens&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt; &lt;span class="c1"&gt;// Estimates ~13 tokens&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Why Client-Side Privacy is Vital for Prompt Auditing
&lt;/h3&gt;

&lt;p&gt;When developing software, engineers routinely paste their active system instructions, proprietary source code, database schemas, or raw user drafts into online token counters to check costs. &lt;/p&gt;

&lt;p&gt;Pasting these private drafts into server-logged public calculators is a major security risk. It exposes your intellectual property, system designs, or client data to external databases.&lt;/p&gt;

&lt;p&gt;At &lt;strong&gt;KandZ Tools&lt;/strong&gt;, we enforce a strict &lt;strong&gt;100% Client-Side Privacy Law&lt;/strong&gt;. Your prompt drafts, tokenizations, and pricing models are calculated exclusively inside your browser's temporary memory (RAM). No data is ever transmitted to external servers, keeping your system architectures completely confidential.&lt;/p&gt;

&lt;p&gt;Audit your AI development budgets privately: &lt;a href="https://tools.kandz.me/ai-cost-calculator" rel="noopener noreferrer"&gt;https://tools.kandz.me/ai-cost-calculator&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>javascript</category>
      <category>webdev</category>
      <category>devops</category>
    </item>
  </channel>
</rss>
