<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Sumer Ahmed</title>
    <description>The latest articles on DEV Community by Sumer Ahmed (@sumer5020).</description>
    <link>https://dev.to/sumer5020</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F892672%2Fb3291878-c9d2-4b19-992c-dd6651e0a605.jpeg</url>
      <title>DEV Community: Sumer Ahmed</title>
      <link>https://dev.to/sumer5020</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/sumer5020"/>
    <language>en</language>
    <item>
      <title>Deploy Spring Boot Applications with NGINX and Ubuntu</title>
      <dc:creator>Sumer Ahmed</dc:creator>
      <pubDate>Fri, 07 Jun 2024 09:01:09 +0000</pubDate>
      <link>https://dev.to/sumer5020/deploy-spring-boot-applications-with-nginx-and-ubuntu-4mlk</link>
      <guid>https://dev.to/sumer5020/deploy-spring-boot-applications-with-nginx-and-ubuntu-4mlk</guid>
      <description>&lt;p&gt;&lt;strong&gt;Step by step, do the following:&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Installing Java JDK 17 or 21 However, a reasonably recent (LTS) release is recommended.
&lt;/h2&gt;

&lt;p&gt;Ensure &lt;code&gt;software-properties-common&lt;/code&gt; is installed.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;software-properties-common
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Install Amazon Corretto 21
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;wget &lt;span class="nt"&gt;-O&lt;/span&gt; - https://apt.corretto.aws/corretto.key | &lt;span class="nb"&gt;sudo &lt;/span&gt;gpg &lt;span class="nt"&gt;--dearmor&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; /usr/share/keyrings/corretto-keyring.gpg &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"deb [signed-by=/usr/share/keyrings/corretto-keyring.gpg] https://apt.corretto.aws stable main"&lt;/span&gt; | &lt;span class="nb"&gt;sudo tee&lt;/span&gt; /etc/apt/sources.list.d/corretto.list

&lt;span class="nb"&gt;sudo &lt;/span&gt;apt-get update&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nb"&gt;sudo &lt;/span&gt;apt-get &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-y&lt;/span&gt; java-21-amazon-corretto-jdk

java &lt;span class="nt"&gt;-version&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Installing NGINX
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;nginx

&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl status nginx

&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl restart nginx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Be shore you stop apache2 &amp;amp; allow OpenSSH and nginx ports throw &lt;code&gt;UFW&lt;/code&gt;
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;ufw allow OpenSSH
&lt;span class="nb"&gt;sudo &lt;/span&gt;ufw allow &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="s2"&gt;"Nginx Full"&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;ufw &lt;span class="nb"&gt;enable

sudo &lt;/span&gt;ufw status
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  install &lt;code&gt;unzip&lt;/code&gt; and &lt;code&gt;zip&lt;/code&gt; too
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;unzip zip
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Installing the Spring Boot CLI
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Install sdkman The Software Development Kit Manager&lt;/span&gt;
curl &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="s2"&gt;"https://get.sdkman.io"&lt;/span&gt; | bash

&lt;span class="c"&gt;# Install springboot CLI&lt;/span&gt;
sdk &lt;span class="nb"&gt;install &lt;/span&gt;springboot

&lt;span class="c"&gt;# Note: if you get sdk not found, do the following&lt;/span&gt;
nano ~/.bashrc

&lt;span class="c"&gt;## Add this line in the end of file&lt;/span&gt;
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;PATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$PATH&lt;/span&gt;:/usr/local/sdkman/bin

&lt;span class="c"&gt;## Finally&lt;/span&gt;
&lt;span class="nb"&gt;source&lt;/span&gt; ~/.bashrc
sdk &lt;span class="nb"&gt;install &lt;/span&gt;springboot

&lt;span class="c"&gt;## Then we can init new project like this&lt;/span&gt;

spring version

