<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:media="http://search.yahoo.com/mrss/"><channel><title><![CDATA[Coding right]]></title><description><![CDATA[Software engineering is not all about coding]]></description><link>http://blog.cemsoyding.com/</link><image><url>http://blog.cemsoyding.com/favicon.png</url><title>Coding right</title><link>http://blog.cemsoyding.com/</link></image><generator>Ghost 5.67</generator><lastBuildDate>Fri, 13 Feb 2026 17:25:35 GMT</lastBuildDate><atom:link href="http://blog.cemsoyding.com/rss/" rel="self" type="application/rss+xml"/><ttl>60</ttl><item><title><![CDATA[Git: custom command with powershell]]></title><description><![CDATA[<p>One of the most annoying thing that I have to do every once in a while is to clean up all the dead references in my git repositories. When the branches get integrated through PRs, they have no reason to continue living on my computer. We have configured Azure DevOps</p>]]></description><link>http://blog.cemsoyding.com/git-custom-command-with-powershell/</link><guid isPermaLink="false">67a1bf857fd5a700014ab288</guid><dc:creator><![CDATA[Cem Soyding]]></dc:creator><pubDate>Tue, 04 Feb 2025 07:33:35 GMT</pubDate><content:encoded><![CDATA[<p>One of the most annoying thing that I have to do every once in a while is to clean up all the dead references in my git repositories. When the branches get integrated through PRs, they have no reason to continue living on my computer. We have configured Azure DevOps to automatically delete the merged branch on the remote server but we still have them locally on our computers.</p><p>I have addressed the issue by creating my own git subcommand: `git putz`. </p><p>For the record, `putz` means cleaning in german. It is a short and fun name for this operation ^^</p><ol><li>Create a script and save it somewhere in your path</li></ol><p>I have picked powershell because my workstation runs on Windows. The same can be achieved with other script languages.</p><pre><code class="language-powershell"># Script to delete merged, obsolete, and untracked git branches

# Fetch latest changes from remote and prune references
Write-Host &quot;Fetching latest changes and pruning references...&quot; -ForegroundColor Yellow
git fetch --prune

# Get current branch
$currentBranch = git rev-parse --abbrev-ref HEAD

# Get list of merged branches (excluding main, master, and develop)
$mergedBranches = git branch --merged |
    Where-Object { $_.Trim() -notmatch &apos;^(\*|\s*(master|main|dev)$)&apos; } |
    ForEach-Object { $_.Trim() }

# Get list of branches where the remote is gone
$goneBranches = git branch -v |
    Where-Object { $_ -match &apos;\[gone\]&apos; } |
    ForEach-Object { $_.Split()[0] } |
    Where-Object { $_ -notmatch &apos;^(\*|\s*(master|main|dev)$)&apos; }

# Get list of local branches with no upstream tracking branch
$untrackedBranches = git branch -vv | 
    Where-Object { $_ -notmatch &apos;\[.+\]&apos; } |
    ForEach-Object { 
        if ($_ -match &apos;^\*?\s*(\S+)&apos;) {
            $matches[1]
        }
    } |
    Where-Object { $_ -notmatch &apos;^(master|main|dev)$&apos; -and $_ -ne $currentBranch }

if ($mergedBranches.Count -eq 0 -and $goneBranches.Count -eq 0 -and $untrackedBranches.Count -eq 0) {
    Write-Host &quot;No branches to clean up!&quot; -ForegroundColor Green
    exit 0
}

# Display branches to be deleted
Write-Host &quot;`nThe following branches will be deleted:&quot; -ForegroundColor Yellow

if ($mergedBranches.Count -gt 0) {
    Write-Host &quot;`nMerged branches:&quot; -ForegroundColor Cyan
    $mergedBranches | ForEach-Object { Write-Host &quot;  - $_&quot; }
}

if ($goneBranches.Count -gt 0) {
    Write-Host &quot;`nBranches with gone remotes:&quot; -ForegroundColor Cyan
    $goneBranches | ForEach-Object { Write-Host &quot;  - $_&quot; }
}

if ($untrackedBranches.Count -gt 0) {
    Write-Host &quot;`nLocal branches with no upstream:&quot; -ForegroundColor Cyan
    $untrackedBranches | ForEach-Object { Write-Host &quot;  - $_&quot; }
}