spring init &lt;span class="nt"&gt;--list&lt;/span&gt;
spring init &lt;span class="nt"&gt;--build&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;maven &lt;span class="nt"&gt;--java-version&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;21 &lt;span class="nt"&gt;--dependencies&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;web,data-jpa &lt;span class="nt"&gt;--packaging&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;jar app-name.zip
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Install Maven
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;wget https://dlcdn.apache.org/maven/maven-3/3.9.6/binaries/apache-maven-3.9.6-bin.tar.gz
&lt;span class="nb"&gt;tar&lt;/span&gt; &lt;span class="nt"&gt;-xvf&lt;/span&gt; apache-maven-3.9.6-bin.tar.gz
&lt;span class="nb"&gt;mv &lt;/span&gt;apache-maven-3.9.6 /opt/

&lt;span class="c"&gt;#  Setting M2_HOME and Path Variables&lt;/span&gt;
&lt;span class="nv"&gt;M2_HOME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'/opt/apache-maven-3.9.6'&lt;/span&gt;
&lt;span class="nv"&gt;PATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$M2_HOME&lt;/span&gt;&lt;span class="s2"&gt;/bin:&lt;/span&gt;&lt;span class="nv"&gt;$PATH&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="nb"&gt;export &lt;/span&gt;PATH

&lt;span class="c"&gt;# Show the mvn version&lt;/span&gt;
mvn &lt;span class="nt"&gt;-version&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Build the jar file
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;java &lt;span class="nt"&gt;-jar&lt;/span&gt; build/libs/app-name-0.0.1-SNAPSHOT.jar
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Creating an Init Script for the Spring Boot Application
&lt;/h2&gt;

&lt;p&gt;Do &lt;code&gt;nano /etc/systemd/system/helloworld.service&lt;/code&gt; and add the content:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;[&lt;/span&gt;Unit]
&lt;span class="nv"&gt;Description&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;Spring Boot app-name
&lt;span class="nv"&gt;After&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;syslog.target
&lt;span class="nv"&gt;After&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;network.target[Service]
&lt;span class="nv"&gt;User&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;username
&lt;span class="nv"&gt;Type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;simple

&lt;span class="o"&gt;[&lt;/span&gt;Service]
&lt;span class="nv"&gt;ExecStart&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/usr/bin/java &lt;span class="nt"&gt;-jar&lt;/span&gt; /home/userdir/app-name/build/libs/app-name-0.0.1-SNAPSHOT.jar
&lt;span class="nv"&gt;Restart&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;always
&lt;span class="nv"&gt;StandardOutput&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;syslog
&lt;span class="nv"&gt;StandardError&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;syslog
&lt;span class="nv"&gt;SyslogIdentifier&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;appname

&lt;span class="o"&gt;[&lt;/span&gt;Install]
&lt;span class="nv"&gt;WantedBy&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;multi-user.target
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  start the service
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl start appname
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Configuring a Reverse Proxy for the Spring Boot Application
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;server &lt;span class="o"&gt;{&lt;/span&gt;
        listen 80&lt;span class="p"&gt;;&lt;/span&gt;
        listen &lt;span class="o"&gt;[&lt;/span&gt;::]:80&lt;span class="p"&gt;;&lt;/span&gt;

        server_name example.com&lt;span class="p"&gt;;&lt;/span&gt;

        location / &lt;span class="o"&gt;{&lt;/span&gt;
            proxy_pass http://localhost:8080/&lt;span class="p"&gt;;&lt;/span&gt;
            proxy_set_header X-Forwarded-For &lt;span class="nv"&gt;$proxy_add_x_forwarded_for&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            proxy_set_header X-Forwarded-Proto &lt;span class="nv"&gt;$scheme&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            proxy_set_header X-Forwarded-Port &lt;span class="nv"&gt;$server_port&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo ln&lt;/span&gt; &lt;span class="nt"&gt;-s&lt;/span&gt; /etc/nginx/sites-available/appname.conf /etc/nginx/sites-enabled/
&lt;span class="c"&gt;# Unlink the default&lt;/span&gt;
&lt;span class="nb"&gt;sudo unlink&lt;/span&gt; /etc/nginx/sites-enabled/default
&lt;span class="c"&gt;# Test the conf&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;nginx &lt;span class="nt"&gt;-t&lt;/span&gt;
&lt;span class="c"&gt;# Restart nginx&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl restart nginx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>webdev</category>
      <category>java</category>
      <category>springboot</category>
      <category>spring</category>
    </item>
    <item>
      <title>360 landing page using three.js and nuxt.js</title>
      <dc:creator>Sumer Ahmed</dc:creator>
      <pubDate>Fri, 07 Jun 2024 08:58:02 +0000</pubDate>
      <link>https://dev.to/sumer5020/360-landing-page-using-threejs-and-nuxtjs-4j3m</link>
      <guid>https://dev.to/sumer5020/360-landing-page-using-threejs-and-nuxtjs-4j3m</guid>
      <description>&lt;h2&gt;
  
  
  In this post, I like to share how to create basic 360 landing page using three.js and nuxt.js.
&lt;/h2&gt;



&lt;p&gt;&lt;strong&gt;Step 1: install new nuxt.js project&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx nuxi@latest init simple-app
cd simple-app
npm i
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 2: install three.js&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm i three -D
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;now we are ready to go let’s create new component for our 360 landing page&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3: create new component&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx nuxi add component Landing
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;now we will create the component content like this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;script setup lang="ts"&amp;gt;
import {
PerspectiveCamera,
Scene,
SphereGeometry,
TextureLoader,
MeshBasicMaterial,
Mesh,
WebGLRenderer,
MathUtils,
} from "three";

const container = ref()

const props = defineProps({
    panoramaUrl:{
        type: String,
        default: "img/hdri.webp"
    },
});

let camera, scene, renderer;
let isUserInteracting = false,
    onPointerDownMouseX = 0, onPointerDownMouseY = 0,
    lon = 0, onPointerDownLon = 0,
    lat = 0, onPointerDownLat = 0,
    phi = 0, theta = 0;

camera = new PerspectiveCamera(40, window.innerWidth / window.innerHeight, 1, 1100);
scene = new Scene();
const geometry = new SphereGeometry(1000, 100, 100);
const reader = new FileReader();

const onWindowResize= () =&amp;gt; {
    camera.aspect = window.innerWidth / window.innerHeight;
    camera.updateProjectionMatrix();
    renderer.setSize(window.innerWidth, window.innerHeight);
}

const onPointerDown = (event) =&amp;gt; {
    if (event.isPrimary === false) return;
    isUserInteracting = true;
    onPointerDownMouseX = event.clientX;
    onPointerDownMouseY = event.clientY;
    onPointerDownLon = lon;
    onPointerDownLat = lat;
    document.addEventListener('pointermove', onPointerMove);
    document.addEventListener('pointerup', onPointerUp);
}

const onPointerMove = (event) =&amp;gt; {
    if (event.isPrimary === false) return;
    lon = (onPointerDownMouseX - event.clientX) * 0.1 + onPointerDownLon;
    lat = (event.clientY - onPointerDownMouseY) * 0.1 + onPointerDownLat;
}

const onPointerUp = () =&amp;gt; {
    if (event.isPrimary === false) return;
    isUserInteracting = false;
    document.removeEventListener('pointermove', onPointerMove);
    document.removeEventListener('pointerup', onPointerUp);
}

const onDocumentMouseWheel = (event) =&amp;gt; {
    const fov = camera.fov + event.deltaY * 0.05;
    camera.fov = MathUtils.clamp(fov, 10, 75);
    camera.updateProjectionMatrix();
}

const animate = () =&amp;gt; {
    requestAnimationFrame(animate);
    update();
}

const update = () =&amp;gt; {
    if (isUserInteracting === false) {
        lon += 0.1;
    }

    lat = Math.max(- 85, Math.min(85, lat));
    phi = MathUtils.degToRad(90 - lat);
    theta = MathUtils.degToRad(lon);
    const x = 500 * Math.sin(phi) * Math.cos(theta);
    const y = 500 * Math.cos(phi);
    const z = 500 * Math.sin(phi) * Math.sin(theta);
    camera.lookAt(x, y, z);
    renderer.render(scene, camera);
}

const dragover = (event) =&amp;gt; {
    event.preventDefault();
    event.dataTransfer.dropEffect = 'copy';
}

const dragenter = () =&amp;gt; {
    document.body.style.opacity = 0.5;
}

const dragleave = () =&amp;gt; {
    document.body.style.opacity = 1;
}

const load1 = (event) =&amp;gt; {
    material.map.image.src = event.target.result;
    material.map.needsUpdate = true;
}

const drop = () =&amp;gt; {
    event.preventDefault();
    reader.addEventListener('load', load1);
    reader.readAsDataURL(event.dataTransfer.files[0]);
    document.body.style.opacity = 1;
}

onMounted(() =&amp;gt; {
        init();
        animate();

        function init() {
            // invert the geometry on the x-axis so that all of the faces point inward
            geometry.scale(- 1, 1, 1);
            const texture = new TextureLoader().load(props.panoramaUrl);
            const material = new MeshBasicMaterial({ map: texture });
            const mesh = new Mesh(geometry, material);
            scene.add(mesh);
            renderer = new WebGLRenderer();
            renderer.setPixelRatio(window.devicePixelRatio);
            renderer.setSize(window.innerWidth, window.innerHeight);
            container.value.appendChild(renderer.domElement);
            container.value.style.touchAction = 'none';
            container.value.addEventListener('pointerdown', onPointerDown);
            document.addEventListener('wheel', onDocumentMouseWheel);
            document.addEventListener('dragover', dragover);
            document.addEventListener('dragenter', dragenter);
            document.addEventListener('dragleave', dragleave);
            document.addEventListener('drop', drop);
            window.addEventListener('resize', onWindowResize);
        }
});

onUnmounted(() =&amp;gt; {
    reader.removeEventListener('load', load1);
    container.value.replaceWith(container.value.cloneNode(true));
    document.removeEventListener('wheel', onDocumentMouseWheel);
    document.removeEventListener('dragover', dragover);
    document.removeEventListener('dragenter', dragenter);
    document.removeEventListener('dragleave', dragleave);
    document.removeEventListener('drop', drop);
    window.removeEventListener('resize', onWindowResize);
});
&amp;lt;/script&amp;gt;

&amp;lt;template&amp;gt;
    &amp;lt;div class="max-w-full h-screen w-full overflow-hidden"&amp;gt;
        &amp;lt;div ref="container"&amp;gt;&amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
&amp;lt;/template&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note that: you can find info about each part of the code in the official documentation of three.js in the link below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://threejs.org/docs/index.html#manual/en/introduction/Creating-a-scene"&gt;three.js documentation&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;now we need to create folder inside the public with the name img then we will create our image that use hdri mode.&lt;br&gt;
You can create your own image or you can find one from any resource in this part i basically use greater website called HDRi Haven then i convert the image to webp just to minify the total size of the image also in my case i don’t care about the shadow reflex and that other powerful things.&lt;br&gt;
Now we have the image img/hdri.webp in our public folder we are ready to use our component in the index.vue page.&lt;/p&gt;

&lt;p&gt;Note that: we may have some rendering problem if we use SSR with our app so basically we will use  wen we call our component like bellow.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;ClientOnly&amp;gt;
    &amp;lt;Landing/&amp;gt;
    &amp;lt;template #fallback&amp;gt;
      &amp;lt;!-- this will be rendered on server side --&amp;gt;
      &amp;lt;p&amp;gt;Landing is loading...&amp;lt;/p&amp;gt;
    &amp;lt;/template&amp;gt;
  &amp;lt;/ClientOnly&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;That’s it, we have now a basic 360 landing page&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://api.daily.dev/r/Sx5RsuKU7"&gt;my showcase in api.daily.dev&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>threejs</category>
      <category>nuxt</category>
    </item>
  </channel>
</rss>