# Prompt for confirmation
Write-Host &quot;`nDo you want to proceed with deletion? (Y/N)&quot; -ForegroundColor Yellow
$confirmation = Read-Host

if ($confirmation -eq &apos;Y&apos; -or $confirmation -eq &apos;y&apos;) {
    # Delete merged branches
    foreach ($branch in $mergedBranches) {
        Write-Host &quot;Deleting merged branch: $branch&quot; -ForegroundColor Cyan
        git branch -d $branch
    }

    # Delete gone branches
    foreach ($branch in $goneBranches) {
        Write-Host &quot;Deleting gone branch: $branch&quot; -ForegroundColor Cyan
        git branch -D $branch
    }

    # Delete untracked branches
    foreach ($branch in $untrackedBranches) {
        Write-Host &quot;Deleting untracked branch: $branch&quot; -ForegroundColor Cyan
        git branch -D $branch
    }

    Write-Host &quot;`nBranch cleanup completed!&quot; -ForegroundColor Green
} else {
    Write-Host &quot;`nOperation cancelled.&quot; -ForegroundColor Yellow
}</code></pre><p>The script lists merged, gone and untracked branches, asks for confirmation and deletes theme all at once. What a relief !</p><p>2. Create an alias for git</p><p>Simply run the following command by making sure to fix the script path:</p><pre><code class="language-sh">git config --global alias.putz &quot;!powershell.exe -File C:/Tools/git_delete_gone_branches.ps1&quot;</code></pre><p>That&apos;s it, now run `git putz`:</p><pre><code>The following branches will be deleted:

Local branches with no upstream:
  - feature/cnc_auto_reset_manual
  - features/architecture_updates
  - features/barrier_crossed_guard
  - features/blazor_server
  - features/cnc_wait_resilience
  - features/dummy_branch
  - features/dummy_to_merge
  - features/emergency_ack
  ...
  
Do you want to proceed with deletion? (Y/N)
Y
Deleting untracked branch: feature/cnc_auto_reset_manual
Deleted branch feature/cnc_auto_reset_manual (was 81a3233d7).
Deleting untracked branch: features/architecture_updates
Deleted branch features/architecture_updates (was 6ccd947b9).
Deleting untracked branch: features/barrier_crossed_guard
Deleted branch features/barrier_crossed_guard (was 3a1e85cef).
Deleting untracked branch: features/blazor_server
Deleted branch features/blazor_server (was dec07d9be).
...

Branch cleanup completed!</code></pre>]]></content:encoded></item><item><title><![CDATA[CSS: Alignment tips]]></title><description><![CDATA[<h2></h2><h3 id="alignment">Alignment</h3><p>Now that we&apos;ve covered the most common CSS properties, here is a summary to how to center an element.</p><h4 id="text-align">text-align</h4><p>Text inside block level elements can be aligned with <code>text-align</code>.</p><pre><code class="language-css">h1 {
   /* Possible values are : left, right, center, justified*/
   text-align: center; 
}
</code></pre><h4 id="margin">margin</h4><p>Another common technique for center alignement</p>]]></description><link>http://blog.cemsoyding.com/css-tips/</link><guid isPermaLink="false">658566933ba3c80001cddb5d</guid><dc:creator><![CDATA[Cem Soyding]]></dc:creator><pubDate>Fri, 12 Jan 2024 10:46:40 GMT</pubDate><media:content url="http://blog.cemsoyding.com/content/images/2023/12/css-5.png" medium="image"/><content:encoded><![CDATA[<h2></h2><h3 id="alignment">Alignment</h3><img src="http://blog.cemsoyding.com/content/images/2023/12/css-5.png" alt="CSS: Alignment tips"><p>Now that we&apos;ve covered the most common CSS properties, here is a summary to how to center an element.</p><h4 id="text-align">text-align</h4><p>Text inside block level elements can be aligned with <code>text-align</code>.</p><pre><code class="language-css">h1 {
   /* Possible values are : left, right, center, justified*/
   text-align: center; 
}
</code></pre><h4 id="margin">margin</h4><p>Another common technique for center alignement in block level elements is to use <code>margin: 0 auto</code>, as explained in <a>Margins</a> chapter.</p><h4 id="position">position</h4><p>To align an element with respect to the viewport or its containing element, you can use <code>absolute</code> position with <code>left</code>, <code>right</code>, <code>top</code>, <code>bottom</code> properties. See <a>Positionning</a> chapter.</p><h4 id="float">float</h4><p>You can align an element left or right inside its container with <code>float:left</code> (or right). See <a>Float</a> chapter.</p>]]></content:encoded></item><item><title><![CDATA[CSS: Elements styling]]></title><description><![CDATA[<p>Here are some element-specific styling properties that you will necessarily use at some point.</p><h3 id="text">Text</h3><pre><code class="language-css">h2 {
    /* Text color */
    color: #5470f0;
    /* Horizontal alignment (left, right, center, justified).
     * &apos;justify&apos; stretches each line so that they all have equal width
     * except for the last one. */
    text-align: center;
    /* Add a line under,</code></pre>]]></description><link>http://blog.cemsoyding.com/css-elements-styling/</link><guid isPermaLink="false">6585661d3ba3c80001cddb4d</guid><dc:creator><![CDATA[Cem Soyding]]></dc:creator><pubDate>Mon, 08 Jan 2024 10:45:36 GMT</pubDate><media:content url="http://blog.cemsoyding.com/content/images/2023/12/css-4.png" medium="image"/><content:encoded><![CDATA[<img src="http://blog.cemsoyding.com/content/images/2023/12/css-4.png" alt="CSS: Elements styling"><p>Here are some element-specific styling properties that you will necessarily use at some point.</p><h3 id="text">Text</h3><pre><code class="language-css">h2 {
    /* Text color */
    color: #5470f0;
    /* Horizontal alignment (left, right, center, justified).
     * &apos;justify&apos; stretches each line so that they all have equal width
     * except for the last one. */
    text-align: center;
    /* Add a line under, on or on top of the text (underline, line-through, overline, none).
    *  Tip: used &apos;none&apos; with &apos;a&apos; to remove the default underline for links*/
    text-decoration: 14px;
    /* Set the case (uppercase, lowercase, capitalize.
     * &apos;capitalize&apos; sets the first letter of each word to uppercase */
    text-transform: uppercase;
    /* Indent the first line or a paragraph (%, px or any length value) */
    text-indent: 10px;
    /* Customize space between characters (px or any length value)*/
    letter-spacing: -3px;
    /* Customize space between words (px or any length value)
     * Note: If alignment is set to &apos;justify&apos;, word-spacing is affected. */
    word-spacing: 2px;
    /* Set inter-lines spacing (%, px or any length value) */
    line-height: 1.2; /* when setting a number, you set a ratio of the font size */

    /** CSS3 **/

    /* Configure how overflowing text (e.g. container too small) should be rendered.
     * &apos;clip&apos;: overflowing text is clipped and becomes invisible
     * &apos;ellipsis&apos;: displays &apos;...&apos; at the end of the line
     * string value: displays the provided string value at the end of the line */
     text-overflow: ellipsis;
     /* Define wether the long words at the end of the line should overflow (&apos;normal&apos;) or be wrapped 
      * onto next line (&apos;break-word&apos;) */
     word-wrap: break-word;
     /* Define how words with &apos;-&apos; character should be displayed when they are too long for the line.
      * &apos;break-all&apos;: the entire word is wrapped onto next line
      * &apos;keep-all&apos;: the word is cut on &apos;-&apos; character and the non-fitting part is wrapped */
     word-break: keep-all;
}
</code></pre><h3 id="links">Links</h3><p>The default rendering of links can be easily edited thanks to <em>pseudo-class selectors</em> fo <code>a</code>:</p><ul><li><code>:link</code>: univisted link</li><li><code>:visited</code>: visited link</li><li><code>:hover</code>: mouse over link</li><li><code>:active</code>: active link</li></ul><pre><code class="language-css">a:link {    /* unvisited link */
    color: #ff0000;
    text-decoration: none;
    border-bottom: 1px solid;
}
a:visited {    /* visited link */
    color: #ff00ff;
}
a:hover {    /* mouse over link */
    color: #00ff00;
    border-bottom: none;
}
a:active {    /* active link */
    color: #00ffff;
}
</code></pre><h3 id="lists">Lists</h3><p>The following styles apply to all types of list (<code>ul</code>, <code>ol</code>, <code>dl</code>).</p><pre><code class="language-css">/* The next styles could also be applied to &apos;ul li&apos; */
ul {
    /* Change default marker (bullet or number) type.
     * (disc (default), circle, square, upper-roman, lower-latin,...) 
     https://developer.mozilla.org/fr/docs/Web/CSS/list-style-type#disc
     */
    list-style-type: square;
    /* Set the position of the marker to be inside text boxes or 
     * outside (default) */
    list-style-position: inside;
    /* Use an external image for the bullet */
    list-style-image: url(&quot;images/bullet.png&quot;);
}
</code></pre><h4 id="shorthand">Shorthand</h4><p>A less verbose property can be used to set all properties at once.</p><pre><code class="language-css">ul  {
    /* Shorthand notation: type position image */
    list-style: square inside url(&quot;images/bullet.png&quot;);
}
</code></pre><h3 id="tables">Tables</h3><p>By default, tables are rendering without borders. CSS offers several styling enhancements.</p><pre><code class="language-css">table, th, td {
    /* Define border : thickness type color */
    border: 1px solid black;
    /* Since each table element (table, th, td) has its own border
     * you get duplicated lines by simply setting a border. You can
     * collapse these lines so that there is no duplication anymore
     * with this option. Values are &apos;collapse&apos; and &apos;separate&apos; (default) */
    border-collapse: collapse;
    /* Only applicable if collapse is set to &apos;separate&apos;, this property
     * sets the space between the borders of the cells. In other conditions
     * simply use the &apos;padding&apos; property */
    border-spacing: 10px;
    /* Only applicable if collapse is set to &apos;separate&apos;, this property
     * configure the behavior of the view with empty cells. By default
     * their border is drawn (show) but it can be hidden (hide) */
    empty-cells: hide;
    /* By default, the table will adapt the column width to their content.
     * You can override this behavior by telling it to distribute the space
     * evenly among columns for a fixed size. 
     * Values: auto (default), fixed (limited but faster rendering) */
    table-layout: fixed;
    width: 400px;
    /* Set horizontal text alignment in rows.
     * By default, td is left-aligned while th is centered */
    text-align: right;
    /* Set vertical text alignment in rows.
     * By default, the alignment is middle. */
    vertical-align: bottom;
}
/* Zebra striped table. Every odd row of the table will have a darker
 * background color thanks to the pseudo-class slector &apos;nth-child.
 * Note that the style is only applied to rows of html5&apos;s tbody element
 * so that headers are not included */
tbody tr:nth-child(odd) {
    background-color: #f2f2f2;
}
caption {
    /* Positionning of the caption (top, bottom).
     * Use text-align to align left or right.*/
    caption-side: bottom;
}
</code></pre><h4 id="responsiveness">Responsiveness</h4><p>By default, tables are not responsive. To add scrolling support, you need to wrap the table in a <code>div</code> and apply the style <code>overflow-x: auto</code> to it as shown below.</p><pre><code class="language-html">&lt;div style=&quot;overflow-x: auto;&quot;&gt; 
    &lt;table&gt;
        ... table content ...
    &lt;/table&gt;
&lt;/div&gt;
</code></pre><h3 id="cursors">Cursors</h3><p>The cursor is the mouse pointer displayed when you navigate through a website. Many html elements define their own, such as links or inputs, which is why the cursors changes when you hover them. With <code>cursor</code> you can change the displayed cursor or define your own with <code>.cur</code> (default standard), <code>.gif</code>, <code>.png</code> or <code>.jpg</code> images (in recent browsers only).</p><pre><code class="language-css">a {
    /* There are many built-in cursors (default, pointer, text, wait, progress, crosshair, move,...)
     * and you can also use images to display custom ones.
     * When you select several cursors, make sure to set a valid one at the end so that there is 
     * always a valid fallback value */
    cursor: url(&quot;custom.gif&quot;), crosshair;
}
</code></pre><h3 id="overflow">Overflow</h3><p><code>overflow</code> (and <code>overflow-x</code>, <code>overflow-y</code>) define how the content of an element should be displayed when it is bigger than its content area (e.g. when <code>height</code> and <code>width</code> are too small).</p><pre><code class="language-css">div {
    height: 50px;
    width: 100px;
    /* Define how the value will be rendered.
     * &apos;visible&apos; (default) : content rendered outside of its box and overlaps other elements
     * &apos;hidden&apos;: content clipped and extra data not visible
     * &apos;scroll&apos;: content clipped but scrollbars let see the hidden parts
     * &apos;auto&apos;: scrollbars are created if content is too big */
    overflow: auto;
}
</code></pre>]]></content:encoded></item><item><title><![CDATA[CSS: Effects]]></title><description><![CDATA[<p></p><h2 id="effects">Effects</h2><h3 id="color">Color</h3><p><code>color</code> property defines the foreground color of an element (in general). It is generally used for text but could also apply to borders or outlines for instance when their respective <code>border-color</code> or <code>outline-color</code> hasn&apos;t been specified.</p><pre><code class="language-css">h1 {
    color: #4457ff;
}
</code></pre><p><code>color</code> is automatically inherited by child elements,</p>]]></description><link>http://blog.cemsoyding.com/css-effects/</link><guid isPermaLink="false">6585658e3ba3c80001cddb3d</guid><dc:creator><![CDATA[Cem Soyding]]></dc:creator><pubDate>Fri, 05 Jan 2024 10:42:20 GMT</pubDate><media:content url="http://blog.cemsoyding.com/content/images/2023/12/css-3.png" medium="image"/><content:encoded><![CDATA[<img src="http://blog.cemsoyding.com/content/images/2023/12/css-3.png" alt="CSS: Effects"><p></p><h2 id="effects">Effects</h2><h3 id="color">Color</h3><p><code>color</code> property defines the foreground color of an element (in general). It is generally used for text but could also apply to borders or outlines for instance when their respective <code>border-color</code> or <code>outline-color</code> hasn&apos;t been specified.</p><pre><code class="language-css">h1 {
    color: #4457ff;
}
</code></pre><p><code>color</code> is automatically inherited by child elements, except for <code>&lt;a&gt;</code> elements.</p><p>A color value can be defined in various formats:</p><ul><li>color keyword: <code>red</code>, <code>blue</code>, <code>purple</code>, ... (full list <a href="https://www.tutorialrepublic.com/css-reference/css-color-names.php?ref=blog.cemsoyding.com">here</a>)</li><li>hex value: <code>#FFAB01</code> (or shorthand notation <code>#ffcc00</code> same as <code>#fc0</code>)</li><li>rgb value: <code>rgb(255, 0, 2)</code> or <code>rgb(50%, 0%, 5%)</code></li><li>[CSS3] rgba (see below)</li><li>[CSS3] hsl (or hue, saturation and lightness) or hsla (same as <code>rgba</code> but for hsl)</li></ul><h4 id="transparency">Transparency</h4><p>CSS3 has introduced a new way to specify a color with transparency with <code>rgba</code>.</p><pre><code class="language-css">div {
    /* the alpha parameter here controls the the transparency from 0 (transparent) to 1 (opaque) */
    background: rgba(10, 200, 100, 0.5);
}
</code></pre><p>CSS3 has also introduced <code>opacity</code> to control the transparency of any element in the page.</p><pre><code class="language-css">img.choice {
    /* Value between 0 (transparent) to 1 (opaque) */
    opacity: 0.6;
}
</code></pre><p>Note that the transparency applied with <code>rgba</code> does not affect child elements whereas using <code>opacity</code> does.</p><h4 id="gradients">Gradients</h4><p>CSS3 introduced an easy solution to generate smooth gradients of colors.</p><pre><code class="language-css">body {
    /* Top to bottom color gradient */
    background: linear-gradient(blue, green);
    /* Left to right color gradient */
    background: linear-gradient(to right, blue, green); /* or with angle: (90deg, blue, green)
    /* Diagonal color gradient */
    background: linear-gradient(to top right, blue, green);
    /* Top to bottom gradient with more colors */
    background: linear-gradient(blue, green, yellow);
    /* Top to bottom gradient with positionnal colors stops */
    background: linear-gradient(blue, green 25%, yellow 70%);
}
</code></pre><p>You can also repeat a gradient with <code>repeating-linear-gradient</code> (same syntax) or use <code>radial-gradient</code> for concentric gradients.</p><h3 id="background">Background</h3><p>CSS has several properties to style the background of an element.</p><pre><code class="language-css">body {
    /* Set the background color of an element.
     * The definition of the color value respects the rules as for `color` property.
     * As opposed to `color`, `background-color` is not inherited by child elements 
     * but since the default value is `transparent`, the parent&apos;s background color will 
     * still be visible by default. */
    background-color: #4457ff;
    /* Set an image as a background of an HTML element. 
     * Several additional properties are available to tune the rendering (see below) */
    background-image: url(&quot;images/tile.png&quot;);
    /* By default, the image is repeated horizontally and vertically to fill the entire 
     * area of an element. `background-repeat` lets you change this behavior.
     * `repeat` (default) : repeats on x and y
     * `repeat-x` (default) : repeats on x only
     * `repeat-y` (default) : repeats on y only
     * `no-repeat` (default) : no repeat, a single image is displayed and doesn&apos;t fill the page (unless big enough) */
    background-repeat: no-repeat;
    /* By default, the image is displayed at coordinates (0,0). With `background-position` 
     * you can set another location. The position is defined with 2 values : first for horizontal, 
     * second for vertical. The values can be expressed with keywords (`left|right|top|bottom`), 
     * percents (`10% 0;`) or any length value (`px`, `em`, ...). */
    background-position: right top;
    /* Determines whether the image is fixed with regard to the viewport or scrolls along the containing block. */
    background-attachment: fixed;

    /** CSS3 **/

    /* Adjust the size of the background image.
     * &apos;contain&apos;: scale as large as possible by keeping original image ratio
     * &apos;cover&apos;: scale to the smallest possible size to fill the container (with repeat) by keeping
     *          original image ratio
     * &apos;auto&apos;: scales automatically by keeping original image ratio
     * &lt;length value or percentage&gt;: stretches the width of the image (height becomes auto)
     * &lt;2 length values or 2 persentages&gt; : stretches the width and the length of the image */
    background-size: 1.5em;

    /* Delimitates where the background is applied in the Box Model
     * &apos;border-box&apos; : applies to all layers of the Box Model (except margin)
     * &apos;padding-box&apos; : applies to content area and padding layers (border is excluded)
     * &apos;content-box&apos; : applies to content area (padding and border are excluded) */
    background-clip: content-box;

    /* Define where the image origin (x:0, y:0) should be positionned in the Box Model.
     * Values are identical to &apos;background-clip&apos; (border-box, padding-box and content-box) */
    background-origin: border-box;
}
</code></pre><h4 id="shorthand">Shorthand</h4><p>Since adding every <code>background-</code> property to the CSS is verbose, you have the option to use the shorthand notation:</p><pre><code class="language-css">/* background: color image repeat attachment position; */
body {
    background: #f0e68c url(&quot;images/smiley.png&quot;) no-repeat fixed 250px 25px;

    /** CSS3 **/

    /* Use layering to display images on top of each others to compose the
     * background image. You can have as many layers as you like. */
    
    background: url(&quot;images/cheese.png&quot;) no-repeat center, /* top layer */
                url(&quot;images/ham.png&quot;) no-repeat center,
                url(&quot;images/sauce.png&quot;) no-repeat center,
                url(&quot;images/dough.png&quot;) no-repeat center, /* bottom layer */
                lightblue; /* background color */
}
</code></pre><h3 id="fonts">Fonts</h3><p>CSS provides several properties to set a font.</p><pre><code class="language-css">body {
    /* Select the font and specify fallback fonts with &apos;,&apos; */
    font-family: Arial, Helvetica, &quot;Times New Roman&quot;, sans-serif;
    /* Define if the text should be normal, italic or oblique 
    * &apos;italic&apos; uses an italic version of the font whereas &apos;oblique&apos; 
    * skews the &apos;normal&apos; font*/
    font-style: italic;
    /* Set font size with pixels, percents, any length value (&apos;px&apos;, &apos;em&apos;,..), 
       special keywords (xx-small, x-small, small, medium, large, x-large, xx-large)
       or viewport units &apos;vw&apos;, &apos;vh&apos;.
       It is recommended to use percents or &apos;em&apos; */
    font-size: 14px;
    /* Set he boldness of the font with either keywords (normal, bold, bolder,
     * lighter) or numeric values (100-900) */
    font-weight: 400; /* same as &apos;normal&apos; */
    /* Pick the small caps variation where the lowecase characters are displayed
     * as smaller versions of the corresponding upper case characters */
    font-variant: small-caps;
}
</code></pre><h4 id="font-size-techniques">Font size techniques</h4><p><code>em</code> is a unit relative to the parent element. <code>1em</code> equals to the font size defined in the parent&apos;s element, <code>2em</code> is two times the parent&apos;s font size and so on.<br>CSS3 introduced <code>rem</code> which is a unit relative to the root element (<code>&lt;html&gt;</code>). A popular technique mixes percents and <code>rem</code> to easily convert <code>em</code> to pixels.</p><pre><code class="language-css">html {
    /* The default font-size is 16 px */
    font-size: 62.5%;    /* font-size becomes 10px (1rem) */
}
/* remaining sizes are then easy to convert */
p {
    font-size: 1.4rem;    /* 1.4rem = 14px */
}
p span {
    font-size: 2rem;    /* 2rem = 20px (not 28px) */
}
</code></pre><h3 id="shadows">Shadows</h3><h4 id="box-shadow">Box shadow</h4><p>With CSS3 you have a simple syntax to add one (or multiple, comma-separated) shadows to your box.</p><pre><code class="language-css">div {
    /* Add a shadow under the div, shifed by x=7px and y=8px, with a blur radius of 10px
     * in gray. The syntax is &lt;offset x&gt; &lt;offset y&gt; &lt;blur radius&gt; &lt;color&gt;.
     * Blur radius defines how sharp the edges of the shadow are. The higher, the smoother. */
    box-shadow: 7px 8px 10px gray;
}
</code></pre><h4 id="text-shadow">Text shadow</h4><p>On the same principle, you can also add a shadow on a text.</p><pre><code class="language-css">h3 {
    /* Same syntax as &apos;box-shadow&apos; */
    text-shadow: 7px 8px 10px blue;
}
</code></pre><h3 id="geometrical-transforms">Geometrical Transforms</h3><p>In CSS3, you can simply apply 2D or 3D effects on your elements, such as rotating, moving or skewing. The edited element will not occupy more space on the page as its <em>Box</em> will remain as if no effect was applied but it can overlap with its siblings.</p><pre><code class="language-css">h1 {
    /* Shift an element on X and Y axes.
     * If the second parameter (y) isn&apos;t specified, it is considered to be 0.
     * See also translateX and translateY */
    transform: translate(10px, 60px); 
    /* The 3d variant lets you specify a shift value along Z axis. However,
     * the effect on Z is only meaningful if it is combined with &apos;perspective&apos; or 
     * &apos;perspective-origin&apos; that modify the size of the element as it goes higher on Z.
     * See also translateZ. */
    transform: translate3d(10px, 60px, 60px); 
    /* Rotate an element around it origin.
     * Negative values are supported.
     * See also rotateX and rotate Y */
    transform: rotate(30deg); 
    /* The 3d variant accepts [x,y,z] vectors as inputs and an angle.
     * It rotates the element around the selected axes with the given magnitude and the specified angle 
     * See also rotateZ. */
    transform: rotate3d(0, 1, 2, 30deg); /* rotates 2x more on z axis than on y */
    /* Increase or decrease the size of an element proportionnally on x and y 
     * If the second parameter (y) isn&apos;t specified, it is considered to be 0.
     * See also scaleX and scaleY */
    transform: scale(1.2, 0.3);
    /* The 3d variant accepts [x,y,z] vectors as inputs. The scaling is applied with the 
     * provided magnitudes along each axis. 
     * See also scaleZ. */
    transform: scale3d(1, 4, 1);
    /* Skew the element along x and y yith the specified angle.
     * If the second parameter (y) isn&apos;t specified, it is considered to be 0.
     * See also skewX and skewY */
    transform: skew(10deg);
    /* And of course, you can chain several effect */
    transform: translate(10px, 60px) rotate(30deg) skew(10deg);
}
</code></pre><h3 id="transitions">Transitions</h3><p>In CSS3, <em>Transitions</em> allow you to add delays and effects when the styling of an element gets updated (usually triggered with user interaction). The result is that instead of seeing the visual appearance changing instantly, it will smoothly occur over a specified amount of time.</p><p>Any property with a value that is a number, length, percentage or color should be animatable.</p><pre><code class="language-css">button {
    background: pink;
    border-color: green;
    /* To apply a transition, you first need to select the properties for which
     * you want to add a transition. 
     * Note that we&apos;re using shorthand properties here which means that the transition will apply 
     * to all underlying css properties */
    transition-property: background, border;
    /* Then you need to set a duration for the transition (in seconds &apos;s&apos; or milliseconds &apos;ms&apos;)
     * Note that the coma separates the duration for each property 
     * specified above.*/
    transition-duration: 1s, 500ms;
    /* Optionnally, you can set a start delay so that the transition does not 
     * start immediately (in seconds &apos;s&apos; or milliseconds &apos;ms&apos;) */
    transition-delay: 0.1s, 0s;
    /* Optionnally, you can pick from different transition styles which differ in how
     * the value change is applied. By default, the transition is linear, meaning that the 
     * value changes gradually over time but you have several other options.
     * &apos;linear&apos; (default)
     * &apos;ease&apos;: value changes quickly at the beginning and slows down at the middle
     * &apos;ease-in&apos;: value changes slowly at the beginning and accelerates at the end
     * &apos;ease-out&apos;: value changes quickly at the beginning and slows down at the end
     * &apos;ease-in-out&apos;: value changes slowly at the beginning, accelerates at the middle and slows down at the end
     * &apos;cubci-bezier(n, n, n, n)&apos;: manual speed curve with values from 0 to 1 */
    transition-timing-function: ease-out;
}
button:hover {
    background: red;
    border-color: blue;
}
</code></pre><h4 id="shorthand-1">Shorthand</h4><p>All transition properties can be set at once with the shorthand notation.</p><pre><code class="language-css">button {
    /* Syntax is : property duration timing-function delay 
    * As usual, if a value is missing its default value is used instead. The default value
    * for &apos;property&apos; is &apos;all&apos;, meaning that all css properties will be affected */
    transition: background 1s ease-out 0.1s;
}
</code></pre><h3 id="animations">Animations</h3><p>Transitions are great for simple animations but when you need more granularity on <em>what property should change at a given moment in the transition</em>, <code>animation</code> offer all the flexibility you need. Animations consist of <code>@keyframes</code> which describe the style to apply at a given time of the animation.</p><pre><code class="language-css">h1 {
    /* Animations only apply to non-static positions */
    position: absolute;
    /* Each animation is identified with a name. You can see the declaration
     * of the animation further below */
    animation-name: moveright;
    /* Just like &apos;transitions&apos;, animation have a duration in &apos;s&apos; or &apos;ms&apos; */
    animation-duration: 3s;
    /* [Optional] Same as &apos;transition-timing-function */
    animation-timing-function: ease;
    /* [Optional] Same as &apos;transition-delay */
    animation-delay: 200ms;
    /* [Optional] Set the number of times the animation should play (each iteration 
     * will last for 3s here). Note that you could also use &apos;infinite&apos; so that the 
     * animation never ends */
    animation-iteration-count: 3;
    /* [Optional] If the number of iteration is superior to 1, the direction let you 
    * chose in which direction the animation should play.
    * &apos;normal&apos; (default)
    * &apos;reverse&apos;: starts at the end and ends at the beginning
    * &apos;alternate&apos;: plays forward on first cycle and reverse in second and continues alternating
    * &apos;alternate-reverse&apos;: same as alternate but in reverse order */
    animation-direction: alternate;
    /* [Optional] Specifies if the styles defined in the animation applies to the element 
    * before the beginning of the animation and/or after the end of the animation.
    * &apos;none&apos; (default)
    * &apos;forwards&apos;: The final style applied by the animation is persisted on the element. In this example,
    *             the text would stick to the right after third iteration.
    * &apos;backwards&apos;: The initial style of the animation is applied to the element before the animation starts
    *             (only visible if you&apos;ve set a delay)
    * &apos;both&apos;: combination of &apos;forwards&apos; and &apos;backwards&apos; */
    animation-fill-mode: none;
    /* [Optional] This is mostly for javascript as it lets you pause or run the animation 
    * Values: &apos;running&apos; (default) or &apos;paused&apos;: */
    animation-play-state: running;
}

/* An animation is an &apos;at-statement&apos; with entries describing the style 
 * at each step. In the example below, we use &apos;from&apos; and &apos;to&apos; for the beginning
 * and end states but you could have chosen to use percentage (0% and 100%) instead.
 * You get the idea, with percentage you can add additional moment (25%, 53%, ...)
 * and fine-tune your animation.
 * This animation will move the title from left to right for 3 seconds. The final position of the text
 * will be the one it occupies in the normal flow which means that here, the text will come back
 * to where it started.*/
@keyframes moveright {
    from { left: 0 };
    to { right: 60% }
}
</code></pre><h4 id="shorthand-2">Shorthand</h4><p>You can pass all properties at once for more consistency.</p><pre><code class="language-css">h1 {
    /* Syntax: name duration timing-function delay count direction */
    animation: moveright 3s ease 200ms 3 alternate;
}
</code></pre>]]></content:encoded></item><item><title><![CDATA[CSS: Layouts]]></title><description><![CDATA[<p></p><h2 id="layout">Layout</h2><p>Understanding the Box Model is not enough to have a clear vision of how CSS will style your page. Many other factors have an influence on the final rendering such as :</p><ul><li>display type of html element (block or inline)</li><li>positioning scheme (normal flow, float or absolute)</li><li>viewport size, image</li></ul>]]></description><link>http://blog.cemsoyding.com/css-layouts/</link><guid isPermaLink="false">658565263ba3c80001cddb31</guid><dc:creator><![CDATA[Cem Soyding]]></dc:creator><pubDate>Mon, 01 Jan 2024 10:40:43 GMT</pubDate><media:content url="http://blog.cemsoyding.com/content/images/2023/12/css-2.png" medium="image"/><content:encoded><![CDATA[<img src="http://blog.cemsoyding.com/content/images/2023/12/css-2.png" alt="CSS: Layouts"><p></p><h2 id="layout">Layout</h2><p>Understanding the Box Model is not enough to have a clear vision of how CSS will style your page. Many other factors have an influence on the final rendering such as :</p><ul><li>display type of html element (block or inline)</li><li>positioning scheme (normal flow, float or absolute)</li><li>viewport size, image dimensions, etc...</li></ul><h3 id="display">Display</h3><p>The default <code>display</code> property (block or inline) of html elements can be overriden in CSS stylesheet and heavily affects how the page is rendered. Here is what differs between each display type:</p><!--kg-card-begin: html--><table>
<thead>
<tr>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>inline</code></td>
<td>Element is displayed inline (no breaks). <code>width</code> and <code>height</code> properties have no effect. Instead it always occupies as much width as its content.</td>
</tr>
<tr>
<td><code>block</code></td>
<td>Element is displayed as a block (breaks at beginning and end). It takes up the full width available.</td>
</tr>
<tr>
<td><code>inline-block</code></td>
<td>Element is displayed <strong>inline as a block</strong> (no breaks). <code>width</code> and <code>height</code> are properly applied</td>
</tr>
<tr>
<td><code>flex</code></td>
<td>[CSS3] Element is displayed with a flexible <strong>block-level</strong> layout entirely built in CSS</td>
</tr>
<tr>
<td><code>inline-flex</code></td>
<td>[CSS3] Element is displayed with a flexible <strong>inline-block</strong> layout entirely built in CSS</td>
</tr>
<tr>
<td><code>none</code></td>
<td>The element does not appear because no box is generated for it (or its children). It simply does not exist.</td>
</tr>
</tbody>
</table><!--kg-card-end: html--><pre><code class="language-css">span {
    display: block; /* replaces default &apos;inline&apos; */
}
p {
    display: inline; /* replaces default &apos;block&apos; */
}
</code></pre><p>Make sure to always remember the html rules:</p><ul><li>an inline element can&apos;t have a child with a block display</li></ul><p>Changing the default display type of an element does not overrule that, you still won&apos;t be able to have block elements inside (orignally) inline elements.</p><h3 id="flexbox">Flexbox</h3><p>The <code>flexbox</code> properties introduced with CSS3 are quickly becoming the new standard for creating layouts without interfering with the html markup. It consists in having a flexible container (e.g. a <code>div</code>) that will hold <em>flex items</em>. To understand how they are rendered, it is important to visualize the spatial representation of a flexbox:</p><pre><code class="language-txt">         A flexbox can be represented in a 2D space but lays out items in 1 direction

                            Main axis 
        (oriented according to local writing direction)
                .-------------------------------------------&gt;
                | ---------------------------------------
                | |  Flex     ||  Flex     ||  Flex     |
    Cross axis  | |__Item 1___||__Item 2___||__Item 3___|
(orthogonal to  | 
Main axis)      | Each element inside a flex container automatically 
                |  becomes a flex item
                v
</code></pre><p>By default, flex items are displayed in a row along the flex line (the <em>Main axis</em>). The direction can however be modified with <code>flex-direction</code>:</p><ul><li><code>row</code> (default) : depending on local culture, from left to right</li><li><code>row-reverse</code> : opposite of <code>row</code></li><li><code>column</code> : same as <code>row</code> but top to bottom</li><li><code>column-reverse</code> : opposite of <code>column</code></li></ul><pre><code class="language-css">.container {
    display:flex;
}
.items {
    flex: 1;
}
</code></pre><p>With the code above, the items will be laid out on full width, sharing all the available space. This behavior can be modified with <code>flex-wrap</code>:</p><ul><li><code>nowrap</code> (default) : items fit in one line</li><li><code>wrap</code> : when there is no more space to display an item, it wraps onto next line. The first line is at the top and each new line is added under</li><li><code>wrap-reverse</code> : same as <code>wrap</code> but first line is at the bottom and each line gets added above</li></ul><p>Note that there is a shorthand to set direction and wrap at once:</p><pre><code class="language-css">.items {
    flex-flow: column wrap;
}
</code></pre><p>Speaking of shorthand notations, the <code>flex</code> property used in the first example is a shorthand for several properties:</p><ul><li><code>flex-grow</code>: specifies how much of the container&apos;s remaining space should be assigned to the item. When it is set to 1, the space is evenly shared by flex items. However, if 2 items have a value of 1 and a third has a value of 2, the total space is (1+1+2) 4 which means that the third item will occupy half of the container.</li><li><code>flex-basis</code>: initial main size of an item</li><li><code>flex-shrink</code>: it&apos;s the opposite of <code>flex-grow</code>. It gives a ratio factor indicating by how much the size of the item should be divided (if <code>0</code>, original size is used)</li></ul><p>but it is recommended to always use <code>flex</code> as it resets unspecified properties correctly.</p><pre><code class="language-css">/* As specified on mdn documentation, the meaning of flex properties varies depending on 
 * the units */

/* One value, unitless number: flex-grow */
flex: 2;

/* Two values: flex-grow | flex-basis */
flex: 1 30px;

/* Two values: flex-grow | flex-shrink */
flex: 2 2;

/* Three values: flex-grow | flex-shrink | flex-basis */
flex: 2 2 10%;
</code></pre><p><strong>Important</strong>: <code>float</code>, <code>clear</code>, <code>vertical-align</code> and <code>column</code> have no effect in flex containers.</p><p>Covering everything that it is possible to do with Flexbox in a single article is difficult. Besides, some great resources are hard to beat so I strongly recommend you to visit <a href="https://css-tricks.com/snippets/css/a-guide-to-flexbox/?ref=blog.cemsoyding.com">css-tricks</a> and/or to watch the very nice video series <a href="https://www.youtube.com/watch?v=Vj7NZ6FiQvo&amp;ref=blog.cemsoyding.com"><em>What the Flexbox</em></a> that covers it very well.</p><h3 id="visibility">Visibility</h3><p>With <code>visibility</code>, you can change the rendering of html elements without changing the structure of the tree, meaning that the boxes won&apos;t be deleted if the element is <code>hidden</code> (as opposed to <code>display:none</code>).</p><pre><code class="language-css">div {
    /* Sets the visibility of an element.
     * &apos;visible&apos; (default) : the box and its content are visible
     * &apos;hidden&apos; : the box and its content are invisible but still are in the layout
     * &apos;collapse&apos; : same as &apos;hidden&apos; except for tables (see below)
     * &apos;inherit&apos; : applies visiblity of the parent */
    visibility: hidden;
}
</code></pre><p>When applying <code>collapse</code> to table elements, they get removed. However, they still affect the layout of the table.</p><h3 id="positioning">Positioning</h3><p>We&apos;ve seen how the <code>display</code> property affects the rendering of an element in the layout. This is called the <em>Normal Flow</em>, a rule based solely on the block or inline nature of the elements.</p><p>The positioning method of an element is <code>static</code> by default, meaning that the element in positionnend into its normal position in the <em>Normal Flow</em>.</p><pre><code class="language-css">p {
    /* Makes absolutely no difference in the display */
    position: static;
}
</code></pre><p>Then there is the <code>relative</code> position which lets you shift the element from its original position in the <em>Normal Flow</em> with <code>top</code>, <code>left</code>, <code>bottom</code>, <code>right</code> properties.<br>When shifted, the content of the element will overlap with others but the space reserved in the layout for the element will remain identical.</p><pre><code class="language-css">p {
    /* The paragraph box will be at the same position on screen but the element will appear shifted down,
     * potentially overlapping the element that was right below */
    position: relative;
    top: 150px;
}
</code></pre><p>If you opt for <code>absolute</code> position, there are 2 things to consider:</p><ul><li>it takes the element out of the <em>Normal Flow</em>, meaning that its box will take no space among siblings</li><li>the position is relative to the first parent that has a position different than <code>static</code> (or the top-left corner if none is found)</li></ul><p>The elements positioned with <code>absolute</code> will very likely be overlapping their siblings.</p><pre><code class="language-css">.inner {
    position: absolute;
    /* Here again, use &apos;top&apos;, &apos;left&apos;, &apos;right&apos;, &apos;bottom&apos; properties */
    left: 2px;
}
</code></pre><p>If we consider the following html code, the <code>inner</code> div will apear on top of the paragraph, simply because it is taken out of the <em>Normal Flow</em>.</p><pre><code class="language-html">&lt;div class=&quot;outer&quot;&gt;
    &lt;div class=&quot;inner&quot;&gt;
        This content will overlap the siblings
    &lt;/div&gt;
    &lt;p&gt;Dummy context that will be positioned below the inner div&lt;/p&gt;
&lt;/div&gt;
</code></pre><p>Finally, if you want to position an element absolutely on a page that does not move when the page is scrolled, use <code>fixed</code> positioning. With <code>fixed</code>, the element is fixed with respect to the browser&apos;s viewport.</p><pre><code class="language-css">.inner {
    position: fixed;
    /* Here again, use &apos;top&apos;, &apos;left&apos;, &apos;right&apos;, &apos;bottom&apos; properties */
    top: 50px;
    left: 300px;
}
</code></pre><h3 id="layers">Layers</h3><p>In addition to <code>position</code> that lets you place elements in a 2D space, <code>z-index</code> offers you an option to place elements on top of each others, along the z axis.</p><p><strong>Note</strong>: <code>z-index</code> is only applicable to elements with a <code>position</code> different than <code>static</code> (default).</p><pre><code class="language-css">.above {
    position: absolute;
    top: 50px;
    /* z-index is expressed with an integer that gives the level of the element on z axis.
     * If higher, the element is placed on top. Negative values are also possible */
    z-index: 2;
}
</code></pre><h3 id="float">Float</h3><p>Put simply, <code>float</code> lets you rearrange elements within a container by stacking (some of) them <code>left</code> or <code>right</code>. Neighbour elements will be inlined next to them on the horizontal line (we say that they <em>float around</em> them). It is a popular technique used to wrap text around images.</p><p>Remember how <code>absolute</code> positionning was removing an element from the <em>Normal Flow</em> ? Well there is more complication if you use <code>float</code>. By definition, <code>float</code> <em>removes an item from Normal Flow but the element is still in the flow</em>. It is some sort of reordering of the <em>Normal Flow</em> that also alters how neighbour elements are displayed.</p><pre><code class="language-html">&lt;div class=&quot;left&quot;&gt;1&lt;/div&gt;
  &lt;div class=&quot;left&quot;&gt;2&lt;/div&gt;
  &lt;div class=&quot;right&quot;&gt;3&lt;/div&gt;
  &lt;p&gt;
    This text will be inlined after div &apos;2&apos; and before div &apos;3&apos;
  &lt;/p&gt;
&lt;/div&gt;
</code></pre><pre><code class="language-css">div {
  margin-left: 5px;
  width: 50px;
  height: 150px;
}

.left {
  /* You can float left or right (none is the default) */
  float: left;
  background: pink;
}

.right {
  float: right;
  background: cyan;
}
</code></pre><figure class="kg-card kg-image-card"><img src="http://blog.cemsoyding.com/content/images/2023/12/float.png" class="kg-image" alt="CSS: Layouts" loading="lazy" width="692" height="160" srcset="http://blog.cemsoyding.com/content/images/size/w600/2023/12/float.png 600w, http://blog.cemsoyding.com/content/images/2023/12/float.png 692w"></figure><p>If you want to prevent some elements from floating around, you can use the <code>clear</code> property by telling which side of the element should be cleared. In the example above, we will print the paragraph on next line.</p><pre><code class="language-css">p {
    /* since by default, elements float from left to right, clearing the left edge will 
     * reposition this element onto next line */
    clear: left; 
}
</code></pre><figure class="kg-card kg-image-card"><img src="http://blog.cemsoyding.com/content/images/2023/12/float_clear.png" class="kg-image" alt="CSS: Layouts" loading="lazy" width="692" height="177" srcset="http://blog.cemsoyding.com/content/images/size/w600/2023/12/float_clear.png 600w, http://blog.cemsoyding.com/content/images/2023/12/float_clear.png 692w"></figure><p>None of the <code>div</code> has been repositionned and there is now an empty space between them.</p><h3 id="columns">Columns</h3><p>When you want to display an element throughout several columns you can chose to set one of the following properties:</p><ul><li><code>column-count</code>: Explicitely defined the number of columns to apply</li><li><code>column-width</code>: Defines the ideal width of the each column and the total number is deduced (the final size will depend on the available space).</li></ul><pre><code class="language-css">p {
    /* You can only use one or the other. Don&apos;t mix &apos;count&apos; and &apos;width&apos; */
    column-count: 4;
    /* [Optional] Set the distance between columns */
    column-gap: 10px;
    /* [Optional] Draw a vertical line between columns (thickness style color)
     * This is a shorthand, you can also use independent properties (&apos;column-rule-color&apos;,
     * &apos;column-rule-style&apos; and &apos;column-rule-width&apos;) */
    column-rule: 1px solid blue;
    /* [Optional] Define how the content is spread among columns 
    * &apos;auto&apos; (default): columns filled sequentially 
    * &apos;balance&apos;: content balanced among columns */
    column-fill: balance;
}
</code></pre><p>Another common approach to build a multi-column layout is to combine <code>float</code> and <code>box-sizing</code>.</p><pre><code class="language-css">.box {
    width: 30%;
    padding: 20px;
    margin-left: 3px;
    background: #f2f2f2;
    float: left;
    box-sizing: border-box;
}
.box:first-child {
    /* With &apos;first-child&apos; pseudo selector, we can remove the left margin on first
     * element */
    margin-left: 0;
}
</code></pre><pre><code class="language-html">&lt;div class=&quot;box&quot;&gt;
    &lt;p&gt;First column .....&lt;/p&gt;
    &lt;p&gt;Second column .....&lt;/p&gt;
    &lt;p&gt;Third column .....&lt;/p&gt;
&lt;/div&gt;
</code></pre><p>Each <code>&lt;p&gt;</code> column is stacked on the left with a margin of <code>3px</code> between them.</p><p>Note that you can also use <code>flexbox</code> properties to create this type of layout.</p>]]></content:encoded></item><item><title><![CDATA[CSS: Box Model]]></title><description><![CDATA[<p></p><h2 id="box-model">Box Model</h2><p>Each html model consists of an encapsulation of boxes (i.e. rectangles).</p><figure class="kg-card kg-image-card"><img src="http://blog.cemsoyding.com/content/images/2023/12/css-box-model.png" class="kg-image" alt="boxmodel" loading="lazy" width="365" height="365"></figure><p>The content area is where the value (content) of an html element goes. The content space is shared with the padding, meaning that if a background color is applied to the element, the padding area gets</p>]]></description><link>http://blog.cemsoyding.com/css-box-model/</link><guid isPermaLink="false">658562703ba3c80001cddb21</guid><dc:creator><![CDATA[Cem Soyding]]></dc:creator><pubDate>Fri, 29 Dec 2023 10:29:51 GMT</pubDate><media:content url="http://blog.cemsoyding.com/content/images/2023/12/css-1.png" medium="image"/><content:encoded><![CDATA[<img src="http://blog.cemsoyding.com/content/images/2023/12/css-1.png" alt="CSS: Box Model"><p></p><h2 id="box-model">Box Model</h2><p>Each html model consists of an encapsulation of boxes (i.e. rectangles).</p><figure class="kg-card kg-image-card"><img src="http://blog.cemsoyding.com/content/images/2023/12/css-box-model.png" class="kg-image" alt="CSS: Box Model" loading="lazy" width="365" height="365"></figure><p>The content area is where the value (content) of an html element goes. The content space is shared with the padding, meaning that if a background color is applied to the element, the padding area gets colored as well. &#xA0;The border box wraps the content area and has its own attributes. Finally, the margin area controls the position of an element relatively to its parent. It is by the way styled according to the parent&apos;s content area.</p><p>On this picture, we can see that <em>padding</em> concentrates the content relatively to the element&apos;s border. <em>margin</em> on the other hand pushes the element relatively to its parent edges.</p><p>When <code>width</code> and <code>height</code> are set on an element, they only apply to the content area. If margin, border and padding are different than 0, then the element occupies more space on screen</p><pre><code class="language-txt">total width = width + padding left + padding right + border left + border right + margin left + margin right
</code></pre><p>Same reasoning with height of course.</p><h3 id="dimensions">Dimensions</h3><p>As explained above, you can set the <code>width</code> and <code>height</code> of the content area of any html element in CSS.</p><pre><code class="language-css">div {
    /* You can set width and height in px, % or any length value (px, em, rem,...).
     * Besides, you can use &apos;auto&apos; to let the browser calculate suitable dimension(s),
     * &apos;initial&apos; to set the default value(s) or &apos;inherit&apos; to use parent values. */
    width: 300px;
    height: inherit;
    /* When the dimesion of the content is dynamic (not fixed), you can define dimension
     * limits to control the display to some extent, for instance to define a range of valid
     * dimensions */
    max-width: 500px; /* can&apos;t grow above this width, even with width set to a higher value */
    max-height: 50px; /* can&apos;t grow above this height */
    min-width: 50px; /* can&apos;t shrink below this width */
    min-height: 5px; /* can&apos;t shrink below this height */
}
</code></pre><p><strong>Note</strong>: By default, html block elements will have a width of 100%. In general, avoid setting fixed dimensions unless it is necessary (prefer using <code>em</code>, <code>rem</code>, <code>%</code>).</p><h3 id="padding">Padding</h3><p>You can specify padding values for each sides of the content area (<code>padding-xxx</code> with <code>xxx</code> one of (<code>top</code>, <code>right</code>, <code>bottom</code>, <code>left</code>)).<br>Negative values aren&apos;t supported.</p><pre><code class="language-css">div {
    /* The value can be set in px, % or any length values (em, rem, ...).
     * You can also use &apos;inherit&apos; to apply the same padding value as the parent */
    padding-top: 50px;
    padding-right: inherit;
}
</code></pre><h4 id="shorthand">Shorthand</h4><p>The shorthand notation lets apply all padding values in one line:</p><pre><code class="language-css">pre {
    padding: 2px; /* applies to all sides */
    padding: 1px 2px; /* vertical and horizontal */
    padding: 1px 2px 1.5px; /* top, horizontal and bottom */
    padding: 1px 2px 1px 2px; /* top, right, bottom and left */
}
</code></pre><h3 id="border">Border</h3><p>The border sits between the margin and the padding areas an could be styled with various options.</p><pre><code class="language-css">h1 {
    /* Border style defines how the border looks like. 
     * none/hidden : no border (default)
     * dashed: line is dashed
     * dotted: line is dotted
     * double: 2 parallel lines are drawn
     * inset/outset: bicolor 2d frame is drawn
     * groove/ridge: bicolor 3d frame is drawn */
    border-style: dashed;
    /* Set the thickness of the border. You can use any length value (p, em, rem...)
     * or pick one of predefined profiles : &apos;thin&apos;, &apos;medium&apos; or &apos;thick&apos; 
     * Note: this is a shorthand notation, you could also set width for each side.
     * Note: border-style must be different than &apos;none&apos;/&apos;hidden&apos;*/
    border-width: 1px;
    /* Set the color of the border. 
     * Note: this is a shorthand notation, you could also set color for each side.
     * Note: border-style must be different than &apos;none&apos;/&apos;hidden&apos;*/
    border-color: #ff0030;
    /* Create rounded borders. The value represents the size of the arc. */
    border-radius: 20px;
    /* With CSS3 you can use an image to draw the border. The sides and corners
     * of the specified image will be replicated and stretched to wrap your content */
    border-image: url(&quot;border.png&quot;) 20 20 round;
}
</code></pre><h4 id="shorthand-1">Shorthand</h4><p>As usual, there is a shorthand notation to set all properties at once.</p><pre><code class="language-css">p {
    /* In this order: width, style, color.
    * Note: You can omit a parameter (2px red) and it will take its default 
    * value if any) */
    border: 2px dotted red;
}
</code></pre><h3 id="margin">Margin</h3><p>The margin is upper coating of the box model and is always transparent.<br>You can specify margin values for each sides of the content area (<code>margin-xxx</code> with <code>xxx</code> one of (<code>top</code>, <code>right</code>, <code>bottom</code>, <code>left</code>)).<br>Negative values <strong>are</strong> supported.</p><pre><code class="language-css">div {
    /* The value can be set in px, % or any length values (em, rem, ...).
     * You can also use &apos;inherit&apos; to apply the same margin value as the parent 
     * or &apos;auto&apos; to let the browser compute the ideal margin value */
    margin-top: 50px;
    margin-right: inherit;
    margin-bottom: -1px;
}
</code></pre><h4 id="shorthand-2">Shorthand</h4><p>The shorthand notation lets apply all margin values in one line:</p><pre><code class="language-css">pre {
    margin: 2px; /* applies to all sides */
    margin: 1px 2px; /* vertical and horizontal */
    margin: 1px 2px 1.5px; /* top, horizontal and bottom */
    margin: 1px 2px 1px 2px; /* top, right, bottom and left */
}
</code></pre><h4 id="horizontal-centering-technique">Horizontal centering technique</h4><p>When the margin is set to <code>auto</code>, the free space in container&apos;s width is split to calculate the margin values on each side of the element. As a consequence, the element is centered. This is a common technique use in frontend development.</p><pre><code class="language-css">div {
    width: 200px;
    margin: 0 auto;
}
</code></pre><h3 id="outline">Outline</h3><p>Outlines are used to indicate focus on elements by drawing a line outside their border, in the margin area. Although they look similar to borders, they differ in many important ways:</p><ul><li>The outline is not part of the Box Model</li><li>An outline does not take space, it overlaps. The dimensions of your element with it</li><li>You can style the outline on each side of the element</li></ul><p>Syntactically, the outline is very similar to the border.</p><pre><code class="language-css">h1 {
    /* Outline style defines how the outline looks like. 
     * none/hidden : no border (default)
     * dashed: line is dashed
     * dotted: line is dotted
     * double: 2 parallel lines are drawn
     * inset/outset: bicolor 2d frame is drawn
     * groove/ridge: bicolor 3d frame is drawn */
    outline-style: double;
    /* Set the thickness of the outline. You can use any length value (p, em, rem...)
     * or pick one of predefined profiles : &apos;thin&apos;, &apos;medium&apos; or &apos;thick&apos; 
     * Note: outline-style must be different than &apos;none&apos;/&apos;hidden&apos;*/
    border-width: 1px;
    /* Set the color of the outline. 
     * Note: outline-style must be different than &apos;none&apos;/&apos;hidden&apos;*/
    border-color: #ff0030;
}
</code></pre><h4 id="shorthand-3">Shorthand</h4><p>The shorthand notation to set all properties at once.</p><pre><code class="language-css">p {
    /* In this order: width, style, color.
    * Note: You can omit a parameter (2px red) and it will take its default 
    * value if any) */
    outline: 2px dotted red;
}
</code></pre><h4 id="common-usage">Common usage</h4><p>By default, active links have an outline drawn. You can change the default style if you need to.</p><pre><code class="language-css">a, a:active, a:focus {
    outline: none;
}
</code></pre><h3 id="box-sizing">Box sizing</h3><p>Since adding a <code>padding</code> and/or a <code>border</code> affects the actual size of the element, creating nice layouts that fit in the viewport could be an intricate task. To ease it up a little bit, CSS3 introduced the <code>box-sizing</code> property so that the size of <code>padding</code> and <code>border</code> is substracted out of the content&apos;s <code>width</code>/<code>height</code>. In other word, it is like applying <code>width</code>/<code>height</code> to the whole <em>Box</em>.</p><pre><code class="language-css">.sized {
    width:100%;
    padding: 10px;
    background: pink;
    border: 5px solid #ffff33;
    /* Thanks to this line, no scrollbar will appear and the 
     * element will occupy full width with padding and border applied */
    box-sizing: border-box;
}
</code></pre>]]></content:encoded></item><item><title><![CDATA[CSS: absolute basics]]></title><description><![CDATA[<p>We start this CSS learning journey by introducing the basics you must know beofre going further. As usual with the articles on this blog, the focus is on the code with insightful comments instead of long and boring explanations. </p><p>In this article series, I assume that you are not a</p>]]></description><link>http://blog.cemsoyding.com/css-absolute-basics/</link><guid isPermaLink="false">658560bf3ba3c80001cddaed</guid><dc:creator><![CDATA[Cem Soyding]]></dc:creator><pubDate>Mon, 25 Dec 2023 10:27:49 GMT</pubDate><media:content url="http://blog.cemsoyding.com/content/images/2023/12/css.png" medium="image"/><content:encoded><![CDATA[<img src="http://blog.cemsoyding.com/content/images/2023/12/css.png" alt="CSS: absolute basics"><p>We start this CSS learning journey by introducing the basics you must know beofre going further. As usual with the articles on this blog, the focus is on the code with insightful comments instead of long and boring explanations. </p><p>In this article series, I assume that you are not a stranger to software development and you have an idea of what CSS is. You came here to find a concise presentation of CSS features that you can quickly pick and use in-code. For in-depth explanations, do not hesitate to consult mdn.</p><h2 id="base-syntax">Base syntax</h2><pre><code class="language-css">/* selector { property:value; property: value; ... } */
h1 { color: red; }
</code></pre><h3 id="selectors">Selectors</h3><!--kg-card-begin: html--><table>
<thead>
<tr>
<th>Selector</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>Universal: <code>*</code></td>
<td>Matches every single element on the page</td>
</tr>
<tr>
<td>Type: <code>p</code></td>
<td>Matches every <code>&lt;p&gt;</code> element on the page</td>
</tr>
<tr>
<td>Id: <code>#cmpId</code></td>
<td>Matches every element where <code>id=&quot;cmpId&quot;</code> on the page</td>
</tr>
<tr>
<td>Class: <code>.cmpClass</code></td>
<td>Matches every element where <code>class=&quot;cmpClass&quot;</code> on the page</td>
</tr>
<tr>
<td>Descendants: <code>ul.nav li a</code></td>
<td>Matches every element <code>&lt;a&gt;</code> inside an <code>&lt;li&gt;</code> inside a <code>&lt;ul&gt;</code> where <code>class=&quot;nav&quot;</code> on the page</td>
</tr>
<tr>
<td>Child: <code>ul &gt; li ol</code></td>
<td>Matches every element <code>&lt;ol&gt;</code> inside an <code>&lt;li&gt;</code> of <code>&lt;ul&gt;</code> elements</td>
</tr>
<tr>
<td>Adjacent siblings: <code>ul.sports + p</code></td>
<td>Matches every element <code>&lt;p&gt;</code> appearing after a <code>&lt;ul&gt;</code> at the same hierarchical level where <code>class=&quot;sports&quot;</code></td>
</tr>
<tr>
<td>General siblings: <code>ul.sports ~ p</code></td>
<td>Matches every element <code>&lt;p&gt;</code> appearing before or after a <code>&lt;ul&gt;</code> at the same hierarchical level where <code>class=&quot;sports&quot;</code></td>
</tr>
</tbody>
</table><!--kg-card-end: html--><h4 id="pseudo-selectors">Pseudo-selectors</h4><p>Pseudo-selectors let you target the states of an element to adapt its style dynamically depending on user interactions. A pseudo-selector can be target using the following syntax :</p><pre><code class="language-css">/* selector:pseudo-selector { property:value; property: value; ... } */
button:hover {
    color: blue;
}
</code></pre><p>Common examples are <code>:hover</code>, <code>:first-child</code> and <code>:last-childs</code> (in lists), <code>:focus</code>, <code>nth-child(n)</code> (tables or lists) ...</p><h4 id="pseudo-elements">Pseudo-elements</h4><p>Pseudo-elements allow you to select parts/areas of an element that do not have an ID or a class. It is helpful when you want to style the first letter of a paragraph or when you want to insert some content before/afer the element.</p><pre><code class="language-css">/* selector::pseudo-element { property:value; property: value; ... } */
p::first-line {
    color: blue;
}
</code></pre><h5 id="before-and-after">::before and :: after</h5><p><code>::before</code> and <code>::after</code> are common pseudo-selectors used to decorate an element with rich content that is not part of the page&apos;s actual markup. You can inject strings, images or other resources using them.</p><pre><code class="language-css">h1::before{
    content: url(&quot;img/bullet.png&quot;);
}
</code></pre><h4 id="attributes">Attributes</h4><p>You can match elements by their attributes as well, by either checking the attribute existence or its value. This is particularly useleful for styling forms.</p><pre><code class="language-css">/* selector[attrbiute expression] { property:value; property: value; ... } */

/* matches all elements that have a &apos;name&apos; attribute */
[name] {
    color: blue;
}

/* matches input elements of type &apos;password&apos; */
input[type=&quot;password&quot;] {
    background-color: gray;
}

/* matches div elements where one of the attributes is &apos;navbar&apos; */
div[type~=&quot;navbar&quot;] {
    background-color: gray;
}

/* matches a elements where the &apos;href&apos; attributes starts with a particular pattern */
a[href^=&quot;ftp://&quot;] {
    background-color: gray;
}

/* matches a elements where the &apos;href&apos; attributes ends with a particular pattern */
a[href$=&quot;.docx&quot;] {
    background-color: gray;
}

/* matches p elements where the &apos;class&apos; attributes contains a particular pattern */
p[class*=&quot;intr&quot;] {
    background-color: gray;
}
</code></pre><h2 id="medias">Medias</h2><p>The formatting of a web page is usually made to render on a screen but CSS supports several other types. The targeted device is called <code>media</code> and you can adjust the styling of a page depending on the media that will render it.</p><p>Most common medias are <code>screen</code>, <code>print</code> (for printers when printing a page) and <code>all</code>.<br>To adapt the styling to each media, simply tag the css entries with <code>@media</code>:</p><pre><code class="language-css">@media screen {
    h1 {
        font-size: 14px;
        font-family: Arial, sans-serif;
    }
}
@media print {
    h1 {
        font-size: 11px;
        font-family: Times, sans-serif;
    }
}

/* This style block applies to all medias */
h2 {
    font-size: 10px;
}
</code></pre><p>You can also specify the media with the <code>@import</code> statetement, at the beginning of the file</p><pre><code class="language-css">@import url(&quot;css/printer.css&quot;) print;
@import url(&quot;css/browser.css&quot;) screen;
</code></pre><p>or with <code>&lt;link&gt;</code> tags in html:</p><pre><code class="language-html">&lt;link rel=&quot;stylesheet&quot; media=&quot;print&quot; href=&quot;css/printer.css&quot;&gt;
</code></pre><h2 id="units">Units</h2><p>Many CSS properties use length values which must be specified with a number and a unit.<br>The length can be expressed with absolute or relative values.</p><p><strong>Note</strong>: Whitespaces between the number and the unit are forbidden.</p><h3 id="absolute">Absolute</h3><p>Absolute values will be applied whatever media is rendering the page. As a consequence, if the page was designed for desktop, it won&apos;t be rendered beautifully on mobile devices since all dimensions are hard-coded and were specified for bigger screens. For scalibility, always prefer relative lengths.</p><pre><code class="language-css">p {
    /* You can pick any unit from the followings:
     * &apos;in&apos;: inches (~2.54cm)
     * &apos;cm&apos;: centimeters
     * &apos;mm&apos;: millimeters
     * &apos;pt&apos;: point=1/72 inch (~0.35mm)
     * &apos;pc&apos;: picas=12 pt
     * &apos;px&apos;: pixel=0.75pt 
     * For on-screen display, consider using &apos;px&apos; only as the others are better for 
     * print media or other high resolution devices. */
    margin: 12px;
}
</code></pre><h3 id="relative">Relative</h3><p>Relative length units are ratios of an absolute dimension.</p><pre><code class="language-css">p {
    font-size: 10px;
    /* You can pick any unit from the followings:
     * &apos;em&apos;: ratio of current font-size
     * &apos;ex&apos;: ratio of the height of letter &apos;x&apos; in current font 
     * &apos;rem&apos;: ratio of root&apos;s font size 
     * &apos;vh&apos; : 1% of viewport&apos;s height 
     * &apos;vw&apos; : 1% of viewport&apos;s width
     * &apos;%&apos; : 1% of parent&apos;s property */
    padding: 1.2em; /* 12 px */
}
</code></pre><p>Note that <code>font-size</code> could have been specified with relative units as well. In that case, the <code>font-size</code> of the parent element would be used, and if relative as well, its parent and so on until reaching the body&apos;s default which is 16px.</p>]]></content:encoded></item><item><title><![CDATA[HTML fundamentals]]></title><description><![CDATA[<p>Welcome to the HTML Fundamentals article, where we&apos;ll explore key HTML elements and concepts that form the foundation of web pages. Whether you&apos;re a seasoned developer or just starting your journey, this series aims to provide valuable insights into HTML, the markup language that structures the</p>]]></description><link>http://blog.cemsoyding.com/html-fundamentals/</link><guid isPermaLink="false">658559c73ba3c80001cdda84</guid><dc:creator><![CDATA[Cem Soyding]]></dc:creator><pubDate>Fri, 22 Dec 2023 10:01:09 GMT</pubDate><media:content url="http://blog.cemsoyding.com/content/images/2023/12/html.png" medium="image"/><content:encoded><![CDATA[<img src="http://blog.cemsoyding.com/content/images/2023/12/html.png" alt="HTML fundamentals"><p>Welcome to the HTML Fundamentals article, where we&apos;ll explore key HTML elements and concepts that form the foundation of web pages. Whether you&apos;re a seasoned developer or just starting your journey, this series aims to provide valuable insights into HTML, the markup language that structures the content of the World Wide Web.</p><p>Each chapter provides concise explanations, code snippets, and practical examples to empower you with a solid understanding of HTML fundamentals.</p><h2 id="head">Head</h2><p>The head elements collectively describe the properties of the document (title, character set, stylesheets, scripts).</p><pre><code class="language-html">&lt;head&gt;
    &lt;!-- Mandatory: the title should ideally be smaller than 65 chars  --&gt;
    &lt;!-- to be indexed properly by search engines  --&gt;
    &lt;title&gt;My fantastic website&lt;/title&gt;
    
    &lt;!-- You can add more data about your website in meta tags that&apos;ll be --&gt;
    &lt;!-- used by browsers or search engines --&gt;
    &lt;meta charset=&quot;utf-8&quot;&gt;
    &lt;meta name=&quot;author&quot; content=&quot;John Smith&quot;&gt;
    &lt;meta name=&quot;description&quot; content=&quot;Presentation of different IoT projects built with Arduino&quot;&gt; 
    &lt;!-- Viewport helps the rendering of your page on mobile devices. You  --&gt;
    &lt;!-- should ideally always have a viewport defined to avoid pinching --&gt;
    &lt;!-- and zooming to read its content. Here, the width is defined to be --&gt;
    &lt;!-- limited to the device-width, at 100% --&gt;
    &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1&quot;&gt;
    
    &lt;!-- You can define the base address for all relative --&gt;
    &lt;!-- links in the document --&gt;
    &lt;base href=&quot;https://mywebsite.com/&quot;&gt;

    &lt;!-- You can refer to CSS stylsheets --&gt;
    &lt;link rel=&quot;stylesheet&quot; href=&quot;style.css&quot;&gt;
    &lt;!-- or embed styles --&gt;
    &lt;style&gt;
        body { background-color: YellowGreen; }
        h1 { color: red; }
        p { color: green; }
    &lt;/style&gt;

    &lt;!-- You can refer to javascript files --&gt;
    &lt;script src=&quot;coloring-utils.js&quot;&gt;&lt;/script&gt;
    &lt;!-- or embed javascript --&gt;
    &lt;!-- Note: Ideally, the script tags should be placed at the bottom --&gt;
    &lt;!-- of the html, in the &apos;body&apos; section to speed up the rendering of the page --&gt;
    &lt;script&gt;
        document.write(&quot;&lt;h1&gt;Hello World!&lt;/h1&gt;&quot;) 
    &lt;/script&gt;
&lt;/head&gt;
</code></pre><h2 id="page-layout">Page layout</h2><p>HTML5 introduced new tags to better structure a web page and no longer rely only on <code>div</code> tags:</p><ul><li><code>&lt;header&gt;</code>: header of a document or a section</li><li><code>&lt;footer&gt;</code>: footer of a document or a section</li><li><code>&lt;nav&gt;</code>: section with navigation links</li><li><code>&lt;section&gt;</code>: represents a section of a document</li><li><code>&lt;article&gt;</code>: self-contained unit of information (such as a blog post)</li><li><code>&lt;aside&gt;</code>: content losely related to the page content (such as a section for ads)</li></ul><p>Here is how these tags can be applied to a section or a document:</p><pre><code class="language-txt">----------------------------------------
              header
----------------------------------------
       |                       |
  Nav  |        Section        |  Aside
       |                       |
       |  -------------------- |--------
       |  |      Article     | |
       |  |                  | |
       |  -------------------- |
----------------------------------------
               footer
----------------------------------------
</code></pre><p>And here is an example of layout in HTML5:</p><pre><code class="language-html">&lt;div class=&quot;container&quot;&gt;
    &lt;header&gt;
        &lt;h1&gt;Sports news&lt;/h1&gt;
    &lt;/header&gt;
    &lt;div class=&quot;wrapper&quot;&gt;
        &lt;nav&gt;
            &lt;ul&gt;
                &lt;li&gt;&lt;a href=&quot;#&quot;&gt;Home&lt;/a&gt;&lt;/li&gt;
                &lt;li&gt;&lt;a href=&quot;#&quot;&gt;Soccer&lt;/a&gt;&lt;/li&gt;
                &lt;li&gt;&lt;a href=&quot;#&quot;&gt;Basketball&lt;/a&gt;&lt;/li&gt;
            &lt;/ul&gt;
        &lt;/nav&gt;
        &lt;section&gt;
            &lt;h2&gt;Lakers failed again&lt;/h2&gt;
            &lt;p&gt;The desire of success was not...&lt;/p&gt;
        &lt;/section&gt;
    &lt;/div&gt;
    &lt;footer&gt;
        &lt;p&gt;copyright &amp;copy; sports news&lt;/p&gt;
    &lt;/footer&gt;
&lt;/div&gt;
</code></pre><p>Note that depending on how you want to wrap elements or how you want to style them, use <code>div</code> tags to create groups.</p><h2 id="html-element-types">HTML Element types</h2><p>There are two groups of elements:</p><ul><li>block level: used to structure the page (<code>div</code>, <code>p</code>, <code>h1-h6</code>, <code>form</code>, <code>ul</code>, <code>ol</code>, ...). They start by a line break, end with a line break and expand on full width.</li><li>inline level: used to fill the content (<code>img</code>, <code>a</code>, <code>span</code>, <code>strong</code>, <code>b</code>, <code>input</code>, <code>button</code> ...). They are inserted in place and just take the required space.</li></ul><p>Note that the default display type of an element can be overriden with css (<code>display</code>).</p><h3 id="empty-elements">Empty elements</h3><p>Some elements don&apos;t need closing tags. Here is an example with <code>&lt;br&gt;</code></p><pre><code class="language-html">&lt;p&gt;This is &lt;br&gt; great&lt;/p&gt;
</code></pre><p>Note that <code>&lt;br&gt;</code> is different than self-closing tags as it does not end with <code>/&gt;</code>. This if fine for HTML, only xHTML always requires <code>/&gt;</code>.</p><h2 id="attributes">Attributes</h2><h3 id="general-purpose">General purpose</h3><p>Some attributes are valid for all HTML elements : <code>id</code>, <code>title</code>, <code>class</code>, <code>style</code>.</p><h3 id="boolean-attributes">Boolean attributes</h3><p>Several attributes do not consist of name/value pairs but just of a name, such as <code>checked</code>, <code>disabled</code>, <code>readonly</code> ... The shortened syntax is equivalent to <code>checked=&quot;true&quot;</code> for instance.</p><h2 id="headings">Headings</h2><p><code>h1</code> to <code>h6</code>.<br>Don&apos;t use them to display big or bold text. Instead, use them to structure your documents as search engines index the structure and the content of the pages.</p><h2 id="paragraphs">Paragraphs</h2><p>Use <code>&lt;p&gt;</code>(paragraph) to publish text on a page. Note that any space or line breaks in the text written within <code>&lt;p&gt;</code> is not taken in consideration when rendering.</p><pre><code class="language-html">&lt;p&gt;The spaces     and line
    breaks      of this paragraph    won&apos;t show
    at rendering. Instead,   you&apos;ll  se a single line with no   spaces
&lt;/p&gt;
</code></pre><p>You can combine <code>&lt;p&gt;</code> with the following tags to customize the output:</p><ul><li><code>&lt;br&gt;</code> : line break</li><li><code>&lt;hr&gt;</code> : horizontal delimitation with a line between paragraphs</li><li><code>&amp;nbsp;</code>: special character (here non-breaking space)</li></ul><pre><code class="language-html">&lt;p&gt;The spaces `&amp;nbsp;&amp;nbsp; and line &lt;br&gt; breaks of this paragraph&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;will show at rendering&lt;/p&gt;
</code></pre><p>Alternatively, consider <code>&lt;pre&gt;</code> to render a text exactly like it&apos;s written:</p><pre><code class="language-html">&lt;pre&gt;The spaces     and line
    breaks      of this paragraph    will show
    at rendering.
&lt;/pre&gt;
</code></pre><h2 id="text-formatting">Text formatting</h2><pre><code class="language-html">&lt;p&gt;This is &lt;b&gt;bold text&lt;/b&gt;.&lt;/p&gt;
&lt;p&gt;This is &lt;strong&gt;strongly important text&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;This is &lt;i&gt;italic text&lt;/i&gt;.&lt;/p&gt;
&lt;p&gt;This is &lt;em&gt;emphasized text&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;This is &lt;mark&gt;highlighted text&lt;/mark&gt;.&lt;/p&gt;
&lt;p&gt;This is &lt;code&gt;computer code&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;This is &lt;small&gt;smaller text&lt;/small&gt;.&lt;/p&gt;
&lt;p&gt;This is &lt;sub&gt;subscript&lt;/sub&gt; and &lt;sup&gt;superscript&lt;/sup&gt; text.&lt;/p&gt;
&lt;p&gt;This is &lt;del&gt;deleted text&lt;/del&gt;.&lt;/p&gt;
&lt;p&gt;This is &lt;ins&gt;inserted text&lt;/ins&gt;.&lt;/p&gt;
</code></pre><h3 id="i-vs-em-and-b-vs-strong"><code>&lt;i&gt;</code> vs <code>&lt;em&gt;</code> and <code>&lt;b&gt;</code> vs <code>&lt;strong&gt;</code></h3><p>Both are used to format a text in <em>italic</em> or <strong>bold</strong> respectively. The only difference is that <code>em</code> emphasizes that its content is important while <code>i</code> is pure styling.<br>Same goes for <code>b</code> and <code>strong</code> where <code>b</code> is pure styling while <code>strong</code> stresses the importanced of its content.</p><h3 id="quotations">Quotations</h3><p>Use <code>&lt;blockquote&gt;</code> to auto-indent a qutotation block that comes from other sources.</p><pre><code class="language-html">&lt;blockquote&gt;
    &lt;p&gt;This text is an extract of an external resources&lt;/p&gt;
    &lt;cite&gt;- M. Author&lt;/cite&gt;
&lt;/blockquote&gt;
</code></pre><p><code>&lt;cite&gt;</code> is used to describe a reference to a creative work. It must include the author name or the title of the work or eventually an URL.</p><p>Inline quotations can also be inserted by using <code>&lt;q&gt;</code></p><pre><code class="language-html">&lt;p&gt;As once said by a wise man, &lt;q&gt;live your dreams&lt;/q&gt;&lt;/p&gt;
</code></pre><p>Note that in this case, the text will simply be surrounded with double quotes <code>&quot;</code>.</p><h3 id="abbreviations">Abbreviations</h3><p>Not everyone knows all the abbreviations that you could use in your text. <code>&lt;abbr&gt;</code> solves this problem by attaching a description to an abbreviation that the user can see by hovering over it.</p><pre><code class="language-html">&lt;p&gt;The &lt;abbr title=&quot;United Nations&quot;&gt;UN&lt;/abbr&gt; decided to not take action&lt;/p&gt;
</code></pre><p>The abbreviation will have a dotted underline to catch user&apos;s attention.</p><h3 id="address">Address</h3><p>HTML provides a special tag to encapsulate a contact information.</p><pre><code class="language-html">&lt;address&gt;
Nico Burger&lt;br&gt;
7 Brooklyn Avenue&lt;br&gt;
London
&lt;/address&gt;
</code></pre><h2 id="images">Images</h2><p>Images can be inserted with the inline and empty element <code>&lt;img&gt;</code>.</p><pre><code class="language-html">&lt;p&gt;A drawing made by an artist &lt;img src=&quot;url&quot; alt=&quot;Artistic drawing&quot;&gt;&lt;/p&gt;
</code></pre><p><code>alt</code> provides an alternative text for the image if it cannot be displayed.</p><p><code>&lt;img&gt;</code> lets you set the image dimensions with <code>height</code> and <code>weight</code> attributes but you can also assign those in the CSS stylesheet.</p><h3 id="picture">Picture</h3><p><code>&lt;img&gt;</code> comes with several limitations:</p><ul><li>scaling the image to fit different devices is difficult</li><li>changing <code>height</code> and <code>width</code> attributes does not reduce the file size</li></ul><p>HTML5 introduced a new tag <code>&lt;picture&gt;</code> to accomodate these limitations.</p><pre><code class="language-html">&lt;picture&gt;
    &lt;source media=&quot;(min-width: 1000px)&quot; srcset=&quot;large.png&quot;&gt;
    &lt;source media=&quot;(min-width: 500px)&quot; srcset=&quot;medium.png&quot;&gt;
    &lt;img src =&quot;default.png&quot; alt=&quot;Company&quot;&gt;
&lt;/picture&gt;
</code></pre><p><code>&lt;picture&gt;</code> works like a <code>switch/case</code>. The browser evaluates the best match among the specified <code>source</code> tags and uses the default <code>&lt;img&gt;</code> tag if none matches.<br>Note that the default <code>&lt;img&gt;</code> tag is mandatory.</p><h3 id="image-maps">Image maps</h3><p>As often used on facebook, your image can contain clickable links on its surface. This is possible with <code>&lt;map&gt;</code>:</p><pre><code class="language-html">&lt;img src=&quot;earth_landscape.png&quot; usemap=&quot;#capitals&quot; alt=&quot;Capitals on earth&quot;&gt;
&lt;map name=&quot;capitals&quot;&gt;
    &lt;area shape=&quot;circle&quot; coords=&quot;127, 54, 654&quot; href=&quot;paris.html&quot; alt=&quot;Paris&quot;&gt;
    &lt;area shape=&quot;circle&quot; coords=&quot;475, 99, 300, 147, 45, 98&quot; href=&quot;beyrouth.html&quot; alt=&quot;Beyrouth&quot;&gt;
&lt;/map&gt;
</code></pre><p><code>&lt;img&gt;</code> references the map by its <code>name</code>. Each <code>area</code> inside the map defines a clickable link.</p><p>Since creating these maps manually is not convenient, you could consider using one of the numerous online tools.<br>Note that <code>&lt;map&gt;</code> is not search-engine-friendly.</p><h2 id="tables">Tables</h2><p>Use tables to display tubular data only (never use them to build the layout of a page, they&apos;re slow to render and hard to maintain).<br>A <code>&lt;table&gt;</code> is made of rows <code>&lt;tr&gt;</code>, columns <code>&lt;td&gt;</code> and can eventually contain a caption <code>caption</code> and a header <code>&lt;th&gt;</code>.</p><pre><code class="language-html">&lt;table&gt;
    &lt;caption&gt;Users Info&lt;/caption&gt;
    &lt;tr&gt;
        &lt;th&gt;Name&lt;/th&gt;
        &lt;th colspan=&quot;2&quot;&gt;Phone&lt;/th&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;td&gt;John Carter&lt;/td&gt;
        &lt;td&gt;5550192&lt;/td&gt;
        &lt;td&gt;5550152&lt;/td&gt;
    &lt;/tr&gt;
&lt;/table&gt;
</code></pre><p>In the example above, the header is horizontal (along a row) and we&apos;re making use of the <code>colspan</code> attribute to span the header <code>Phone</code> on 2 columns.<br>Here is another example with a vertical header and the use of <code>rowspan</code> to span the header on 2 rows:</p><pre><code class="language-html">&lt;table&gt;
    &lt;tr&gt;
        &lt;th&gt;Name:&lt;/th&gt;
        &lt;td&gt;John Carter&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;th rowspan=&quot;2&quot;&gt;Phone:&lt;/th&gt;
        &lt;td&gt;55577854&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;td&gt;55577855&lt;/td&gt;
    &lt;/tr&gt;
&lt;/table&gt;
</code></pre><p>Finally, not that HTML5 introduced additional tags to add more structure into a table woth <code>&lt;thead&gt;</code>, <code>&lt;tbody&gt;</code> and <code>tfoot</code>.</p><pre><code class="language-html">&lt;table&gt;
    &lt;thead&gt;
        &lt;tr&gt;
            &lt;th&gt;Items&lt;/th&gt;
            &lt;th&gt;Expenditure&lt;/th&gt;
        &lt;/tr&gt;
    &lt;/thead&gt;
    &lt;tbody&gt;
        &lt;tr&gt;
            &lt;td&gt;Stationary&lt;/td&gt;
            &lt;td&gt;2,000&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td&gt;Furniture&lt;/td&gt;
            &lt;td&gt;10,000&lt;/td&gt;
        &lt;/tr&gt;        
    &lt;/tbody&gt;
    &lt;tfoot&gt;
        &lt;tr&gt;
            &lt;th&gt;Total&lt;/th&gt;
            &lt;td&gt;12,000&lt;/td&gt;
        &lt;/tr&gt;
    &lt;/tfoot&gt;
&lt;/table&gt;
</code></pre><h2 id="lists">Lists</h2><h3 id="unordered">Unordered</h3><p>The displayed elements are marked with a bullet.</p><pre><code class="language-html">&lt;ul&gt;
    &lt;li&gt;Butter&lt;/li&gt;
    &lt;li&gt;Milk&lt;/li&gt;
    &lt;li&gt;Sugar&lt;/li&gt;
&lt;/ul&gt;
</code></pre><h3 id="ordered">Ordered</h3><p>The displayed elements are marked with a number.</p><pre><code class="language-html">&lt;ol start=&quot;5&quot;&gt;
    &lt;li&gt;Open the box&lt;/li&gt;
    &lt;li&gt;Replace the battery&lt;/li&gt;
    &lt;li&gt;Close the box&lt;/li&gt;
&lt;/ol&gt;
</code></pre><p>By default, <code>start</code> attribute equals <code>1</code> which the starting number for the ordering. However, you can set it to other values if needed.</p><h3 id="description">Description</h3><p>A description list <code>&lt;dl&gt;</code> displays items <code>&lt;dt&gt;</code> with a definition or description <code>&lt;dd&gt;</code> for each. The descriptive text is usually automatically indented by browsers.</p><pre><code class="language-html">&lt;dl&gt;
    &lt;dt&gt;Bread&lt;/dt&gt;
    &lt;dd&gt;A baked food made of flour.&lt;/dd&gt;
    &lt;dt&gt;Coffee&lt;/dt&gt;
    &lt;dd&gt;A drink made from roasted coffee beans.&lt;/dd&gt;
&lt;/dl&gt;
</code></pre><h2 id="forms">Forms</h2><p>Forms are used to collect user inputs and submit them.</p><pre><code class="language-html">&lt;form name=&quot;uniqueName&quot; action=&quot;url&quot; method=&quot;post&quot; target=&quot;_self&quot;&gt;
    &lt;label&gt;Name: &lt;input type=&quot;text&quot;&gt;&lt;/label&gt;
    &lt;input type=&quot;submit&quot; value=&quot;Submit&quot;&gt;
&lt;/form&gt;
</code></pre><p><code>&lt;form&gt;</code> accepts several types of attributes:</p><ul><li><code>name</code>: name of the form. Must be unique in the document and not empty</li><li><code>action</code>: url of program or script that will process the inputs</li><li><code>method</code>: http verb used to send the data : <code>post</code> (default) or <code>get</code> (means that the data is visible in browser&apos;s address bar)</li><li><code>target</code>: specifies where the response should be displayed (<code>_blank</code>, <code>_self</code>, <code>_parent</code>, <code>_top</code>)</li></ul><p>A form can contain several type of controls depending on what it does.</p><h3 id="inputs">Inputs</h3><p>Most commonly used element, the input can take different forms depending on its <code>type</code> attribute.</p><pre><code class="language-html">&lt;form&gt;
    &lt;!-- Text field --&gt;
    &lt;!-- Note that label and input are separate here. &apos;for&apos; and &apos;id&apos; --&gt;
    &lt;!-- are used to join the two. The condensed syntax shown above is also possible --&gt;
    &lt;label for=&quot;user-name&quot;&gt;Username:&lt;/label&gt;
    &lt;input type=&quot;text&quot; name=&quot;username&quot; id=&quot;user-name&quot;&gt;

    &lt;!-- Text area field --&gt;
    &lt;!-- The input here is multiline --&gt;
    &lt;label for=&quot;comment-area&quot;&gt;Comment:&lt;/label&gt;
    &lt;textarea type=&quot;text&quot; name=&quot;comment&quot; id=&quot;comment-area&quot;&gt;&lt;/textarea&gt;

    &lt;!-- Password field --&gt;
    &lt;!-- The input here is masked with dots --&gt;
    &lt;label for=&quot;user-pwd&quot;&gt;Password:&lt;/label&gt;
    &lt;input type=&quot;password&quot; name=&quot;user-password&quot; id=&quot;user-pwd&quot;&gt;

    &lt;!-- Radio buttons field --&gt;
    &lt;!-- Note tha the &apos;name&apos; is identical for each input to group them together. --&gt;
    &lt;!-- You can only select one item per group. --&gt;
    &lt;input type=&quot;radio&quot; name=&quot;gender&quot; id=&quot;male&quot;&gt;
    &lt;label for=&quot;male&quot;&gt;Male&lt;/label&gt;
    &lt;input type=&quot;radio&quot; name=&quot;gender&quot; id=&quot;female&quot;&gt;
    &lt;label for=&quot;female&quot;&gt;Female&lt;/label&gt;
    
    &lt;!-- Checkboxes field --&gt;
    &lt;!-- You can only select any item per group. --&gt;
    &lt;!-- Here, the attribute &apos;checked&apos; sets the default state of a checkbox. --&gt;
    &lt;!-- Same attribute is valid for radio buttons --&gt;
    &lt;input type=&quot;checkbox&quot; name=&quot;options&quot; id=&quot;opt-dark&quot; checked&gt;
    &lt;label for=&quot;opt-dark&quot;&gt;Use dark mode&lt;/label&gt;
    &lt;input type=&quot;checkbox&quot; name=&quot;options&quot; id=&quot;opt-hour&quot;&gt;
    &lt;label for=&quot;opt-hour&quot;&gt;Use 24h mode&lt;/label&gt;

    &lt;!-- File select field --&gt;
    &lt;!-- Renders a button that will open a file explorer --&gt;
    &lt;label for=&quot;file-select&quot;&gt;Upload:&lt;/label&gt;
    &lt;input type=&quot;file&quot; name=&quot;upload&quot; id=&quot;file-select&quot;&gt;

    &lt;!-- Select boxes field --&gt;
    &lt;!-- Renders a combobox with different options --&gt;
    &lt;label for=&quot;city&quot;&gt;City:&lt;/label&gt;
    &lt;select name=&quot;city&quot; id=&quot;city&quot;&gt;
        &lt;option value=&quot;sydney&quot;&gt;Sydney&lt;/option&gt;
        &lt;option value=&quot;melbourne&quot;&gt;Melbourne&lt;/option&gt;
        &lt;option value=&quot;cromwell&quot;&gt;Cromwell&lt;/option&gt;
    &lt;/select&gt;

    &lt;!-- Submit button --&gt;
    &lt;!-- Triggers the processing of submitted data --&gt;
    &lt;!-- Note that you can also use a &apos;button&apos; here for more --&gt;
    &lt;!-- rendering options --&gt;
    &lt;input type=&quot;submit&quot; value=&quot;Submit&quot;&gt;
    
    &lt;!-- Reset button --&gt;
    &lt;!-- Clears user inputs --&gt;
    &lt;input type=&quot;reset&quot; value=&quot;Reset&quot;&gt;
&lt;/form&gt;
</code></pre><p>There are <a href="https://www.tutorialrepublic.com/html-tutorial/html5-new-input-types.php?ref=blog.cemsoyding.com">other</a> inputs as well for colors, email, datetime, number, range, search, phone number, url ...</p><h3 id="groups">Groups</h3><p>You can add more structure to your forms by grouping some inputs together in named panels with <code>&lt;fieldset&gt;</code> and <code>legend</code>.</p><pre><code class="language-html">&lt;form&gt;
    &lt;fieldset&gt;
        &lt;legend&gt;Name&lt;/legend&gt;            
        &lt;label&gt;Firstname: &lt;input type=&quot;text&quot; name=&quot;firstname&quot;&gt;&lt;/label&gt;            
        &lt;label&gt;Lastname: &lt;input type=&quot;text&quot; name=&quot;lastname&quot;&gt;&lt;/label&gt;
    &lt;/fieldset&gt;
    &lt;fieldset&gt;
        &lt;legend&gt;Contact Details&lt;/legend&gt;
        &lt;label&gt;Email Address: &lt;input type=&quot;email&quot; name=&quot;email&quot;&gt;&lt;/label&gt;
        &lt;label&gt;Phone Number: &lt;input type=&quot;text&quot; name=&quot;phone&quot;&gt;&lt;/label&gt;
    &lt;/fieldset&gt;
&lt;/form&gt;
</code></pre><h2 id="iframe">iFrame</h2><p><code>&lt;iframe&gt;</code> lets you display an external html page inside yours. It pretty much acts like a mini web browser within a web browser.</p><pre><code class="language-html">&lt;iframe src=&quot;hello.html&quot; width=&quot;400&quot; height=&quot;200&quot;&gt;&lt;/iframe&gt;
</code></pre><p>Note: <code>height</code> and <code>width</code> can be expressed in <code>%</code> as well.</p><p>The iFrame can also be used to render a link accessed within the page thanks to <code>target</code> and <code>name</code> attributes.</p><pre><code class="language-html">&lt;iframe src=&quot;weather.html&quot; name=&quot;weatherFrame&quot;&gt;&lt;/iframe&gt;
&lt;p&gt;&lt;a href=&quot;http://myweather.org/city=paris&quot; target=&quot;weatherFrame&quot;&gt;Show weather in Paris&lt;/a&gt;&lt;/p&gt;
</code></pre><p>The external link will be rendered inside of the iFrame.</p><h2 id="canvas">Canvas</h2><p>HTML5 only.</p><p>The canvas is a two-dimensional rectangular area that can be used to draw graphics on the webpage via Javascript.</p><pre><code class="language-html">&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;en&quot;&gt;
&lt;head&gt;
&lt;meta charset=&quot;utf-8&quot;&gt;
&lt;title&gt;Drawing on Canvas&lt;/title&gt;
&lt;script&gt;
    window.onload = function() {
        var canvas = document.getElementById(&quot;myCanvas&quot;);
        var context = canvas.getContext(&quot;2d&quot;);
        // draw a line
        context.moveTo(50, 150);
        context.lineTo(250, 50);
        context.stroke();
    };
&lt;/script&gt;
&lt;/head&gt;
&lt;body&gt;
    &lt;canvas id=&quot;myCanvas&quot; width=&quot;300&quot; height=&quot;200&quot;&gt;&lt;/canvas&gt;
&lt;/body&gt;
&lt;/html&gt;
</code></pre><p>You can <a href="https://www.tutorialrepublic.com/html-tutorial/html5-canvas.php?ref=blog.cemsoyding.com">draw many shapes and colors</a> in a canvas. The content of a canvas can be saved into a file.</p><h2 id="svg">SVG</h2><p>HTML5 only.</p><p>An SVG is an XML-based image format that can be scaled without any loss of quality. The SVG also supports animations and can be edited dynamically with Javascript.</p><pre><code class="language-tsx">&lt;svg width=&quot;300&quot; height=&quot;200&quot;&gt;
    &lt;!-- Example of a line--&gt;
    &lt;line x1=&quot;50&quot; y1=&quot;50&quot; x2=&quot;250&quot; y2=&quot;150&quot; style=&quot;stroke:red; stroke-width:3;&quot; /&gt;
    &lt;!-- Example of a rectangle--&gt;
    &lt;rect x=&quot;50&quot; y=&quot;50&quot; width=&quot;200&quot; height=&quot;100&quot; style=&quot;fill:orange; stroke:black; stroke-width:3;&quot; /&gt;
    &lt;!-- Example of a circle --&gt;
    &lt;circle cx=&quot;150&quot; cy=&quot;100&quot; r=&quot;70&quot; style=&quot;fill:lime; stroke:black; stroke-width:3;&quot; /&gt;
    &lt;!-- Example of text --&gt;
    &lt;text x=&quot;20&quot; y=&quot;30&quot; style=&quot;fill:purple; font-size:22px;&quot;&gt;
        Welcome to Our Website!
    &lt;/text&gt;
&lt;/svg&gt;
</code></pre><h2 id="audio">Audio</h2><p>HTML5 only.</p><p><code>&lt;audio&gt;</code> element lets you embed sound in web pages.</p><pre><code class="language-html">&lt;audio controls=&quot;controls&quot;&gt;
    &lt;!-- You can defined many sources for the same sound --&gt;
    &lt;!-- and the browser will pick the first it supports --&gt;
    &lt;source src=&quot;media/birds.mp3&quot; type=&quot;audio/mpeg&quot;&gt;
    &lt;source src=&quot;media/birds.ogg&quot; type=&quot;audio/ogg&quot;&gt;
&lt;/audio&gt;
</code></pre><h2 id="video">Video</h2><p>HTML5 only.</p><p><code>&lt;audio&gt;</code> element lets you embed videos in web pages.</p><pre><code class="language-html">&lt;video controls=&quot;controls&quot;&gt;
    &lt;!-- You can defined many sources for the same video --&gt;
    &lt;!-- and the browser will pick the first it supports --&gt;
    &lt;source src=&quot;media/shuttle.mp4&quot; type=&quot;video/mp4&quot;&gt;
    &lt;source src=&quot;media/shuttle.ogv&quot; type=&quot;video/ogg&quot;&gt;
&lt;/video&gt;
</code></pre><h2 id="web-storage">Web storage</h2><p>HTML5 only.</p><p>HTML5&apos;s we storage provides you with a solution to store 5MB of data locally on computer whereas a cookie was only capable of storing 4KB and had the inconvenient of being transferred on each request.</p><p>There are 2 types of storages with different scope and lifetime as explained below.</p><h3 id="local-storage">Local storage</h3><p>Stores data permanently for an entire website.</p><pre><code class="language-html">&lt;script&gt;
// Store data
localStorage.setItem(&quot;first_name&quot;, &quot;Peter&quot;);
// Retrieve data
console.log(&quot;Hi, &quot; + localStorage.getItem(&quot;first_name&quot;));
&lt;/script&gt;
</code></pre><h3 id="session-storage">Session storage</h3><p>Stores data temporarily for a single browser tab and deletes the data when the browser or tab is closed.</p><pre><code class="language-html">&lt;script&gt;
// Store data
sessionStorage.setItem(&quot;first_name&quot;, &quot;Peter&quot;);
// Retrieve data
console.log(&quot;Hi, &quot; + sessionStorage.getItem(&quot;first_name&quot;));
&lt;/script&gt;
</code></pre><h2 id="application-cache">Application cache</h2><p>HTML5 only.</p><p>Caching helps with performances as your browser will store some of the resources accessed for a web page and load them back from storage instead of requesting them againg from the server. In HTML5, a caching manifest can be specified on server side to tell the browser what to cache:</p><pre><code class="language-python">CACHE MANIFEST
# v1.0 : 10-08-2014
 
# All the items under CACHE: will be cached
CACHE:
# pages
index.html
 
# styles &amp; scripts
css/theme.css
js/jquery.min.js
js/default.js
 
# images
/favicon.ico
images/logo.png
 
# All the items under CACHE: will not be cached
# meaning that the access to login.php is only
# possible if the user is online
NETWORK:
login.php

# Fallback URIs. The index of the page will be redirected
# to offline.html when the user is offline
FALLBACK:
/ /offline.html
</code></pre><p>The cache manifest needs to be indicated in the <code>html</code> element:</p><pre><code class="language-html">&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;en&quot; manifest=&quot;mywebsite.appcache&quot;&gt;
</code></pre><h2 id="web-workers">Web workers</h2><p>HTML5 only.</p><p>The execution of javascript in the web browser is single threaded by default, meaning that any pending execution will prevent the user from interacting with the page.<br>For intensive computations that can be executed in background, HTML5 has introduced <em>web workers</em> to keep the page responsive.</p><p>To use this feature, you must first create a javascript file which will contain the code to be executed in background. Note that this code cannot access the DOM.</p><pre><code class="language-js">// worker.js

var i = 0;
function countNumbers() {
    if(i &lt; 100000) {
        i = i + 1;
        postMessage(i);
    }
 
    // Wait for sometime before running this script again
    setTimeout(&quot;countNumbers()&quot;, 500);
}
countNumbers();
</code></pre><p>Now from the web page, you can control the execution of the worker and/or consume its result as shown below:</p><pre><code class="language-html">&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;en&quot;&gt;
&lt;head&gt;
&lt;meta charset=&quot;utf-8&quot;&gt;
&lt;title&gt;Using Web Worker&lt;/title&gt;
&lt;script&gt;
    // You can control the execution from the web page
    // Here is how you can start the execution
    function startWorker() {
        // Create a new web worker
        var worker = new Worker(&quot;worker.js&quot;);
        
        // Everytime the worker calls postMessage, this function will be executed
        worker.onmessage = function(event) {
            document.getElementById(&quot;result&quot;).innerHTML = event.data;
        }
        worker.postMessage(&quot;start&quot;);
    }

    // Here is how you can stop the execution
    function stopWorker() {
        worker.terminate();
    }
&lt;/script&gt;
&lt;/head&gt;
&lt;body&gt;
    &lt;h1&gt;Web Worker Demo&lt;/h1&gt;
    &lt;button type=&quot;button&quot; onclick=&quot;startWorker();&quot;&gt;Start web worker&lt;/button&gt;
    &lt;button type=&quot;button&quot; onclick=&quot;stopWorker();&quot;&gt;Stop web worker&lt;/button&gt;
    &lt;div id=&quot;result&quot;&gt;
        &lt;!--Received messages will be inserted here--&gt;
    &lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;
</code></pre><h2 id="server-sent-events">Server sent events</h2><p>HTML5 only.</p><p>When a client communicates with a server, the connection is closed after receiving the response which is sufficient most of the time but does not cover the situations where data needs to be streamed.</p><p>In HTML5, a web page can hold a connection open so that the web server can send new responses automatically at any time. Server-Side Events (or SSE) are unidirectional responses delivered from server to client.</p><pre><code class="language-php">// server_time.php

&lt;?php
// On server side we set the content-type to text/event-stream 
// to enable SSE
header(&quot;Content-Type: text/event-stream&quot;);
// We disable caching to prevent the browser from storing the data
header(&quot;Cache-Control: no-cache&quot;);
 
// Get the current time on server
$currentTime = date(&quot;h:i:s&quot;, time());
 
// Send it in a message
// The SSE sent by the server must start with &apos;data:&apos;
echo &quot;data: &quot; . $currentTime . &quot;\n\n&quot;;
flush();
?&gt;
</code></pre><p>On client side, we simply attach an event handler to the <code>EventSource</code> object.</p><pre><code class="language-html">&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;en&quot;&gt;
&lt;head&gt;
&lt;title&gt;Using Server-Sent Events&lt;/title&gt;
&lt;script&gt;
    window.onload = function() {
        var source = new EventSource(&quot;server_time.php&quot;);
        source.onmessage = function(event) {
            document.getElementById(&quot;result&quot;).innerHTML += &quot;New time received from web server: &quot; + event.data + &quot;&lt;br&gt;&quot;;
        };
    };
&lt;/script&gt;
&lt;/head&gt;
&lt;body&gt;
    &lt;div id=&quot;result&quot;&gt;
        &lt;!--Server response will be inserted here--&gt;
    &lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;
</code></pre>]]></content:encoded></item><item><title><![CDATA[Resolving RabbitMQ Administration Issues on Windows]]></title><description><![CDATA[<h3 id="introduction">Introduction</h3><p>Managing RabbitMQ on Windows machines can sometimes present unexpected challenges. Recently, I dedicated some time to delve into the inner workings of RabbitMQ, and I finally grasped the core issues causing difficulties with using command-line scripts. In this article, I will share my findings and the solution I&apos;</p>]]></description><link>http://blog.cemsoyding.com/resolving-rabbitmq/</link><guid isPermaLink="false">653fcb2d3ba3c80001cdda4d</guid><dc:creator><![CDATA[Cem Soyding]]></dc:creator><pubDate>Tue, 14 Nov 2023 15:43:22 GMT</pubDate><media:content url="http://blog.cemsoyding.com/content/images/2023/10/rabbitmq_logo-1.png" medium="image"/><content:encoded><![CDATA[<h3 id="introduction">Introduction</h3><img src="http://blog.cemsoyding.com/content/images/2023/10/rabbitmq_logo-1.png" alt="Resolving RabbitMQ Administration Issues on Windows"><p>Managing RabbitMQ on Windows machines can sometimes present unexpected challenges. Recently, I dedicated some time to delve into the inner workings of RabbitMQ, and I finally grasped the core issues causing difficulties with using command-line scripts. In this article, I will share my findings and the solution I&apos;ve discovered to address these problems.</p><h3 id="the-user-context-challenge">The User Context Challenge</h3><p>The root of the problem lies in the active user on the machine. RabbitMQ is initially installed with the &quot;Administrator&quot; user, and this is where the cookie file is configured. The RabbitMQ service also starts under the &quot;Administrator&quot; user. However, it seems to ignore or not read environmental variables, based on my testing.</p><p>On the other hand, command-line tools located in the installation directory run under the current user&apos;s account (in our case, &quot;Setup&quot;) and take into account environmental variables. This stark contrast between different users leads to significant issues.</p><h3 id="disappointing-results">Disappointing Results</h3><p>The consequences of this problem are as follows:</p><ol><li>The RabbitMQ service starts as expected, but with the default name and not the one we defined in &quot;RABBITMQ_NODENAME.&quot;</li><li>Command-line tools run but fail to locate the cookie and attempt to connect to &quot;RABBITMQ_NODENAME,&quot; which is destined to fail.</li></ol><h3 id="the-solution-rabbitmq-env-confbat">The Solution: &quot;rabbitmq-env-conf.bat&quot;</h3><p>The proposed solution involves using the optional configuration file, &apos;rabbitmq-env-conf.bat&apos;. This batch file is executed when the service (and tools) starts, making it the ideal place to configure the node name.</p><p>Firstly, it&apos;s essential to remove the use of &quot;RABBITMQ_NODENAME&quot; env variable (and stop creating it). Secondly, to use command-line tools effectively, you need to specify the cookie. Execute the following line before using them:</p><p><code>set RABBITMQ_ERLANG_COOKIE=&lt;cookie&gt;</code></p><p>Replace <code>&lt;cookie&gt;</code> with the content of the &quot;.erlang.cookie&quot; file from the &quot;Administrator&quot; user.</p><p>Please note that this last environmental variable may not be used in the latest RabbitMQ versions, so you might need to find an alternative.</p><h3 id="node-renaming-script">Node renaming script</h3><p>Now that you&apos;re all set, run the script below to rename the default node effectively.</p><!--kg-card-begin: markdown--><pre><code class="language-batch">@echo off

REM Set the NODENAME environment variable and create rabbitmq-env-conf.bat file
echo set NODENAME=machine@localhost &gt; &quot;C:\Users\Administrator\AppData\Roaming\RabbitMQ\rabbitmq-env-conf.bat&quot;

REM Create a system environment variable named RABBITMQ_BASE
setx RABBITMQ_BASE &quot;C:\Users\Administrator\AppData\Roaming&quot; /m

REM Stop RabbitMQ service
C:\Program Files\RabbitMQ Server\rabbitmq_server-3.11.0\sbin\rabbitmq-service.bat stop

REM Remove mnesia directories
rmdir /s /q &quot;%AppData%\RabbitMQ\db&quot;
rmdir /s /q &quot;%AppData%\RabbitMQ\log&quot;

REM Copy .erlang.cookie file to C:\Users\Administrator
copy &quot;C:\Windows\SysWOW64\config\systemprofile\.erlang.cookie&quot; &quot;C:\Users\Administrator&quot;

REM Uninstall the RabbitMQ Windows service
C:\Program Files\RabbitMQ Server\rabbitmq_server-3.11.0\sbin\rabbitmq-service.bat remove

REM Re-install the RabbitMQ Windows service
C:\Program Files\RabbitMQ Server\rabbitmq_server-3.11.0\sbin\rabbitmq-service.bat install

REM Start the RabbitMQ Windows service
C:\Program Files\RabbitMQ Server\rabbitmq_server-3.11.0\sbin\rabbitmq-service.bat start

echo RabbitMQ setup completed.

</code></pre>
<!--kg-card-end: markdown--><h3 id="conclusion">Conclusion</h3><p>Resolving RabbitMQ administration challenges on Windows machines can be perplexing, but understanding the user context and making use of the &quot;rabbitmq-env-conf.bat&quot; configuration file can help streamline the process. By addressing these issues, you can ensure a smoother experience when working with RabbitMQ in a Windows environment.</p>]]></content:encoded></item><item><title><![CDATA[I am building an SFFPC : Case selection]]></title><description><![CDATA[<p>In my previous article, we&apos;ve covered the essential components required for assembling your Small Form Factor PC (SFFPC). Now, there&apos;s one element left to complete your build: the case. It&apos;s both logical and recommended to select the case as the final step. The most</p>]]></description><link>http://blog.cemsoyding.com/i-am-building-an-sffpc-case-selection/</link><guid isPermaLink="false">653e2b9c3ba3c80001cdda05</guid><dc:creator><![CDATA[Cem Soyding]]></dc:creator><pubDate>Fri, 10 Nov 2023 10:27:46 GMT</pubDate><media:content url="http://blog.cemsoyding.com/content/images/2023/10/my_build_components-1.JPG" medium="image"/><content:encoded><![CDATA[<img src="http://blog.cemsoyding.com/content/images/2023/10/my_build_components-1.JPG" alt="I am building an SFFPC : Case selection"><p>In my previous article, we&apos;ve covered the essential components required for assembling your Small Form Factor PC (SFFPC). Now, there&apos;s one element left to complete your build: the case. It&apos;s both logical and recommended to select the case as the final step. The most aesthetically pleasing cases may not necessarily be the most suitable for your specific configuration. You&apos;ll often find yourself facing a dilemma between style and volume. This step is not only crucial but also one of the most challenging. Here&apos;s an overview to help you navigate through the case selection process:</p><ul><li><strong>SFFPC Case Size:</strong> SFFPCs are often compared to the dimensions of a shoebox, with a target volume of around 10 liters&#x2014;a goal for purists in the SFFPC community. However, achieving this goal is not always straightforward.</li><li><strong>Component Sizes and Cooling:</strong> As previously mentioned, component sizes have been on the rise, accompanied by increased power consumption. Naturally, this requires more efficient cooling solutions, often leading to larger cases.</li><li><strong>Modern Case Volumes:</strong> In contemporary SFFPC builds, case volumes typically range from 15 to 20 liters. This represents nearly a doubling in size compared to our initial point of reference.</li><li><strong>Is Size a Concern?</strong> In absolute terms, the increased case size is not inherently problematic. SFFPC cases still remain significantly smaller than traditional towers while exuding a stylish and compact aesthetic. However, if you had envisioned the convenience of easily transporting your PC to gaming sessions at your friends&apos; places, the larger cases may present a challenge compared to the shoebox-sized options that can readily fit in a backpack.</li><li><strong>Size vs. Power:</strong> As emphasized in the introduction, striking the right balance is the key challenge. Honesty with yourself is paramount in determining your ideal SFFPC. Do you truly need a 12-core CPU? Is a cutting-edge graphics card a necessity? Will you be moving your PC regularly? Start by answering these questions honestly, and then proceed with selecting the case that aligns with your practical requirements and personal preferences.</li></ul><p>By thoughtfully considering these factors, you can confidently select a case that complements your SFFPC configuration, ultimately achieving the perfect blend of aesthetics and performance for your compact system.</p><h3 id="case-shapes">Case Shapes</h3><p>SFFPC cases come in various shapes, each with its unique design and advantages. Understanding these different case shapes can help you make the right choice for your compact system:</p><ul><li><strong>Classic:</strong> This design resembles a traditional ATX tower case, allowing you to assemble your SFFPC components much like a standard PC. While it offers flexibility, the interior volume optimization is not a primary focus in classic SFFPC cases. This classic style is becoming increasingly rare in the SFFPC landscape.</li><li><strong>Console:</strong> Console-style cases are characterized by a vertical, elongated form factor, reminiscent of gaming consoles like the PS5. One of the popular examples of this style is the Fractal Ridge case. Console cases offer a unique and sleek appearance, often fitting seamlessly into entertainment setups.</li></ul><figure class="kg-card kg-image-card"><img src="http://blog.cemsoyding.com/content/images/2023/10/lc5lmw613ne81-1.jpg" class="kg-image" alt="I am building an SFFPC : Case selection" loading="lazy" width="2000" height="2000" srcset="http://blog.cemsoyding.com/content/images/size/w600/2023/10/lc5lmw613ne81-1.jpg 600w, http://blog.cemsoyding.com/content/images/size/w1000/2023/10/lc5lmw613ne81-1.jpg 1000w, http://blog.cemsoyding.com/content/images/size/w1600/2023/10/lc5lmw613ne81-1.jpg 1600w, http://blog.cemsoyding.com/content/images/size/w2400/2023/10/lc5lmw613ne81-1.jpg 2400w" sizes="(min-width: 720px) 720px"></figure><ul><li><strong>Sandwich:</strong> Sandwich-style cases divide the interior into two distinct zones&#x2014;one for the motherboard and another for the graphics card. These two sections are connected by a PCIe extension cable, often referred to as a Riser cable. This design is similar to the console form, where the layout emphasizes a compact, vertical orientation. The sandwich-style case is currently one of the most commonly used designs in the SFFPC community.</li></ul><figure class="kg-card kg-image-card"><img src="http://blog.cemsoyding.com/content/images/2023/10/image-8.png" class="kg-image" alt="I am building an SFFPC : Case selection" loading="lazy" width="1775" height="1347" srcset="http://blog.cemsoyding.com/content/images/size/w600/2023/10/image-8.png 600w, http://blog.cemsoyding.com/content/images/size/w1000/2023/10/image-8.png 1000w, http://blog.cemsoyding.com/content/images/size/w1600/2023/10/image-8.png 1600w, http://blog.cemsoyding.com/content/images/2023/10/image-8.png 1775w" sizes="(min-width: 720px) 720px"></figure><ul><li><strong>Open-air:</strong> In open-style cases, your PC components are assembled on a structure (or backbone) without a traditional enclosure. This design allows all components to be exposed, facilitating efficient cooling. However, it also makes the system more susceptible to dust, which can accumulate more readily without an enclosed case.</li></ul><figure class="kg-card kg-image-card"><img src="http://blog.cemsoyding.com/content/images/2023/10/sffpc_example_3.png" class="kg-image" alt="I am building an SFFPC : Case selection" loading="lazy" width="640" height="734" srcset="http://blog.cemsoyding.com/content/images/size/w600/2023/10/sffpc_example_3.png 600w, http://blog.cemsoyding.com/content/images/2023/10/sffpc_example_3.png 640w"></figure><p>Understanding these different case shapes enables you to make an informed decision based on your preferences, the components you plan to use, and the overall aesthetics you desire for your SFFPC build.</p><h3 id="case-dimensions">Case Dimensions</h3><p>Beyond the overall volume, it&apos;s crucial to carefully review the specifications of your chosen case, paying particular attention to length, width, and height. While most ITX cases can accommodate a motherboard and power supply, the same isn&apos;t always true for the CPU cooling solution or the graphics card.</p><p>Two important factors to consider are the length and thickness of the graphics card you select. For instance, if you opt for the Nvidia GTX 4080, you should be aware that it measures at least 30.4 cm in length, potentially even more depending on the manufacturer. It&apos;s advisable to choose a case that has a length of at least 35 cm to accommodate this card comfortably. Additionally, keep in mind that the card is quite thick, requiring three slots on the case&apos;s front. Not all cases can accommodate this width, so it&apos;s essential to verify compatibility.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="http://blog.cemsoyding.com/content/images/2023/10/gpu_geforces_2-1.jpg" class="kg-image" alt="I am building an SFFPC : Case selection" loading="lazy" width="959" height="720" srcset="http://blog.cemsoyding.com/content/images/size/w600/2023/10/gpu_geforces_2-1.jpg 600w, http://blog.cemsoyding.com/content/images/2023/10/gpu_geforces_2-1.jpg 959w" sizes="(min-width: 720px) 720px"><figcaption>GTX4080 at the top</figcaption></figure><p>When it comes to CPU cooling, modern processors often come with high Thermal Design Power (TDP) ratings. If you plan to use an air cooler, you&apos;ll notice that the heatsinks provided can be quite substantial. They&apos;re often tall and, in some cases, quite wide. Thus, it&apos;s crucial to confirm the maximum heatsink height supported by your chosen case. Furthermore, ensure that the cooler you select is compatible with your CPU, considering both TDP and the CPU socket. It&apos;s worth noting that achieving compatibility can sometimes be challenging.</p><figure class="kg-card kg-image-card"><img src="http://blog.cemsoyding.com/content/images/2023/10/image-9.png" class="kg-image" alt="I am building an SFFPC : Case selection" loading="lazy" width="960" height="720" srcset="http://blog.cemsoyding.com/content/images/size/w600/2023/10/image-9.png 600w, http://blog.cemsoyding.com/content/images/2023/10/image-9.png 960w" sizes="(min-width: 720px) 720px"></figure><p>To further complicate matters, the width of the coolers can also be a deciding factor, as they may interfere with your RAM or VRM (the L-shaped section on the left that powers your CPU). In these situations, online forums and tutorial videos can be invaluable resources, as you&apos;re unlikely to be the first person attempting such a build. These resources provide insights and guidance based on the experiences of others in the SFFPC community.</p><h3 id="conclusion">Conclusion</h3><p>As you&apos;ve undoubtedly gathered, assembling a Small Form Factor PC (SFFPC) is no small feat; it&apos;s a challenging and often costly endeavor that may deter many. However, the unique aesthetics and the gratification of building one&apos;s SFFPC from the ground up serve as compelling incentives for enthusiasts like myself.</p><p>While I remain realistic about not attempting to rival the world of ATX systems in terms of sheer performance, I firmly believe that SFFPCs have the potential to pack a considerable punch. With this conviction in mind, I&apos;m embarking on my own SFFPC build, driven by the desire to discover just how formidable a compact powerhouse can be. The SFFPC world is a realm where the balance between performance and form factor truly comes to life, making it an enticing endeavor for those who appreciate both the art and science of PC building.</p>]]></content:encoded></item><item><title><![CDATA[Langchain : introduction]]></title><description><![CDATA[<p>Today, we only hear about AI, and more specifically, Generative AI, since the emergence of ChatGPT. Everyone enjoys using it on the OpenAI website, typically to obtain information or for interactive assistance. This technology is also heavily used for creating dedicated assistants for very specific tasks. If you too want</p>]]></description><link>http://blog.cemsoyding.com/langchain-introduction/</link><guid isPermaLink="false">653bc10b3ba3c80001cdd908</guid><dc:creator><![CDATA[Cem Soyding]]></dc:creator><pubDate>Mon, 06 Nov 2023 14:49:24 GMT</pubDate><media:content url="http://blog.cemsoyding.com/content/images/2023/10/langchain.png" medium="image"/><content:encoded><![CDATA[<img src="http://blog.cemsoyding.com/content/images/2023/10/langchain.png" alt="Langchain : introduction"><p>Today, we only hear about AI, and more specifically, Generative AI, since the emergence of ChatGPT. Everyone enjoys using it on the OpenAI website, typically to obtain information or for interactive assistance. This technology is also heavily used for creating dedicated assistants for very specific tasks. If you too want to integrate this kind of functionality or even develop a tool from scratch based on Generative AI, you&apos;ll find that there are several alternatives, and organizing them can be tricky.</p><p>In this new series of articles, I am creating a guided journey for building applications based on large language models using a popular framework called <em>Langchain</em>. We will see how this set of libraries simplifies the creation of applications around AI through diagrams and code examples. </p><p>While Python is the preferred language for AI, I&apos;ve opted here for the JS variant of the library in order to easily integrate these features into a modern tech stack such as Next.js.</p><p>In this first article, I describe the main challenges you&apos;ll face when working with AI and introduce the basic concepts of <em>Langchain</em>.</p><h2 id="challenges">Challenges</h2><h3 id="limited-text-size">Limited Text Size</h3><p>The prompts you may have used with ChatGPT support a limited number of tokens. In other words, the amount of text you feed into the AI cannot exceed a certain number of words. For instance, ChatGPT accepts around 3,800 words, and it&apos;s much less for other models. However, you may be looking to customize your AI with large volumes of input text which constitutes an initial obstacle for your application development.</p><p>Briefly, here&apos;s a quick reminder of what a token is: a token is a text unit identified by the AI within a text. Although one might think that a word is equivalent to a token, that&apos;s not the case. Some words are divided into multiple tokens if they contain a sequence of characters recognized by the AI based on its training set. The character sets most frequently seen in the texts it was trained on will be tokenized and thus recognized in words because the AI considers them as being significant for understanding the sentence. Feel free to <a href="https://platform.openai.com/tokenizer?ref=blog.cemsoyding.com">try it yourself</a>. </p><p>The commonly used rule of thumb to estimate the number of tokens in a sentence is that one token is equivalent to 3/4 of a word (in English). </p><h3 id="very-general-training-data">Very General Training Data</h3><p>Large Language Models (referred to as LLMs) have been trained on a huge amount of data and you can&apos;t verify its content or authenticity. If you want to build an application focused on a specific domain, how can you be sure that the selected AI contains all the relevant data for your business?</p><p>Although the models are somewhat documented, the limited information you have inevitably exposes you to inaccuracies in the tool&apos;s responses.</p><p>However, it is possible to provide reference information to a model to make it more relevant to your needs, as we&apos;ll see later.</p><h3 id="the-complexity-of-prompts">The Complexity of Prompts</h3><p>To be efficient, a prompt must contain a complete context that will help the tool respond as accurately as possible to the query. This involves defining roles, instructions, including things not to do/say, and providing examples. Besides, for your prompt to be usable by your customers, it will partially contain information that they provide and achieving a precise solution in all cases will not be easy.</p><p>Furthermore, the size of the prompt is a problem, as well as scaling it to address a growing number of customers.</p><h3 id="formatting-unstructured-data">Formatting Unstructured Data</h3><p>The external data you that you may want to add to your model can be in various formats, such as PDF, Excel, or even proprietary ones. To make your model capable of using this data, you will need to convert it into the format expected by the model first. The question of storing this information will also be a point to address to easily make it exploitable in the future.</p><h3 id="pricing">Pricing</h3><p><em>OpenAI </em>has become quite popular on social media with ChatGPT, but using it in an application (API calls) is not free. Billing is done per token and varies depending on the selected model (gpt 3.5, gpt 4, ...). </p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="http://blog.cemsoyding.com/content/images/2023/10/openai_pricing.png" class="kg-image" alt="Langchain : introduction" loading="lazy" width="791" height="137" srcset="http://blog.cemsoyding.com/content/images/size/w600/2023/10/openai_pricing.png 600w, http://blog.cemsoyding.com/content/images/2023/10/openai_pricing.png 791w" sizes="(min-width: 720px) 720px"><figcaption>GPT4 pricing</figcaption></figure><p>Although it may seem cheap, prices can quickly add up when dealing with large volumes of text. </p><h2 id="langchain">Langchain</h2><p><em>Langchain </em>is a framework for developing applications based on LLMs with a set of components that can be assembled to build <em>chains</em>. Each component has a specific role in the chain and allows you to fine-tune the performance of the LLM for your application. The concept of <em>chaining things</em> is very representative of how the library works because each component is actually a link that plays its role and passes the result to its neighbor.</p><p>One of <em>Langchain</em>&apos;s major strengths is the availability of predefined chains that are suitable for the simplest types of applications in just a few lines of code, such as creating a chatbot or a summarization tool.</p><p>Another major advantage for me is the number of third-party API integrations that let you use various models or tools very easily.</p><h3 id="components">Components</h3><p>The <a href="https://js.langchain.com/docs/modules/?ref=blog.cemsoyding.com">official documentation</a> is, of course, the reference point, and this article does not intend to replace it. Here are the main components of a chain and their roles.</p><!--kg-card-begin: html--><table>
<thead>
<tr>
<th>Component</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>Model I/O</strong></td>
<td>The minimal chain will always consist of input text (or prompt), an LLM, and output text (response). This component provides tools to format the prompt by integrating parameters, examples, etc. (<code>PromptTemplate</code>), to select from available models (<code>LLM</code>, <code>ChatModel</code>), and to extract useful information from the returned response (<code>OutputParser</code>).</td>
</tr>
<tr>
<td><strong>Data connection</strong></td>
<td>This set of tools is intended for customizing your model by injecting third-party data. You can load documents (<code>DocumentLoader</code>), break them into smaller chunks for LLMs (document transformers), convert them into a format understandable by LLMs (<code>Embedding</code>), store them (<code>VectorStore</code>), and finally query them for information retrieval (<code>Retrievers</code>).</td>
</tr>
<tr>
<td><strong>Chains</strong></td>
<td>Chaining multiple components (including other chains) is possible with this library. Ready-to-use chains are also available.</td>
</tr>
<tr>
<td><strong>Memory</strong></td>
<td>Memory typically serves to retain the conversation state so that each new message is not interpreted out of context.</td>
</tr>
<tr>
<td><strong>Callbacks</strong></td>
<td>As the name suggests, this component allows attaching intermediate logic in the execution of your chains.</td>
</tr>
</tbody>
</table><!--kg-card-end: html--><h3 id="typical-use-cases">Typical Use Cases</h3><p>With the concept of <em>Runnable</em>, all components are independent and can be chained or nested. However, it is not necessary to always use all of the components as illustrated below.</p><h4 id="basic-qa">Basic Q&amp;A</h4><figure class="kg-card kg-image-card kg-card-hascaption"><img src="http://blog.cemsoyding.com/content/images/2023/10/basic_qa.png" class="kg-image" alt="Langchain : introduction" loading="lazy" width="330" height="86"><figcaption>Basic Q&amp;A</figcaption></figure><p>The simplest approach for using an LLM is to instantiate it and call it with a query to obtain a response. This solution is based entirely on the default training of the LLM.</p><pre><code class="language-js">import { OpenAI } from &quot;langchain/llms/openai&quot;;
import * as dotenv from &apos;dotenv&apos;;

// Load your .env file containing your private api keys
dotenv.config();
// Create the LLM
const llm = new OpenAI({});
// Call the LLM
const res = await llm.call(&quot;Tell me a joke&quot;);
// Print the output
console.log(res);
</code></pre><h4 id="chain-with-advanced-prompt">Chain with Advanced Prompt</h4><p>When you want to add context to the prompt to achieve better results, the use of a <code>PromptTemplate</code> is helpful.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="http://blog.cemsoyding.com/content/images/2023/10/prompt_template.png" class="kg-image" alt="Langchain : introduction" loading="lazy" width="359" height="156"><figcaption>Using prompt template</figcaption></figure><pre><code class="language-js">import { OpenAI } from &quot;langchain/llms/openai&quot;;
import * as dotenv from &apos;dotenv&apos;;

// Load your .env file containing your private api keys
dotenv.config();
// Create parametric prompt
const promptTemplate = new PromptTemplate({
    template: &quot;Give me a {adjective1} and {adjective2} name for my watch manufacturing company&quot;, 
    inputVariables: [&apos;adjective1&apos;, &apos;adjective2&apos;]
})
// Create the LLM
const llm = new OpenAI({ temperature : 1 });
// Create a chain
const chain = new LLMChain({
    llm: llm,
    prompt: promptTemplate
});
// Execute chain
const res = await chain.call({
    adjective1: &quot;friendly&quot;, 
    adjective2: &quot;innovative&quot;
});
// Print the output
console.log(res.text);
</code></pre><p>Please note that the LLM has been configured to be creative with the <code>temperature</code> parameter. <code>0</code> makes the LLM precise, while <code>1</code> makes it imaginative. Feel free to use intermediate values to gauge the creativity of your LLM.</p><h4 id="chain-with-memory">Chain with Memory</h4><p>In the following example, we define a buffer for storing messages exchanged with the AI. Memories are primarily used for chatbot-type applications.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="http://blog.cemsoyding.com/content/images/2023/10/memory_chatbot.png" class="kg-image" alt="Langchain : introduction" loading="lazy" width="388" height="217"><figcaption>Adding memory to a conversation chain</figcaption></figure><pre><code class="language-js">import { OpenAI } from &apos;langchain/llms/openai&apos;;
import { BufferMemory } from &apos;langchain/memory&apos;;
import { ConversationChain } from &apos;langchain/chains&apos;;
import * as dotenv from &apos;dotenv&apos;;

// Load .env
dotenv.config();

// Declare model
const model = new OpenAI({});
const memory = new BufferMemory();
const chain = new ConversationChain({
    llm: model,
    memory
});

const res1 = await chain.call({
    input: &quot;Hi I&apos;m Jimmy&quot;
});

const res2 = await chain.call({
    input: &quot;What is my name ?&quot;
}); // outputs Jimmy thanks to memory
</code></pre><h4 id="indexes">Indexes</h4><p>Information extraction from external documents is done through a pipeline that involves loading the text, breaking it down, and transforming it into vectors that are then stored in a database. This storage can be injected into a chain to enhance the quality of the response.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="http://blog.cemsoyding.com/content/images/2023/10/indexes.png" class="kg-image" alt="Langchain : introduction" loading="lazy" width="552" height="168"><figcaption>The pipeline of document conversion into embeddings</figcaption></figure><pre><code class="language-js">import { loadQARefineChain } from &quot;langchain/chains&quot;;
import { OpenAI } from &quot;langchain/llms/openai&quot;;
import { TextLoader } from &quot;langchain/document_loaders/fs/text&quot;;
import { MemoryVectorStore } from &quot;langchain/vectorstores/memory&quot;;
import { OpenAIEmbeddings } from &quot;langchain/embeddings/openai&quot;;

// Create the models and chain
const embeddings = new OpenAIEmbeddings();
const model = new OpenAI({ temperature: 0 });
const chain = loadQARefineChain(model);

// Load the documents and create the vector store
const loader = new TextLoader(&quot;./my_grandma_recpies.txt&quot;);
const docs = await loader.loadAndSplit();
// Store it in memory 
const store = await MemoryVectorStore.fromDocuments(docs, embeddings);

// Select the relevant documents
const question = &quot;What&apos;s the recipe of french crepes ?&quot;;
const relevantDocs = await store.similaritySearch(question);

// Call the chain
const res = await chain.call({
  input_documents: relevantDocs,
  question,
});

console.log(res);
</code></pre><p>The <code>TextSplitter</code> divides the large initial text (using <code>\n</code>, <code>\n\n</code>, and <code> </code>) into smaller pieces to optimize searching with the <code>similaritySearch</code> call. These smaller chunks of text are then transformed into vectors (or <code>Embeddings</code>) relative to the selected model. This means that the number of dimensions in your vector will vary depending on the model you&apos;re working with. There are different vector comparison algorithms:</p><ul><li><code>dot product</code>: a scalar value representing the sum of the products of vector magnitudes</li><li><code>cosine similarity</code>: the cosine of the angle between two vectors, calculated by dividing the dot product of the vectors by the product of their magnitudes.</li></ul><p>The closer the result is to <code>1</code>, the closer the vectors are. The number of vector dimensions plays a significant role in your model&apos;s performance. A higher number of dimensions leads to longer computations. So, while accuracy increases with dimension, performance decreases.</p><h4 id="agents">Agents</h4><p>With agents, you enter the world of automation. You have the option to integrate tools that complement your LLM&apos;s capabilities. The most impressive aspect here is that the agent is controlled by an <code>Executor</code>, which will iteratively process the initial request until the final result is obtained. Thus, the request will be internally evaluated and broken down into a series of actions delegated to the LLM or one of the tools. The response will then be assessed, determining the necessary next steps for constructing the response.</p><figure class="kg-card kg-image-card"><img src="http://blog.cemsoyding.com/content/images/2023/10/agent.png" class="kg-image" alt="Langchain : introduction" loading="lazy" width="371" height="309"></figure><pre><code class="language-js">import { OpenAI } from &apos;langchain/llms/openai&apos;;
import {SerpAPI} from &apos;langchain/tools&apos;;
import {Calculator} from &apos;langchain/tools/calculator&apos;;
import {initializeAgentExecutorWithOptions} from &apos;langchain/agents&apos;;
import * as dotenv from &apos;dotenv&apos;;

// Load .env
dotenv.config();

// Declare model
const model = new OpenAI({
    temperature: 0
});

// Declare tools
const tools = [
    // Google search api
    new SerpAPI(process.env.SERPAPI_API_KEY, {
        hl: &apos;en&apos;,
        gl: &apos;us&apos;,
    }),
    new Calculator()
];

// Create agent
const executor = await initializeAgentExecutorWithOptions(tools, model, {
    agentType: &quot;zero-shot-react-description&quot;,
    verbose: true, // debugging feature tracing all intermediate steps
});

// Execute agent
const res = await executor.call({
    input: &quot;prompt&quot;,

})
</code></pre><h2 id="conclusion">Conclusion</h2><p>This first article provides a very schematic overview of the working concepts of Langchain. In the following articles, I will delve into specific cases that make the most of the many tools made available by this framework.</p>]]></content:encoded></item><item><title><![CDATA[I am building an SFFPC]]></title><description><![CDATA[<p>A Small Form Factor PC, or SFFPC, is a compact computer system designed with a significantly smaller volume than a standard ATX tower. To give you a perspective, SFFPCs are often compared to shoeboxes, with a volume of approximately 10 liters. There is an even smaller category known as Ultra</p>]]></description><link>http://blog.cemsoyding.com/i-am-building-an-sffpc/</link><guid isPermaLink="false">652a4a4b760e9500016692e4</guid><dc:creator><![CDATA[Cem Soyding]]></dc:creator><pubDate>Sun, 05 Nov 2023 12:43:39 GMT</pubDate><media:content url="http://blog.cemsoyding.com/content/images/2023/10/my_build_components.JPG" medium="image"/><content:encoded><![CDATA[<img src="http://blog.cemsoyding.com/content/images/2023/10/my_build_components.JPG" alt="I am building an SFFPC"><p>A Small Form Factor PC, or SFFPC, is a compact computer system designed with a significantly smaller volume than a standard ATX tower. To give you a perspective, SFFPCs are often compared to shoeboxes, with a volume of approximately 10 liters. There is an even smaller category known as Ultra Small Form Factor, represented by devices like NUCs and HP Elite, which utilize low-power components commonly found in laptops. However, our focus here lies on the category just above this, as we aim to maximize the use of standard desktop components within a minimized enclosure.</p><p>At first glance, you might think this is a straightforward endeavor, but in reality, it comes with numerous challenges. The limited volume of the enclosure introduces significant constraints, affecting the temperatures during operation. Therefore, it becomes crucial to select an appropriate cooling solution tailored to both your CPU and GPU, as well as the form factor of your case. Not everything will fit, and this also applies to other components like the graphics card, whose dimensions increase with each generation, thus requiring a delicate balancing act.</p><figure class="kg-card kg-image-card"><img src="http://blog.cemsoyding.com/content/images/2023/10/sffpc_size_comparison_2_bis.png" class="kg-image" alt="I am building an SFFPC" loading="lazy" width="792" height="591" srcset="http://blog.cemsoyding.com/content/images/size/w600/2023/10/sffpc_size_comparison_2_bis.png 600w, http://blog.cemsoyding.com/content/images/2023/10/sffpc_size_comparison_2_bis.png 792w" sizes="(min-width: 720px) 720px"></figure><p>Another crucial consideration is noise. While it might not be a top priority for gamers who play with headphones on, individuals utilizing the computer for resource-intensive tasks such as 3D rendering or video editing prefer a silent PC. However, cooling solutions can often be noisy, leading to yet another decision to be made.</p><p>It&apos;s worth reiterating that temperature is the arch-nemesis of performance in a PC, and the goal here is to achieve maximum performance. As you gain a better understanding of the challenges of this PC form factor, you&apos;ll need to skillfully select your components to strike the right balance among volume, temperature, performance, and noise.</p><figure class="kg-card kg-image-card"><img src="http://blog.cemsoyding.com/content/images/2023/10/lc5lmw613ne81.jpg" class="kg-image" alt="I am building an SFFPC" loading="lazy" width="2000" height="2000" srcset="http://blog.cemsoyding.com/content/images/size/w600/2023/10/lc5lmw613ne81.jpg 600w, http://blog.cemsoyding.com/content/images/size/w1000/2023/10/lc5lmw613ne81.jpg 1000w, http://blog.cemsoyding.com/content/images/size/w1600/2023/10/lc5lmw613ne81.jpg 1600w, http://blog.cemsoyding.com/content/images/size/w2400/2023/10/lc5lmw613ne81.jpg 2400w" sizes="(min-width: 720px) 720px"></figure><p>Additionally, there&apos;s the cost factor to consider, as building an SFFPC typically comes at a higher price.</p><p>At this juncture, you should be in a position to choose your path:</p><ul><li>If you lean towards getting the most performance at the lowest cost and aren&apos;t bothered by the size of the PC, then sticking with ATX is the way to go.</li><li>However, if you have a penchant for challenges and value the compact size of your PC, welcome to my first guide, which aims to assist you in choosing your components.</li></ul><h2 id="processor">Processor </h2><h3 id="tdp">TDP</h3><p>The Thermal Design Power (TDP), expressed in watts, serves as an indicator of a processor&apos;s heat output, distinct from its actual power consumption. This value plays a pivotal role in the selection of an appropriate cooling solution for your system. Going beyond a processor&apos;s designated TDP can result in thermal throttling, a process where the CPU&apos;s frequency is deliberately lowered to avert overheating. Operating electronic components at elevated temperatures not only compromises their performance but can also induce anomalies, failures, and even permanent damage. The TDP figure is influenced by a combination of factors, encompassing the process node, number of transistors, cores, voltage, cache size, and the presence and utilization of an integrated GPU. Careful consideration of these variables is essential to ensure your processor functions optimally while maintaining safe thermal conditions.</p><figure class="kg-card kg-image-card"><img src="http://blog.cemsoyding.com/content/images/2023/10/throttling.png" class="kg-image" alt="I am building an SFFPC" loading="lazy" width="725" height="383" srcset="http://blog.cemsoyding.com/content/images/size/w600/2023/10/throttling.png 600w, http://blog.cemsoyding.com/content/images/2023/10/throttling.png 725w" sizes="(min-width: 720px) 720px"></figure><h3 id="manufacturer-intel-vs-amd">Manufacturer : Intel vs AMD</h3><p>When it comes to CPU manufacturers, the two main players are AMD and Intel. Intel is often favored for its superior performance and overall value for money, making it an attractive choice for many users. However, it&apos;s essential to note that Intel processors typically exhibit higher power consumption, which can pose challenges for Small Form Factor PCs (SFFPCs) unless equipped with expensive cooling solutions. In the realm of SFFPCs, where power efficiency is of paramount importance, AMD emerges as a more favorable alternative. Notably, there are several intriguing SFFPC processors on the market, including the i5-13600K, Ryzen 7-7700X, and, particularly for gaming enthusiasts, the Ryzen 7-5800X3D, each offering a unique blend of performance and efficiency tailored to the demands of compact computing.</p><figure class="kg-card kg-image-card"><img src="http://blog.cemsoyding.com/content/images/2023/10/Intel_gegen_AMD.jpg" class="kg-image" alt="I am building an SFFPC" loading="lazy" width="1240" height="700" srcset="http://blog.cemsoyding.com/content/images/size/w600/2023/10/Intel_gegen_AMD.jpg 600w, http://blog.cemsoyding.com/content/images/size/w1000/2023/10/Intel_gegen_AMD.jpg 1000w, http://blog.cemsoyding.com/content/images/2023/10/Intel_gegen_AMD.jpg 1240w" sizes="(min-width: 720px) 720px"></figure><h3 id="cache">Cache</h3><p>The CPU cache is a vital component that enhances program execution speed. Acting as a high-speed, short-access memory, the cache stores frequently accessed data, reducing the CPU&apos;s reliance on accessing data from the slower system RAM. What sets the cache apart is its remarkable speed; cache access times are notably faster than those of RAM, with various cache levels offering different access times. In resource-intensive tasks like gaming, the cache&apos;s size becomes of paramount importance. A larger cache serves to significantly reduce the CPU&apos;s need to access the system&apos;s RAM, resulting in smoother, more responsive performance, ultimately making it an indispensable asset for demanding computing endeavors.</p><figure class="kg-card kg-image-card"><img src="http://blog.cemsoyding.com/content/images/2023/10/cpuCache.png" class="kg-image" alt="I am building an SFFPC" loading="lazy" width="799" height="711" srcset="http://blog.cemsoyding.com/content/images/size/w600/2023/10/cpuCache.png 600w, http://blog.cemsoyding.com/content/images/2023/10/cpuCache.png 799w" sizes="(min-width: 720px) 720px"></figure><h3 id="socket">Socket</h3><p>The CPU socket serves as the physical interface connecting your CPU to the motherboard. It plays a pivotal role in ensuring compatibility between your selected processor and motherboard. Different CPUs are designed to fit specific socket types, so matching them correctly is crucial. For example, the Ryzen 7-7700X utilizes the AM5 socket, the Ryzen 5-5800X is compatible with the AM4 socket, and the i5-13600K pairs with the LGA1700 socket. This careful alignment of CPU and socket is essential.</p><h3 id="ram-compatibility">RAM compatibility</h3><p>Matching your RAM to your CPU is a critical consideration, as RAM size and frequency compatibility can vary. Adhering to the manufacturer&apos;s specified limits is essential to ensure optimal performance and system stability. For instance, the Ryzen 7-7700X supports a maximum of DDR5-5200 RAM and the Ryzen 5-5800X is compatible with up to DDR4-3200. Understanding and adhering to these limits ensures your CPU and RAM work seamlessly together to deliver the best possible performance for your specific computing needs.</p><figure class="kg-card kg-image-card"><img src="http://blog.cemsoyding.com/content/images/2023/10/image.png" class="kg-image" alt="I am building an SFFPC" loading="lazy" width="970" height="647" srcset="http://blog.cemsoyding.com/content/images/size/w600/2023/10/image.png 600w, http://blog.cemsoyding.com/content/images/2023/10/image.png 970w" sizes="(min-width: 720px) 720px"></figure><h3 id="overclocking">Overclocking</h3><p>While the prospect of overclocking, which entails boosting a CPU&apos;s clock frequency, might be enticing for some, it contradicts the fundamental principles of Small Form Factor PCs (SFFPCs). Overclocking typically demands a more robust cooling solution and a larger case to manage the increased heat generated. It&apos;s important to note that not all CPUs are designed for overclocking. In Intel&apos;s lineup, models intended for overclocking are labeled with a &quot;K&quot; suffix, signifying their unlocked potential. On the other hand, all AMD Ryzen CPUs support overclocking, providing users with the flexibility to enhance performance within the parameters of their SFFPC build, although it should be approached with caution, keeping thermals and case constraints in mind.</p><h2 id="motherboard">Motherboard</h2><p>When it comes to selecting a motherboard for your SFFPC build, several key considerations can significantly impact your system&apos;s functionality. Once you&apos;ve determined the appropriate CPU socket for your build, the next step is to find a motherboard in the ITX form factor. Here are some crucial aspects to bear in mind during the selection process.</p><h3 id="ram-support">RAM support</h3><p>ITX motherboards have specific limitations, particularly concerning RAM compatibility. Ensure that your chosen motherboard supports the desired RAM type, whether it be DDR5 or DDR4. If your CPU supports DDR5, and your budget allows, opting for this newer standard is often advantageous.</p><figure class="kg-card kg-image-card"><img src="http://blog.cemsoyding.com/content/images/2023/10/image-1.png" class="kg-image" alt="I am building an SFFPC" loading="lazy" width="2000" height="1581" srcset="http://blog.cemsoyding.com/content/images/size/w600/2023/10/image-1.png 600w, http://blog.cemsoyding.com/content/images/size/w1000/2023/10/image-1.png 1000w, http://blog.cemsoyding.com/content/images/size/w1600/2023/10/image-1.png 1600w, http://blog.cemsoyding.com/content/images/size/w2400/2023/10/image-1.png 2400w" sizes="(min-width: 720px) 720px"></figure><h3 id="bios-flashback">BIOS Flashback</h3><p>A valuable feature to look for in a motherboard is the capability to perform a BIOS flashback. This functionality allows you to update or reflash the BIOS without having installed RAM or a CPU. It&apos;s exceptionally convenient for testing new features or accommodating compatibility with new processors, simplifying the upgrade process.</p><h3 id="connectivity">Connectivity</h3><p>Pay close attention to the available connectivity options, as ITX motherboards often have limited space for ports and slots. Your preferences matter here. Whether you prioritize multiple USB-A ports over USB-C or require a 7.1 audio setup, thoroughly examine the motherboard&apos;s specifications to ensure it aligns with your connectivity needs.</p><figure class="kg-card kg-image-card"><img src="http://blog.cemsoyding.com/content/images/2023/10/image-2.png" class="kg-image" alt="I am building an SFFPC" loading="lazy" width="600" height="500" srcset="http://blog.cemsoyding.com/content/images/2023/10/image-2.png 600w"></figure><h3 id="m2-pcie-slots">M.2 PCIe slots</h3><p>ITX motherboards typically feature at least one M.2 PCIe slot for the insertion of M.2 SSDs. These drives are not only compact but also offer high performance. With two M.2 slots, you can dedicate one for booting and the other for data storage, optimizing your storage configuration.</p><figure class="kg-card kg-image-card"><img src="http://blog.cemsoyding.com/content/images/2023/10/image-3.png" class="kg-image" alt="I am building an SFFPC" loading="lazy" width="725" height="484" srcset="http://blog.cemsoyding.com/content/images/size/w600/2023/10/image-3.png 600w, http://blog.cemsoyding.com/content/images/2023/10/image-3.png 725w" sizes="(min-width: 720px) 720px"></figure><h3 id="pcie-slots">PCIe slots</h3><p>Most ITX motherboards come equipped with a single PCIe slot, which is typically used for the graphics card. However, verify the available PCIe version. The communication speed is notably enhanced with PCIe 4 compared to PCIe 3, provided that both your graphics card and CPU support this standard. It&apos;s worth noting that some motherboards may support both versions and can be configured in the BIOS accordingly.</p><h3 id="wifi-6">Wifi 6</h3><p>With Wi-Fi 6 becoming a standard feature, it&apos;s almost expected on modern motherboards. Ensure that your chosen ITX motherboard includes Wi-Fi 6 support, as it offers improved wireless connectivity and performance, ensuring a more seamless online experience for your SFFPC.</p><h2 id="graphic-card">Graphic card</h2><p>Are you a gamer? If not, there&apos;s no need to chase after large, expensive, power-hungry graphics cards. Instead, consider a CPU with integrated graphics (often referred to as an APU in the case of AMD) or an entry-level graphics card.</p><figure class="kg-card kg-image-card"><img src="http://blog.cemsoyding.com/content/images/2023/10/gpu_geforce_3.jpg" class="kg-image" alt="I am building an SFFPC" loading="lazy" width="960" height="720" srcset="http://blog.cemsoyding.com/content/images/size/w600/2023/10/gpu_geforce_3.jpg 600w, http://blog.cemsoyding.com/content/images/2023/10/gpu_geforce_3.jpg 960w" sizes="(min-width: 720px) 720px"></figure><p>For gamers, the current landscape offers a challenging scenario. Graphics cards have soared to exorbitant prices, making it necessary to allocate at least $800 for something decent and potentially up to $1200 for a high-end card.</p><p>The issue doesn&apos;t end there. Graphics card sizes and power consumption are on the rise, requiring careful consideration when selecting your case. If you opt for a minimalist design to maximize space-saving, cooling becomes a significant challenge. Adequate space is necessary for proper airflow or for accommodating cooling solutions, such as liquid cooling.</p><figure class="kg-card kg-image-card"><img src="http://blog.cemsoyding.com/content/images/2023/10/gpu_geforces_2.jpg" class="kg-image" alt="I am building an SFFPC" loading="lazy" width="959" height="720" srcset="http://blog.cemsoyding.com/content/images/size/w600/2023/10/gpu_geforces_2.jpg 600w, http://blog.cemsoyding.com/content/images/2023/10/gpu_geforces_2.jpg 959w" sizes="(min-width: 720px) 720px"></figure><p>Another critical factor to keep in mind with high-end graphics cards is their capacity to run games in 4K at high frame rates. Before diving into the world of 4K gaming, ask yourself the following questions:</p><ul><li>Do you have a monitor capable of handling this resolution and high frame rates?</li><li>Does your motherboard offer the necessary connectivity to utilize these capabilities? A DisplayPort 1.4 port, for instance, allows you to achieve 4K at 120 or 144Hz, while an HDMI port typically limits you to 60Hz.</li></ul><p>Ultimately, the choice is yours and should align with your personal preferences and budget. It&apos;s essential to be honest with yourself about what you truly need from your SFFPC. The allure of an SFFPC lies in the balance between case size and machine power. If you&apos;re seeking excessive power, it might be more practical to opt for an ATX build, which would save you a lot of potential headaches in your pursuit of high-end performance.</p><h2 id="ram">RAM</h2><p>Selecting the appropriate RAM for your Small Form Factor PC (SFFPC) is a crucial step in tailoring your system&apos;s performance to your needs. Here are some key considerations to guide your RAM selection.</p><figure class="kg-card kg-image-card"><img src="http://blog.cemsoyding.com/content/images/2023/10/image-4.png" class="kg-image" alt="I am building an SFFPC" loading="lazy" width="780" height="439" srcset="http://blog.cemsoyding.com/content/images/size/w600/2023/10/image-4.png 600w, http://blog.cemsoyding.com/content/images/2023/10/image-4.png 780w" sizes="(min-width: 720px) 720px"></figure><h3 id="number-of-ram-slots">Number of RAM Slots</h3><p>The number of available RAM slots on your motherboard, as well as their individual capacities, plays a vital role in determining the optimal RAM configuration for your SFFPC. This directly affects your system&apos;s total memory capacity.</p><h3 id="16gb-as-a-starting-point">16GB as a Starting Point </h3><p>As a starting point, 16GB of RAM is a solid choice for most SFFPC builds. It strikes a balance between performance and cost-effectiveness. However, it&apos;s essential to consider the maximum RAM frequency supported by your motherboard. If the motherboard specifies frequencies with an &quot;(o.c)&quot; notation, it means that the default RAM frequency may be lower than the memory module&apos;s maximum capabilities. In such cases, you may need to overclock your RAM from the BIOS to unlock its full potential. We&apos;ll explore the overclocking process in more detail shortly.</p><h3 id="rgb-or-non-rgb">RGB or Non-RGB</h3><p>The inclusion of RGB (colorful LED lighting) on your RAM modules is a matter of personal customization. If you enjoy the aesthetic appeal and wish to add a touch of personal style to your SFFPC, RGB RAM modules can be a fun choice. Prices for RGB and non-RGB RAM modules are typically similar, so this decision ultimately boils down to your personal preferences and whether you prefer the vibrant look or a more understated design for your system.</p><figure class="kg-card kg-image-card"><img src="http://blog.cemsoyding.com/content/images/2023/10/image-5.png" class="kg-image" alt="I am building an SFFPC" loading="lazy" width="678" height="381" srcset="http://blog.cemsoyding.com/content/images/size/w600/2023/10/image-5.png 600w, http://blog.cemsoyding.com/content/images/2023/10/image-5.png 678w"></figure><p>By thoughtfully considering these factors, you can ensure that your RAM selection aligns with the specific needs and objectives of your SFFPC build, ultimately contributing to a well-balanced and customized computing experience.</p><h2 id="power-supply">Power supply </h2><p>Choosing the appropriate power supply unit (PSU) is a critical step in your Small Form Factor PC (SFFPC) build. Here are essential considerations to guide your PSU selection</p><h3 id="calculate-your-systems-power-consumption">Calculate Your System&apos;s Power Consumption</h3><p>Once your system configuration is determined, you have the option to calculate the maximum power your system will consume. Fortunately, there are convenient tools available for this purpose, such as the <a href="https://www.newegg.com/tools/power-supply-calculator/?ref=blog.cemsoyding.com">Newegg Power Supply Calculator</a>, where you simply input your build&apos;s components to obtain the power consumption estimate. For example, a setup featuring a Ryzen 7 7700X, a GeForce RTX 3070Ti graphics card, and 16GB of RAM may reach a consumption level of around 700 watts. In this scenario, opting for a 750W or 800W PSU would be advisable to ensure sufficient power for your system.</p><h3 id="safe-bet-corsair-sf750">Safe bet : Corsair SF750</h3><p>A highly regarded PSU for SFFPCs is the Corsair SF750. Priced at just a little over $150 and boasting an 80 Plus Gold certification, this PSU offers reliability, low noise operation, and minimal heat generation, making it an excellent fit for SFFPCs. The SF750 is known for its compact form factor, ideal for smaller cases, and delivers the power you need without compromising on efficiency or reliability.</p><p>By thoughtfully considering these factors and performing a power consumption calculation, you can ensure your PSU selection aligns with the specific requirements of your SFFPC build, providing the necessary power for your components while maintaining efficiency and reliability.</p><h2 id="cooling-systems">Cooling Systems</h2><p>Effective cooling is a crucial consideration. Here is a brief overview of the most common cooling systems.</p><h3 id="air-cooling">Air Cooling</h3><p>Air cooling relies on large heatsinks and fans to dissipate heat from your components. While it&apos;s cost-effective and readily available, it can be relatively bulky and might generate more noise compared to other cooling options.</p><figure class="kg-card kg-image-card"><img src="http://blog.cemsoyding.com/content/images/2023/10/image-11.png" class="kg-image" alt="I am building an SFFPC" loading="lazy" width="474" height="474"></figure><h3 id="aio-all-in-one-liquid-cooling">AIO (All-In-One) Liquid Cooling</h3><p>AIO cooling systems combine elements of both air and liquid cooling. They consist of a fluid circuit with a radiator that features one, two, or even three fans. AIO coolers are known for their excellent efficiency, requiring minimal maintenance. Over the years, their reliability has significantly improved. Although they are pricier than air coolers, their cost-to-performance ratio is compelling. A 240mm AIO cooler, ideal for SFFPCs, typically costs around $100. If it fits in your case, it&apos;s a solid choice.</p><figure class="kg-card kg-image-card"><img src="http://blog.cemsoyding.com/content/images/2023/10/image-10.png" class="kg-image" alt="I am building an SFFPC" loading="lazy" width="2000" height="1414" srcset="http://blog.cemsoyding.com/content/images/size/w600/2023/10/image-10.png 600w, http://blog.cemsoyding.com/content/images/size/w1000/2023/10/image-10.png 1000w, http://blog.cemsoyding.com/content/images/size/w1600/2023/10/image-10.png 1600w, http://blog.cemsoyding.com/content/images/size/w2400/2023/10/image-10.png 2400w" sizes="(min-width: 720px) 720px"></figure><h3 id="custom-liquid-cooling-loop">Custom Liquid Cooling Loop</h3><p>For the DIY enthusiasts with deep pockets, custom liquid cooling loops offer an irresistible aesthetic. They allow for personalization, letting you choose the liquid color to match your preferences. However, these systems can be extremely expensive, with costs easily adding up for tubing, fittings, reservoirs, and pumps, often reaching around $800 or more. Furthermore, due to their complexity, custom liquid cooling systems are more susceptible to issues like leaks and malfunctions. Nevertheless, water cooling remains the most efficient cooling solution, capable of adapting to your graphics card, delivering exceptional silence and outstanding performance&#x2014;when it&apos;s working as intended.</p><figure class="kg-card kg-image-card"><img src="http://blog.cemsoyding.com/content/images/2023/10/image-12.png" class="kg-image" alt="I am building an SFFPC" loading="lazy" width="960" height="769" srcset="http://blog.cemsoyding.com/content/images/size/w600/2023/10/image-12.png 600w, http://blog.cemsoyding.com/content/images/2023/10/image-12.png 960w" sizes="(min-width: 720px) 720px"></figure><p>Each cooling system has its advantages and drawbacks, making it essential to consider your priorities and budget when selecting the right cooling solution for your SFFPC build.</p><h3 id="cable-management">Cable Management</h3><p>Finally, let&apos;s address the issue of cables. Power supply units come with relatively long cables designed to accommodate a wide range of PC configurations. While this versatility is beneficial, it may not be the best fit for your specific SFFPC build. Consequently, you&apos;ll be left with a multitude of cables to manage neatly, adding another layer to the challenges of building an SFFPC.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="http://blog.cemsoyding.com/content/images/2023/10/image-13.png" class="kg-image" alt="I am building an SFFPC" loading="lazy" width="2000" height="1500" srcset="http://blog.cemsoyding.com/content/images/size/w600/2023/10/image-13.png 600w, http://blog.cemsoyding.com/content/images/size/w1000/2023/10/image-13.png 1000w, http://blog.cemsoyding.com/content/images/size/w1600/2023/10/image-13.png 1600w, http://blog.cemsoyding.com/content/images/2023/10/image-13.png 2000w" sizes="(min-width: 720px) 720px"><figcaption>Cable management will improve the aesthetics and air flow of your build</figcaption></figure><p>Fortunately, some online stores offer custom-made cables tailored to specific cases or requirements. These cables can be customized in terms of color, and some even support RGB lighting, allowing you to further personalize your build. However, this level of customization comes at a price. Some custom cables can cost up to $50 each, and you&apos;ll likely need at least three or four to ensure your SFFPC looks both clean and organized.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="http://blog.cemsoyding.com/content/images/2023/10/image-14.png" class="kg-image" alt="I am building an SFFPC" loading="lazy" width="2000" height="2000" srcset="http://blog.cemsoyding.com/content/images/size/w600/2023/10/image-14.png 600w, http://blog.cemsoyding.com/content/images/size/w1000/2023/10/image-14.png 1000w, http://blog.cemsoyding.com/content/images/size/w1600/2023/10/image-14.png 1600w, http://blog.cemsoyding.com/content/images/size/w2400/2023/10/image-14.png 2400w" sizes="(min-width: 720px) 720px"><figcaption>Custom cables can make a huge difference</figcaption></figure><p>Efficient cable management is a vital aspect of your SFFPC build, as it not only enhances the aesthetics of your system but also aids in optimizing airflow and cooling. So, while it may add an extra expense, it&apos;s an investment that can greatly improve the overall functionality and appearance of your compact powerhouse.</p><h2 id="conclusion">Conclusion</h2><p>Picking the right components takes time and you should take it if you want to complete and enjoy the sffpc of your dreams.</p><p>In my next article, I&apos;ll address the selection of the case which should naturally come at the end of the selection process to be sure that everything fits in with ideal thermal conditions.</p>]]></content:encoded></item><item><title><![CDATA[Javascript: advanced]]></title><description><![CDATA[<p>This is already my 10th article about javascript&apos;s programming syntax. Today, I&apos;m stepping into some of the <em>advanced</em> features that appeared with ES6+ revisions. Read it carefully since many of these concepts are fundamental if you&apos;re planning to learn <em>React</em> &#xA0;for instance.</p><p>The</p>]]></description><link>http://blog.cemsoyding.com/javascript-advanced/</link><guid isPermaLink="false">6528ff39760e95000166925e</guid><dc:creator><![CDATA[Cem Soyding]]></dc:creator><pubDate>Thu, 02 Nov 2023 08:40:32 GMT</pubDate><media:content url="http://blog.cemsoyding.com/content/images/2023/10/JavaScript_Logo.png" medium="image"/><content:encoded><![CDATA[<img src="http://blog.cemsoyding.com/content/images/2023/10/JavaScript_Logo.png" alt="Javascript: advanced"><p>This is already my 10th article about javascript&apos;s programming syntax. Today, I&apos;m stepping into some of the <em>advanced</em> features that appeared with ES6+ revisions. Read it carefully since many of these concepts are fundamental if you&apos;re planning to learn <em>React</em> &#xA0;for instance.</p><p>The following features appeared with latest javascript revisions (ES6 and beyond).</p><h3 id="template-literal-string">Template literal string</h3><p>This operator is similar to <code>$&quot;&quot;</code> in C# as it allows you to create interpolated strings.<br>The syntax is a bit different here as show below.</p><pre><code class="language-js">const car = {
    model: &apos;Toledo&apos;,
    vendor: &apos;Seat&apos;
};

// Use ${} inside back ticks to interpolate data
console.log(`${car.vendor} ${car.model}`); // Seat Toledo
</code></pre><h3 id="destructuring">Destructuring</h3><p>Unpacks values from arrays or objects into distinct variables.</p><pre><code class="language-js">// Array destructuring
let [x, y] = [24, -5];
console.log(x, y); // 24 -5

[x, y] = [8, 6, 8]; // remaining items are ignored
console.log(x, y); // 8 6

// Works on any iterable
let [pair1, pair2] = new Map([
    [&apos;H&apos;, &apos;Hydrogen&apos;],
    [&apos;O&apos;, &apos;Oxygen&apos;],
]);
console.log(pair1, pair2); // [&apos;H&apos;, &apos;Hydrogen&apos;], [&apos;O&apos;, &apos;Oxygen&apos;]

// Object destructuring (since ES2018)
const person = { name: &apos;Oliver&apos;, age: 25 };
let { name, age } = person;
console.log(name, age); // &apos;Oliver&apos; 25
person.age = 24; // has no effect on destructured items
console.log(name, age); // &apos;Oliver&apos; 25
</code></pre><p><strong>Important</strong>: when using object destructuring, keep in mind that you&apos;re collection the properties of an input object. So the variables names used on left-hand necessarily point to a property with the same name. You can use <code>:</code> to specify the target variable if you want to use a different name.</p><p>You can use 2 sytaxes : <em>binding pattern</em> and <em>assignment pattern</em>.</p><pre><code class="language-js">const car = { vendor: &apos;Fiat&apos;, model: &apos;Punto&apos;, mileage: 14578 };

// binding pattern requires &apos;var&apos;, &apos;let&apos;, or &apos;const&apos;
// &apos;mileage&apos; receives the value
const { mileage } = car;

let carProperties = [];
// assignment pattern requires parenthesis
// left hand declares the target of assignment thanks to &apos;:&apos;
({ vendor: carProperties[0], model: carProperties[1] } = car);
console.log(carProperties); // [&apos;Fiat&apos;, &apos;Punto&apos;]
</code></pre><p>Finally, note that a destructured property can have a default value, used if input value is <code>undefined</code> or absent.</p><pre><code class="language-js">const [x = 0] = []; // x = 0
const {x = 0, y = 1} = { x: undefined, y: null }; // x = 0, y = null
</code></pre><h3 id="rest-operator"><em>Rest</em> operator</h3><p>Use <em>rest</em> operator (<code>...rest</code>) to end destructuring and collect all remaining properties of an object.</p><pre><code class="language-js">const [a, b, ...remaining] = [24, -5, 8, 6, 8]; 
console.log(a, b, remaining); // 24 -5 [8, 6, 8]

// You can also use binding pattern as the rest property
// don&apos;t forget that you destructure input object, so here you read the length
// property of input array, to use it later in a new const with the same name
const [x, y, ...{ length }] = [24, -5, 8, 6, 8];
console.log(x, y, length); // 24 -5 1
</code></pre><h3 id="spread-operator"><em>Spread</em> operator</h3><p>Syntactically similar to <em>Rest</em> operator, <em>Spread</em> syntax can be used to expand elements from an object or an array into a new array or object.</p><pre><code class="language-js">const firstCounts = [0,1,2];
const allCounts = [...firstCounts,3,4,5];
console.log(allCounts); // [0,1,2,3,4,5]

// Handy when passing arguments to a method
const dateFields = [1970, 0, 1]; // 1 Jan 1970
const d = new Date(...dateFields);

// You can also use it to copy an arra
let copy = [...firstCounts]; // same as firstCounts.slice()

// It works with objects as well. Here, we merge two objects
const engine = { power: &apos;120hp&apos;, cylinders: 8 };
const design = { doors: 5, length: &apos;9ft&apos;, width: &apos;4ft&apos; };
const car = { ...engine, ...design };
</code></pre><h3 id="object-literal-improvements">Object literal improvements</h3><p>For reminder, object literals let you create an object on the fly, without the <code>class</code> keyword.</p><pre><code class="language-js">var car = {
  fuel: &apos;SP95&apos;,
  model: &apos;208&apos;,
  vendor: &apos;Peugeot&apos;,
  mileage: 125478,
  printMileage: function() {
    console.log(mileage);
  }
};
</code></pre><p>ES6 improved these declarations in many ways:</p><pre><code class="language-js">// initialization from variables
// no need to write repetitive things like &apos;a: a, b: b&apos;
const a = 3, b = &apos;Notre Dame&apos;;
const myObject = {
    a // same as a:a
    b // same as b:b
}

// shortened method definition
const robot {
    // same as &apos;moveLeft: function(d) {}&apos; in ES5
    moveLeft(d) { /* code */ },
    // or arrow syntax
    // same as &apos;moveRight: function(d) {}&apos; in ES5
    moveRight: (d) =&gt; /* code */
}
</code></pre><h3 id="null-coalescing-operator">Null coalescing operator</h3><p>Similar to C# but here, the <code>??</code> operator also works with <code>undefined</code>.</p><pre><code class="language-js">let a = null ?? &quot;default&quot;;
let b = undefined ?? &quot;value&quot;;
console.log(a, b); // default value
</code></pre><h3 id="null-coalescing-assignment">Null coalescing assignment</h3><p>With almost the same syntax, you can set the value of a variable if it is <code>null</code> or <code>undefined</code></p><pre><code class="language-js">let b = null;
let a ??= &quot;default&quot;;
let b ??= &quot;value&quot;;
console.log(a, b); // default value
</code></pre><h3 id="optional-chaining">Optional chaining</h3><p>Similar to C# but returns <code>undefined</code> instead of null.</p><pre><code class="language-js">const obj = { 
    name: &apos;John&apos;, 
    house: {
        address : &apos;45 johnson street&apos;,
        city: &apos;Malibu&apos;
    },
    dog : null,
};
console.log(obj.house.garage?.surface); // undefined
console.log(obj.dog?.name); // undefined
</code></pre><h3 id="symbol"><code>Symbol</code></h3><p>Symbols solves an issue that appeared with the flexibility of javascript, ahich allows you to add keys into your objects from all over the place.<br>At some point, one might override an existing key by redefining it again which would obvisouly introduce issues in code.</p><p>A <code>Symbol</code> is a new type of primitive in ES6 and its purpose is to create unique keys that you can then use to in your object. In a sense, it comes close to an enum value with a unique reference.</p><pre><code class="language-js">// Consider the following object
const jet {};
jet[&quot;company&quot;] = &apos;Js arilines&apos;;
console.log(jet); // { company: &apos;Js arilines&apos;}

// Anyone can alter existing key in the codebase
jet[&quot;company&quot;] = &apos;Airbus&apos;;
console.log(jet); // { company: &apos;Airbus&apos;}

// To prevent this type of accident, use Symbols
// A symbol can be declare with Symbol() with an optional
// input description that you can reuse later to provide context
// The description does not identify the symbol, it it is purely informative
let company = Symbol(&quot;The airline company&quot;);
// Now you can add this as a key in the object
jet[company] = &apos;Js airline&apos;;

console.log(jet); // { company: &apos;Airbus&apos;, [Symbol(The airline company)]: &apos;Js airline&apos;}

// Now you can only access the property you created with THE symbol
console.log(jet[company]); 
console.log(jet[Symbol(&quot;The airline company&quot;)]); // undefined 

// Here is another example
const color = {};
let red = Symbol(&apos;R&apos;);
let green = Symbol(&apos;G&apos;);
let blue = Symbol(&apos;B&apos;);
color[red] = 145;
color[green] = 0;
color[blue] = 60;
// unless you have access to &apos;red&apos;, &apos;green&apos;, &apos;blue&apos;,
// you can&apos;t edit color[red], color[green] and color[blue]
</code></pre>]]></content:encoded></item><item><title><![CDATA[Javascript: modules]]></title><description><![CDATA[<p>8th article in my exploratory work on javascript and this time I sched light on javascript modules system.</p><p>Javascript modules let you to break up your code into separate files.</p><pre><code class="language-js">&lt;script type=&quot;module&quot; src=&quot;person.js&quot;&gt;&lt;/script&gt;
</code></pre><p>By default, the code written</p>]]></description><link>http://blog.cemsoyding.com/javascript-modules/</link><guid isPermaLink="false">6523f4704127b30001b624c6</guid><dc:creator><![CDATA[Cem Soyding]]></dc:creator><pubDate>Tue, 31 Oct 2023 12:56:53 GMT</pubDate><media:content url="http://blog.cemsoyding.com/content/images/2023/10/JavaScript-logo-8.png" medium="image"/><content:encoded><![CDATA[<img src="http://blog.cemsoyding.com/content/images/2023/10/JavaScript-logo-8.png" alt="Javascript: modules"><p>8th article in my exploratory work on javascript and this time I sched light on javascript modules system.</p><p>Javascript modules let you to break up your code into separate files.</p><pre><code class="language-js">&lt;script type=&quot;module&quot; src=&quot;person.js&quot;&gt;&lt;/script&gt;
</code></pre><p>By default, the code written in a js file is not exported.<br>Explicit <code>export</code> keywords should be used to export variables or functions and transform your javascript file into a javascript module.</p><pre><code class="language-js">// The following consts are visible to all other javascript code since 
// they&apos;re declared in the global space
export const name = &quot;Ben&quot;;
export const age = 12;
</code></pre><p>It is also possible to declare a <code>default export</code> as shown below:</p><pre><code class="language-js">function foo() {
    ...
}
// Only 1 default export is allowed per file
export default foo;
</code></pre><p>The difference is in how the module is used in other js files:</p><pre><code class="language-js">import { name, age } from &quot;person.js&quot;; // several exports
import foo from &quot;person.js&quot;; // default export
</code></pre><p><strong>Note</strong>: <code>import</code> is only allowed for scripts declared with <code>type=&quot;module&quot;</code></p><h3 id="legacy-module-systems">Legacy module systems</h3><p>This is where it gets confusing.</p><p>Since javascript did not initially have any standardized module system, the community created many of them :</p><!--kg-card-begin: html--><table>
<thead>
<tr>
<th>Name</th>
<th>Description</th>
<th>Code example</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>CJS</code></td>
<td>CommonJS, defined for back-end code.</td>
<td>Export: <code>module.exports = function sendEmail{ ... }</code> Import: <code>const myModule = require(&apos;./sendEmail.js&apos;)</code>. When you import a module, you synchronously get a copy of the module</td>
</tr>
<tr>
<td><code>AMD</code></td>
<td>Asynchronous Module Definition, defined for front-end code.</td>
<td>Import: <code>define(function(require) { var sendEmail = require(&apos;./sendEmail.js); return function() { /* do something  */ }})</code>. The syntax is less intuitive. Here, the import is done asynchronously.</td>
</tr>
<tr>
<td><code>UMD</code></td>
<td>Universal Module Definition, works on front and back ends. UMD is a pattern used to configure several module systems. It is actually some code that&apos;ll check which module system is in use and adapt the import.</td>
<td><code>if(typeof define === &quot;function&quot; &amp;&amp; define.amd) { /* AMD */} else if(typeof exports == &quot;object&quot;) { /* UMD */} ...</code></td>
</tr>
</tbody>
</table><!--kg-card-end: html--><p>Luckily, ES6 introduced a standard called <code>ESM</code> (for ES Modules) and this is what we will focus on. The code examples given in the first section are leveraging <code>ESM</code> :</p><pre><code class="language-js">import { units, convertUnit } from &apos;./physics&apos;;
</code></pre><pre><code class="language-js">export const units = [&quot;Meter&quot;, &quot;Centimeter&quot;, &quot;Inch&quot;];
export function convertUnit(input {
    // ...
});
</code></pre><p><strong>Note</strong>: <em>Node.js</em> uses <code>CJS</code> by default but there several ways of enabling <code>ESM</code> as described <a href="https://www.geeksforgeeks.org/how-to-use-an-es6-import-in-node-js/?ref=blog.cemsoyding.com">here</a></p><h3 id="npm">npm</h3><p><code>npm</code> is the module management utility in <em>Node.js</em>. You can use it to install 3rd party modules with a very simple syntax:</p><pre><code>npm i &lt;module_name&gt;
</code></pre><h2 id="tree-shaking">Tree-shaking</h2><p>There are several ways of importing code with <code>ESM</code>:</p><pre><code class="language-js">// Import a default export called &apos;alpha&apos; in module.js
import alpha from &quot;./module.js&quot;;

// Import all exports from a module
import * as services from &quot;./services.js&quot;;

// Import some exports from a module (with or without an alias)
import { getVersion, getWindowHeight as getHeight } from &quot;./services.js&quot;;

// Import none but execute the global code of a js file
import &quot;./setContext.js&quot;;

// Use import as an async function
let module = await import(&quot;./hotcoffee.js&quot;);
// or
import(&quot;./hotcoffee.js&quot;).then((module) =&gt; {
    // Do something
});

// Usages
console.log(alpha());
console.log(services.printVersion());
console.log(getVersion());
console.log(getHeight());
</code></pre><p>One thing that you should keep in mind: javascript is an expensive resource. It has to be decompressed, parsed, compiled and executed. As a consequence a common technique applied by developers, called <em>code splitting</em>, consists in splitting your code into small chunks which only contain the required code for a route or a component. It reduces the overall memory footprint and the execution time. Although efficient, it is complicated to apply in big codebases and this is where <em>tree shaking</em> helps.</p><p><em>Tree shaking</em> is a good practice forcing you to only pick the exports you need instead of importing the whole file. It basically says:</p><ul><li>Do this: <code>import {a, b, c} from &quot;./devices.js</code>;</li><li>Instead of this: <code>import * as devices from &quot;./devices.js</code></li></ul><p><em>Module bundlers</em> do that out of the box.</p><h2 id="module-bundlers">Module bundlers</h2><p>Nowadays, you don&apos;t manually include your js dependencies in your html files. Instead, you bundle them into a static file that you can load with a single line of code.</p><pre><code class="language-html">&lt;!-- No more this --&gt;
&lt;script type=&apos;text/javascript&apos; src=&apos;devices.js&apos;&gt;&lt;/script&gt;
&lt;script type=&apos;text/javascript&apos; src=&apos;serial.js&apos;&gt;&lt;/script&gt;
&lt;script type=&apos;text/javascript&apos; src=&apos;shared.js&apos;&gt;&lt;/script&gt;
&lt;script type=&apos;text/javascript&apos; src=&apos;main.js&apos;&gt;&lt;/script&gt;

&lt;!-- but this --&gt;
&lt;script type=&apos;text/javascript&apos; src=&apos;bundle.js&apos;&gt;&lt;/script&gt;
</code></pre><p><em>A bundler is a tool that combines multiple javascript files into a single one for production.</em></p><p>In the <em>dependency resolution</em> phase, the bundler scans all of your dependencies (and their dependencies) to build a <em>dependency graph</em>. This graph is then used to get rid of unused files, prevent naming conflicts, etc ...</p><p>Then the bundling starts in a phase known as <em>packing</em> where the dependency graph is leveraged to integrate the code files, inject required functions and return a single executable bundle that can be loaded by your browser. Things like <em>code splitting</em> or <em>tree-shaking</em> are often applied during the process.</p><h3 id="popular-bundlers">Popular bundlers</h3><p>There are several bundlers out there such as <code>Webpack</code>, <code>parcel</code> or <code>rollup</code>. They usually require a config file where you specify the main js file (i.e. root of your dependency graph) and the name of the output file (ex: <code>bundle.js</code>).</p><h4 id="ex-rollup">Ex: Rollup</h4><p>To use <code>Rollup</code> in your app, start by adding the package</p><pre><code>npm i rollup
</code></pre><p>Then add some configuration:</p><pre><code class="language-js">export default {
    input: &apos;src/main.js&apos;,
    output: {
        file: &apos;bundle.js&apos;,
        format: &apos;cjs&apos;
    }
}
</code></pre><h2 id="relative-vs-absolute-paths">Relative vs Absolute paths</h2><p>As a closing note, I&apos;d like to emphasize that you should, as much as possible, avoid relative paths when importing your modules. Relative paths can quickly become difficult to read when reaching a distant js file (i.e. <code>..\..\components\myModule.js</code>). You should prefer using absolute paths to improve the overall readability (i.e. <code>components\myModule.js</code>).</p><p>You will start by configuring your environment to define the <em>root path</em>. Here are the common options:</p><ul><li>Webpack:</li></ul><pre><code class="language-js">// webpack.config.json
resolve: {
  alias: {
    components: path.resolve(__dirname, &apos;src/&apos;)
  }
}
</code></pre><ul><li>React:</li></ul><pre><code class="language-js">// jsconfig.json
{
  &quot;compilerOptions&quot;: {
    &quot;baseUrl&quot;: &quot;src&quot;
  }
}
</code></pre><ul><li>Typescript</li></ul><pre><code class="language-js">// tsconfig.json
{
  &quot;compilerOptions&quot;: {
    &quot;baseUrl&quot;: &quot;src/&quot;,
  }
}
</code></pre><p>then you can use remove the root path from your import paths:</p><pre><code class="language-js">import { engine } from &quot;components/services.js&quot;;
</code></pre>]]></content:encoded></item><item><title><![CDATA[Blazor : how to use OpenCV in a component]]></title><description><![CDATA[<p>Since v3.3.1, OpenCV is available for javascript. It is actually built from LLVM (c++) binaries thanks to <a href="https://emscripten.org/docs?ref=blog.cemsoyding.com">emscripten</a>. The releases are available <a href="https://docs.opencv.org/4.x?ref=blog.cemsoyding.com">here</a>.</p><h4 id="script-size">Script size</h4><p>If you look at the size of the different versions of <code>opencv.js</code>, you&apos;ll see that it ranges from ~4Mb to</p>]]></description><link>http://blog.cemsoyding.com/blazor-using-opencv-in-a-component/</link><guid isPermaLink="false">6521147ca1901100011b4425</guid><dc:creator><![CDATA[Cem Soyding]]></dc:creator><pubDate>Mon, 30 Oct 2023 15:39:00 GMT</pubDate><media:content url="http://blog.cemsoyding.com/content/images/2023/10/Blazor-2.png" medium="image"/><content:encoded><![CDATA[<img src="http://blog.cemsoyding.com/content/images/2023/10/Blazor-2.png" alt="Blazor : how to use OpenCV in a component"><p>Since v3.3.1, OpenCV is available for javascript. It is actually built from LLVM (c++) binaries thanks to <a href="https://emscripten.org/docs?ref=blog.cemsoyding.com">emscripten</a>. The releases are available <a href="https://docs.opencv.org/4.x?ref=blog.cemsoyding.com">here</a>.</p><h4 id="script-size">Script size</h4><p>If you look at the size of the different versions of <code>opencv.js</code>, you&apos;ll see that it ranges from ~4Mb to 9Mb for v4.8.0. Depending on what you&apos;re trying to achieve, picking a version that covers your need for a minimal size is imo the recommended approach. However if you don&apos;t care about memory usage or loading times, then go for the latest stable version.</p><h5 id="recompiling-the-library">Recompiling the library</h5><p>You always have the option to recompile the script by disabling the modules that you don&apos;t need which could cut the size in half (especially by disabling <code>-DBUILD_opencv_dnn</code>). It could be a good compromise between having the latest version but limited to your application&apos;s need.</p><p>Precautions:</p><ul><li>At this day you can&apos;t build opencv.js from a Windows environment (unless you use a linux distro in WSL)</li><li>In my experience, the built image had a flaw, well explained <a href="https://forum.opencv.org/t/manual-opencv-js-build-not-working-in-node/13165/2?ref=blog.cemsoyding.com">here</a>. My js component wouldn&apos;t work with the compiled file whereas it worked fine with the official release. Didn&apos;t dig deeper into this issue, but if you have weird errors like <code>right-hand side of &apos;instanceof&apos; is not an object</code>, consider trying with the official script.</li></ul><p>The recompiling steps are documented in <a href="https://docs.opencv.org/4.x/d4/da1/tutorial_js_setup.html?ref=blog.cemsoyding.com">official documentation</a>. I had no trouble to build it, just used the following command instead of the one provided in docs (from opencv repo&apos;s root directory):</p><pre><code class="language-bash">python platforms/js/build_js.py build_out --emscripten_dir ../emsdk/upstream/emscripten --build_wasm --clean_build_dir
</code></pre><h4 id="adding-it-to-blazor">Adding it to Blazor</h4><h5 id="statically">Statically</h5><p>If you read the <a href="https://docs.opencv.org/4.8.0/d0/d84/tutorial_js_usage.html?ref=blog.cemsoyding.com">docs</a>, you simply need to add the following lines in your <code>index.html</code> file to start using OpenCV in your javascript modules:</p><pre><code class="language-js">&lt;script src=&quot;_content/MyComp/opencv.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
</code></pre><p><strong>Note</strong>: This example supposes that your <code>opencv.js</code> file is under <code>wwwroot</code> in your component&apos;s project.</p><p>And well, here start the troubles. The following error messages will occasionnally happen when you start your software:</p><ul><li><code>TypeError: Failed to execute &apos;compile&apos; on &apos;WebAssembly&apos;: Cannot compile WebAssembly.Module from an already read Response</code></li><li><code>Module.ready couldn&apos;t be redefined</code></li></ul><p>For someone new to webassmbly and Blazor, these errors are really not helpful. After reading a bit on emscripten and after several dry attempts to find a solution online, here is what I finally did to make it work. Open your <code>opencv.js</code> file and replace the last lines as shown below:</p><pre><code class="language-js">  if (typeof Module === &apos;undefined&apos;)
    Module = {};
  return cv(Module);
}));
</code></pre><p>with</p><pre><code class="language-js">if (typeof OpenCvModule === &apos;undefined&apos;)
    OpenCvModule = {};
  return cv(OpenCvModule);
}));
</code></pre><p>My understanding is that emscripten creates a <code>Module</code> variable in the global space by default when compiling a js file. Since <code>_framework/blazor.webassembly.js</code> also defines <code>Module</code>, the runtime complains. Renaming the variable fixes the issue. There is probably a cleaner way of resolving this issue and I&apos;ll update this article accordingly when I get more familiar with emscripten and webassembly in general.</p><h5 id="dynamically">Dynamically</h5><p>If you only want to load opencv when needed, you need to load it dynamically from javascript. Copy paste the following function in your typescript class (or convert it to a function) :</p><pre><code class="language-ts">private initOpenCv() {
    if (typeof cv === &apos;undefined&apos;) {
        // OpenCV.js not loaded yet, load it asynchronously
        let script = document.createElement(&apos;script&apos;);
        script.setAttribute(&apos;async&apos;, &apos;&apos;);
        script.setAttribute(&apos;type&apos;, &apos;text/javascript&apos;);
        script.addEventListener(&apos;load&apos;, async () =&gt; {
            // Checking the loading of the buildInformation
            if (cv instanceof Promise) {
                cv = await cv;
                console.info(&quot;OpenCv ready&quot;);
                console.log(cv.getBuildInformation());
                this._isOpenCvRuntimeReady = true;
            }
            else if (cv != &apos;undefined&apos; &amp;&amp; cv.getBuildInformation) {
                console.info(&quot;OpenCv ready&quot;);
                console.log(cv.getBuildInformation());
            }
            else {
                // Web Assembly check
                cv[&apos;onRuntimeInitialized&apos;] = () =&gt; {
                    console.info(&quot;OpenCv ready&quot;);
                    console.log(cv.getBuildInformation());
                    this._isOpenCvRuntimeReady = true;
                }
            }
        });
        script.addEventListener(&apos;error&apos;, () =&gt; {
            console.error(&apos;Failed to load opencv&apos;);
        });
        script.src = &apos;_content/MyComp/opencv.js&apos;;
        let node = document.getElementsByTagName(&apos;script&apos;)[0];
        node.parentNode.insertBefore(script, node);
    } else {
        console.info(&quot;OpenCv already loaded&quot;);
        this._isOpenCvRuntimeReady = true;
    }
}
</code></pre><p>This script basically modifies the DOM to add the <code>&lt;script&gt;</code> tag on demand, loads it asynchronously and subscribes to the <code>load</code> event to detect the successful loading of opencv.<br>Call this method from a public <code>init</code> method of your class, or from your constructor.<br>Do not forget to set <code>this._isOpenCvRuntimeReady</code> to false in your constructor as well.</p><h3 id="other-known-issues">Other known issues</h3><h4 id="amd-vs-esm">AMD vs ESM</h4><p>If you somehow encounter the following error when loading your component :</p><p><code>Uncaught Error: Can only have one anonymous define call per script file</code></p><p>start by reading this <a href="https://dev.to/iggredible/what-the-heck-are-cjs-amd-umd-and-esm-ikm?ref=blog.cemsoyding.com">article</a>.</p><p>Your application has probably a mixup of technology in how javascript modularity is handled. In my case, the app was also using Microsoft&apos;s Monaco editor which comes with AMD loader by default. If you read the article carefully, you&apos;ve seen that there&apos;s a pattern called UMD to verify the module system when importing a js library. OpenCV uses that pattern. In fact, commenting parts of the first line of opencv fixes the issue as shown below:</p><pre><code class="language-js">(function(root,factory){/*if(typeof define===&apos;function&apos;&amp;&amp;define.amd){define(function(){return(root.cv=factory());});}else */if(typeof module===&apos;object&apos;&amp;&amp;module.exports){...
</code></pre><p>but I have to tell you that this is an ugly fix because it breaks the UMD pattern (which is good !). You better review your js modules and make sure that they&apos;re aligned to the same module systems.</p><h3 id="resources">Resources</h3><ul><li>Playing around with OpenCV js<br><a href="https://medium.com/artificialis/easily-build-a-web-app-with-haar-cascades-and-opencv-js-aa46be637096?ref=blog.cemsoyding.com">https://medium.com/artificialis/easily-build-a-web-app-with-haar-cascades-and-opencv-js-aa46be637096</a></li><li>Build<br><a href="https://lambda-it.ch/blog/build-opencv-js?ref=blog.cemsoyding.com">https://lambda-it.ch/blog/build-opencv-js</a></li></ul>]]></content:encoded></item></channel></rss>