<?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>Forem: Kerschbaumer Stefan</title>
    <description>The latest articles on Forem by Kerschbaumer Stefan (@xsip).</description>
    <link>https://forem.com/xsip</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%2F265467%2F5b6e3405-c4ae-4a6d-b25d-f040043c6be2.png</url>
      <title>Forem: Kerschbaumer Stefan</title>
      <link>https://forem.com/xsip</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/xsip"/>
    <language>en</language>
    <item>
      <title>Angular 20.1 Simple Animate On Scroll POC Implementation</title>
      <dc:creator>Kerschbaumer Stefan</dc:creator>
      <pubDate>Sat, 26 Jul 2025 11:12:45 +0000</pubDate>
      <link>https://forem.com/xsip/angular-201-simple-animate-on-scroll-poc-implementation-2650</link>
      <guid>https://forem.com/xsip/angular-201-simple-animate-on-scroll-poc-implementation-2650</guid>
      <description>&lt;p&gt;&lt;strong&gt;Did you ever think about creating your own Animate on scroll - for short AOS - library in Angular?&lt;/strong&gt;&lt;br&gt;
I did a few times, so i gave it a try and made a simple AOS library which supports only one animation type but can be extended pretty easy.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;First of all, what is AOS?&lt;/strong&gt;&lt;br&gt;
AOS - Animate on scroll is some kind of UI feature where divs, images, ... - you name it - will get visible if with a beautiful animation when entering the viewport and hide again with the same - or another - animation when leaving the view port.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What do we need to archive this wanted behavior?&lt;/strong&gt;&lt;br&gt;
We basically only need a scrolling container where the animated elements are within and a little bit of angular magic.&lt;/p&gt;

&lt;p&gt;Let's start by installing the latest angular cli globally, create a project and add tailwind since we will use it for easier animating!&lt;/p&gt;

&lt;p&gt;So in your Favorite terminal, execute the following commands:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpwva7pigszqoijizoi27.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpwva7pigszqoijizoi27.png" alt=" " width="800" height="189"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This will create a project in your desired directory and install its dependencies.&lt;br&gt;
After that we need to setup tailwind.&lt;br&gt;
We can do this easily by executing &lt;br&gt;
&lt;code&gt;npm install tailwindcss @tailwindcss/postcss postcss --force&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Adding a file called &lt;code&gt;.postcssrc.json&lt;/code&gt; with the following content:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fviwtibjx3j90652j0ul5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fviwtibjx3j90652j0ul5.png" alt=" " width="726" height="566"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;and adding &lt;code&gt;@import "tailwindcss";&lt;/code&gt; to our angular project &lt;code&gt;styles.scss&lt;/code&gt;.&lt;br&gt;
Let's also add some simple primary &amp;amp; secondary colors for our testing environment in &lt;code&gt;styles.scss&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Your &lt;code&gt;styles.scss&lt;/code&gt; with custom colors and darkmode support could look like this for example:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg72hwe74bm0ye4fsc4s9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg72hwe74bm0ye4fsc4s9.png" alt=" " width="800" height="1059"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Perfect! Our base is setup completly fine.&lt;br&gt;
Now we should create some basic buttons or something which we can later animate on scroll.&lt;br&gt;
For that i made a simple button which gets repeated four times within our future scrolling container. &lt;br&gt;
This looks like this in the code:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkcf7e76widag6bod1kkb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkcf7e76widag6bod1kkb.png" alt=" " width="800" height="759"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And like this in the browser. (Note that you can only see one item since each button is wrapped in a full screen height div and you would need to scroll to see the others.)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbya0ielwmus67nct6d13.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbya0ielwmus67nct6d13.png" alt=" " width="800" height="547"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now comes the fun part!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;We need a few things to make this work:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A Service which get's initialized when the app gets initalized so we can listen to scroll events on needed containers.&lt;/li&gt;
&lt;li&gt;A directive which marks needed containers so we know we need to listen for scroll events on this container.&lt;/li&gt;
&lt;li&gt;A directive which marks an element which should be animated on scroll with the needed meta, such as threshold, animation name, and so on.&lt;/li&gt;
&lt;li&gt;A environment provider which will initialize our service on startup and gives us the possibility to customize everything.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;**Let's start with the Service.&lt;/p&gt;

&lt;p&gt;What do we need here?**&lt;/p&gt;

&lt;p&gt;The first thing We need is an array with HTMLElements for which we should listen to scroll events, and a function to push to this array and add listeners to those elements.&lt;br&gt;
We will push this elements from directives including a &lt;code&gt;onDestroyRef&lt;/code&gt;, so we can stop listening to its events when the component attachted to the directive we are calling the service from gets destroyed.&lt;/p&gt;

&lt;p&gt;So let's do that.&lt;/p&gt;

&lt;p&gt;Create a simple service by executing &lt;code&gt;ng g s aos-service&lt;/code&gt; in your favorite terminal. ( Make sure to remove the &lt;code&gt;{providedIn: 'root'}&lt;/code&gt; part since we will later register it as a library.&lt;/p&gt;

&lt;p&gt;After adding a function to save elements, and listen to scroll events your service should look like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4jcermfqx7sefq1nbl7h.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4jcermfqx7sefq1nbl7h.png" alt=" " width="800" height="580"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Perfect!&lt;br&gt;
&lt;strong&gt;Since we got this, we can add our &lt;code&gt;aosWatch&lt;/code&gt; directive to register scroll containers.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is actually pretty easy. All we need here is a SSR check to prevent logic from running in SSR context if you are using SSR, the elementRef to the element we are appending it to and the &lt;code&gt;AosService&lt;/code&gt; injected.&lt;/p&gt;

&lt;p&gt;If you are done it should look like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frf3g0foimbufc7irjih1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frf3g0foimbufc7irjih1.png" alt=" " width="800" height="459"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you now add the &lt;code&gt;xsipAosWatch&lt;/code&gt; directive to the main div and scroll in the Browser, you should se many &lt;code&gt;SCROLLING!!&lt;/code&gt; logs.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsareabuubhhm9i1hvxnd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsareabuubhhm9i1hvxnd.png" alt=" " width="800" height="391"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Perfect, we are halfway done!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Let's implement our &lt;code&gt;aosElement&lt;/code&gt; directive&lt;/strong&gt;&lt;br&gt;
What do we need for that?&lt;br&gt;
This is actually a pretty simple directive. It will set a attribute using &lt;code&gt;setAttribute&lt;/code&gt; and some tailwind classes to smooth out animations.&lt;br&gt;
You could for sure improve this with more input params, but for now we will only add one for the animation style which we will later bind to a tailwind class using a object.&lt;/p&gt;

&lt;p&gt;Our &lt;code&gt;aos&lt;/code&gt; directive which identifies elements which should be animated on scroll could look like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmcrjmzfqyygrjg0vobb3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmcrjmzfqyygrjg0vobb3.png" alt=" " width="800" height="482"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If we import this directive to our &lt;code&gt;app-component&lt;/code&gt; and append it to the third element - in this case the div with the title &lt;code&gt;Button 3&lt;/code&gt; we will see in the browser that it got a few more classes and a new attribute now. &lt;br&gt;
That's exactly what we wanted to archive!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc1mmjw2f0urb8izveoir.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc1mmjw2f0urb8izveoir.png" alt=" " width="800" height="395"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Let's re-visit our &lt;code&gt;aos-service&lt;/code&gt; and add a function to identify if elements are in view or hidden, as well as a custom naming to tailwind class mapping ( for example &lt;code&gt;fadeIn&lt;/code&gt; will result in &lt;code&gt;opacity-0&lt;/code&gt; ) and a type for that to make our &lt;code&gt;aos-directive&lt;/code&gt; input typesafe!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;After doing all this changes our &lt;code&gt;aos-service&lt;/code&gt; should be finished and look like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8x02i0ox0ff1hj3yeotj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8x02i0ox0ff1hj3yeotj.png" alt=" " width="800" height="1181"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And our &lt;code&gt;aos-directive&lt;/code&gt; like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F70go7elk6q4q0qd13d3i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F70go7elk6q4q0qd13d3i.png" alt=" " width="800" height="497"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We are done! Congratulations, you did your first AOS implementation.&lt;br&gt;
&lt;strong&gt;For sure, this is a POC, but can be refactored into something really cool!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you visit &lt;a href="https://aos.kerschbaumer.dev/" rel="noopener noreferrer"&gt;https://aos.kerschbaumer.dev/&lt;/a&gt; and scroll through the page, you will see that button 3 fades in as you scroll it into view, and out as it leaves the view.&lt;/p&gt;

&lt;p&gt;Also here is the github repo for the POC : &lt;br&gt;
&lt;a href="https://github.com/xsip/ng-20-aos" rel="noopener noreferrer"&gt;https://github.com/xsip/ng-20-aos&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I hope you learned something. &lt;br&gt;
Happy coding :)&lt;/p&gt;

</description>
      <category>angular</category>
      <category>aos</category>
      <category>animation</category>
      <category>tailwindcss</category>
    </item>
    <item>
      <title>How to Prevent Darkmode Flickering in angular@20.1.0 SSR using Tailwind</title>
      <dc:creator>Kerschbaumer Stefan</dc:creator>
      <pubDate>Mon, 21 Jul 2025 22:38:41 +0000</pubDate>
      <link>https://forem.com/xsip/how-to-prevent-darkmode-flickering-in-angular2010-ssr-using-tailwind-im2</link>
      <guid>https://forem.com/xsip/how-to-prevent-darkmode-flickering-in-angular2010-ssr-using-tailwind-im2</guid>
      <description>&lt;p&gt;Lately i am Diving deeply into Angular SSR.&lt;br&gt;
When it comes to DarkMode and SSR/ Hydration I faced the following issue:&lt;/p&gt;

&lt;p&gt;The site is Flickering when hydrating the angular app in cases where i am using dark mode. This happens because the Website not beeing served in DarkMode when initialy loading the Site and the darkmode gets restored from the browser later on.&lt;/p&gt;

&lt;p&gt;Why is this happening?&lt;br&gt;
In most cases you save your &lt;code&gt;ìsDarkModeEnabled&lt;/code&gt; in the cookies as well as in the &lt;code&gt;localStorage&lt;/code&gt;. That's perfect, but Frontend logic for example appending classes to document elements can't run in the SSR Context.&lt;/p&gt;

&lt;p&gt;To solve this i found a simple solution.&lt;/p&gt;

&lt;p&gt;What you need to do, is check your cookies if dark mode is set, and append the class by manipulating the response body if needed.&lt;/p&gt;

&lt;p&gt;This should look like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F34p2ug0682pjv49joyye.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F34p2ug0682pjv49joyye.png" alt=" " width="800" height="617"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After that when i load my page with JS Disabled it get's served perfectly fine in darkmode.&lt;/p&gt;

&lt;p&gt;Hope this helped you in some way!&lt;br&gt;
Have a nice day and feel free to leave Feedback :)&lt;/p&gt;

</description>
      <category>ssr</category>
      <category>angular</category>
      <category>tailwindcss</category>
      <category>darkmode</category>
    </item>
    <item>
      <title>How to Use NestJS as SSR Server for Angular v20 | POC</title>
      <dc:creator>Kerschbaumer Stefan</dc:creator>
      <pubDate>Sat, 19 Jul 2025 11:47:40 +0000</pubDate>
      <link>https://forem.com/xsip/how-to-use-nestjs-as-ssr-server-for-angular-v20-poc-5897</link>
      <guid>https://forem.com/xsip/how-to-use-nestjs-as-ssr-server-for-angular-v20-poc-5897</guid>
      <description>&lt;p&gt;Did you ever think about using nestjs as your SSR Server for angular v20 ?&lt;br&gt;
It's actually pretty easy to set this up as a POC.&lt;/p&gt;

&lt;p&gt;First of all we need to install a few dependencies to our angular application.&lt;/p&gt;

&lt;p&gt;Those are:&lt;br&gt;
`&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"@nestjs/serve-static": "^5.0.3",
"@nestjs/cli": "^11.0.7",
"@nestjs/common": "^11.1.5",
"@nestjs/core": "^11.1.5",
"@nestjs/platform-express": "^11.1.5",
"@nestjs/schematics": "^11.0.5",
"@types/node": "^20.19.8",
"reflect-metadata": "^0.2.2",
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;`&lt;/p&gt;

&lt;p&gt;After that we need to define a middleware to use the &lt;code&gt;AngularNodeAppEngine&lt;/code&gt; within our NestJS server.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo4hbpvqizd13r0s97rxm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo4hbpvqizd13r0s97rxm.png" alt=" " width="800" height="445"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After that we need to create our &lt;code&gt;AppModule&lt;/code&gt; where we register the Middleware and import the &lt;code&gt;ServerStaticModule&lt;/code&gt; for static content serving.&lt;/p&gt;

&lt;p&gt;This will look like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuv3w4xfaswcfmm6r26ae.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuv3w4xfaswcfmm6r26ae.png" alt=" " width="800" height="722"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That's basically all we need.&lt;br&gt;
Our &lt;code&gt;server.ts&lt;/code&gt; within the Angular App will look like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3le62u7b6ypwi5nlhuxo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3le62u7b6ypwi5nlhuxo.png" alt=" " width="800" height="379"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now if you run &lt;code&gt;npm run start&lt;/code&gt; and have SSR enabled you will see that the NestJS server starts up perfectly fine.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl6yghkm8tahd7cf6203o.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl6yghkm8tahd7cf6203o.png" alt=" " width="800" height="660"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Please note that this is just a simple POC and needs some tweaking as for example sometimes when the app is reloading the server is not shutting down completly or &lt;code&gt;npm run build&lt;/code&gt; doesn't work at this time.&lt;/p&gt;

&lt;p&gt;But i will try to improve my POC github repo to fix this issues.&lt;/p&gt;

&lt;p&gt;You can find the minimal POC repo here:&lt;br&gt;
&lt;a href="https://github.com/xsip/ng-nest-ssr" rel="noopener noreferrer"&gt;https://github.com/xsip/ng-nest-ssr&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Hopefully this helped you in some way.&lt;br&gt;
Have a nice day :)&lt;/p&gt;

</description>
      <category>ssr</category>
      <category>angular</category>
      <category>nestjs</category>
      <category>development</category>
    </item>
    <item>
      <title>Unity Game Hacking - Calling FindObjectsOfType in C++</title>
      <dc:creator>Kerschbaumer Stefan</dc:creator>
      <pubDate>Wed, 20 Nov 2024 16:32:12 +0000</pubDate>
      <link>https://forem.com/xsip/unity-game-hacking-calling-findobjectsoftype-in-c-1bjp</link>
      <guid>https://forem.com/xsip/unity-game-hacking-calling-findobjectsoftype-in-c-1bjp</guid>
      <description>&lt;p&gt;Since i had struggles finding Objects while reversing Unity games i am going to share you how to find Objects by classname.&lt;br&gt;
First of all: This will only work for mono games.&lt;br&gt;
Games using IL2CPP need another approach.&lt;/p&gt;

&lt;p&gt;So first of all, What are Objects in the Unity Game Engine?&lt;br&gt;
Objects are instances of a classes for example Objects which gets rendered, the local player instance, ....&lt;br&gt;
Sometimes classes hold static properties which provides a list of instances.&lt;br&gt;
But if that's not the case we need to obtain them in another way.&lt;br&gt;
That's where "FindObjectsOfType" comes in hand.&lt;/p&gt;

&lt;p&gt;First of all we need to initialize mono to get access to all game internal stuff when injecting a dll.&lt;/p&gt;

&lt;p&gt;So "mono.dll" exports a few symbols which we can use in our DLL.&lt;br&gt;
You can get the C++ SDK from here: &lt;a href="https://github.com/mono/mono/" rel="noopener noreferrer"&gt;Mono SDK On Github&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So lets add a file called "mono-loader.h" which will get our mono symbols so we can call them from out of C++.&lt;br&gt;
This file will look like the following:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fduipz5hkeqnkrry9nc76.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fduipz5hkeqnkrry9nc76.png" alt=" " width="800" height="711"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So no we are not ready yet to call our mono functions.&lt;br&gt;
We can fix that by calling "LoadMonoFunctions" and executing "mono_thread_attach_func" with "mono_get_root_domain_func" at the beginning of our main thread.&lt;/p&gt;

&lt;p&gt;This will look like the following:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fercz5jd0mtzmul9q5j43.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fercz5jd0mtzmul9q5j43.png" alt=" " width="800" height="269"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Lets Implement our "FindObjectsOfType" function.&lt;/p&gt;

&lt;p&gt;To do that we need to have a look in &lt;a href="https://github.com/dnSpy/dnSpy" rel="noopener noreferrer"&gt;DnSPy&lt;/a&gt; to see where it is defined at.&lt;br&gt;
If you look at "UnityEngine.CoreModule", you will see  a class Called "Object".&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdvyh4yktuwbg7r7ubfcb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdvyh4yktuwbg7r7ubfcb.png" alt=" " width="609" height="154"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This object class has a static function called "FindObjectsOfType" which takes a class instance of "Type" as argument.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbuhum39v95yff0u127u8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbuhum39v95yff0u127u8.png" alt=" " width="618" height="283"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To resolve the type by providing a String which Contains Module, Namespace and Class name we need to have a look at "mscorlib::system::type" within DnSpy. There we will find a  static function "GetType".&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fegy95of5pwkpsd8yx5t8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fegy95of5pwkpsd8yx5t8.png" alt=" " width="690" height="121"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So what do we need to do?&lt;br&gt;
First of all we need to create a string used by the UnityEngine to get our type.&lt;br&gt;
We can do that by defining a new function within our "MonoLoader" namespace called "MonoString".&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1xuunz4min1a863w55l9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1xuunz4min1a863w55l9.png" alt=" " width="800" height="141"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This will create a Unity Engine / Mono string instance within our memory.&lt;/p&gt;

&lt;p&gt;After that we can resolve our Type which we then need to provide to "FindObjectsOfType" by declaring a few helper functions.&lt;/p&gt;

&lt;p&gt;First of all we need a function to resolve a Class.&lt;br&gt;
After that a function to retrieve a mono module.&lt;br&gt;
After that we need a function to get a class method, and a function to compile a function after obtaining the class method.&lt;/p&gt;

&lt;p&gt;This are the needed Implementations:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F808tkuj18blqg7nti93e.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F808tkuj18blqg7nti93e.png" alt=" " width="800" height="304"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So lets create our helper functions so that we can later on implement "GetObjectsOfType".&lt;/p&gt;

&lt;p&gt;First of all we need to be able to retrieve our needed classes.&lt;br&gt;
We can do that with the following implementations:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc03jjsm4ux8xzh1t37kc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc03jjsm4ux8xzh1t37kc.png" alt=" " width="800" height="199"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After that we can implement "GetObjectsOfType" pretty easily.&lt;br&gt;
Have look:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frg5er81p354iqulwar1u.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frg5er81p354iqulwar1u.png" alt=" " width="800" height="711"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This function will return a pointer to a c# array which we can read with the following functions:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6npk92l1sppq7h6hls96.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6npk92l1sppq7h6hls96.png" alt=" " width="800" height="292"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To find out why i am using this offsets, please have a look at Cheat Engine using the dissect mono feature!&lt;/p&gt;

&lt;p&gt;So lets imagine we want to create an aimbot and retrieve all enemies in a game.&lt;br&gt;
In the game i am trying to hack there is a class called "Enemy" which has no namspace and is declared in the "Assembly-CSharp" module.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F74hitdjzxofela04an05.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F74hitdjzxofela04an05.png" alt=" " width="800" height="476"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So that we can retrieve our enemy array and walk through it we can simply do the following:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0wtru3aq2i340czpdo1n.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0wtru3aq2i340czpdo1n.png" alt=" " width="800" height="280"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To better explaing "FindObjectsByType" function:&lt;br&gt;
The first argument is the Object name str which is constructed out of&lt;br&gt;
"&amp;lt;classname&amp;gt;, &amp;lt;module-name&amp;gt;". If there is a namespace it would look like &lt;br&gt;
"&amp;lt;classname&amp;gt;, &amp;lt;module-name&amp;gt;, &amp;lt;namespace&amp;gt;".&lt;/p&gt;

&lt;p&gt;Well. From there on you are ready to hack!&lt;/p&gt;

&lt;p&gt;Happy Hacking!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Prerender routes in Angular 18</title>
      <dc:creator>Kerschbaumer Stefan</dc:creator>
      <pubDate>Tue, 06 Aug 2024 07:52:20 +0000</pubDate>
      <link>https://forem.com/xsip/prerender-routes-in-angular-18-3ekl</link>
      <guid>https://forem.com/xsip/prerender-routes-in-angular-18-3ekl</guid>
      <description>&lt;p&gt;So lets expect you wanna create a blog website using angular 18 and need to prerender your blog urls for SEO.&lt;/p&gt;

&lt;p&gt;This is actually pretty easy.&lt;br&gt;
To get started we need to generate a list of our URLs to prerender.&lt;br&gt;
For that i wrote a simple script.&lt;br&gt;
This script will connect to our backend and get a list of all Blog entry names and writes it to a file called "routes.txt".&lt;br&gt;
We will later on use this file for prerendering &lt;/p&gt;

&lt;p&gt;First of all create a backend returning all names of your blog entries. I did this by using NestJS and wont get into detail here.&lt;br&gt;
The server returns as said before a string array.&lt;/p&gt;

&lt;p&gt;To create a "routes.txt" file for all your blog entries use the following script:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj0pf0vpiz3jpfzyu3cym.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj0pf0vpiz3jpfzyu3cym.png" alt=" " width="800" height="485"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The output will look like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8er0rbgv54h371febdeg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8er0rbgv54h371febdeg.png" alt=" " width="394" height="182"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now edit your package.json build script to the following:&lt;br&gt;
&lt;code&gt;"build": "node routes-generator.js &amp;amp;&amp;amp; ng build",&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;After that we need to configure our "angular.json" to use this file for pre-rendering and replace our enviroment file to connect to the server instead of using our proxy.conf.json while building.&lt;br&gt;
This will look like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpbggsaw8dhfk5makp378.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpbggsaw8dhfk5makp378.png" alt=" " width="800" height="886"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;My environment files look like the following:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3gmjpw6fm7xmc8mng1ed.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3gmjpw6fm7xmc8mng1ed.png" alt=" " width="800" height="679"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now when running &lt;code&gt;npm run build&lt;/code&gt; our sites will be pre-rendered and when serving without JS enabled in chrome everything should be rendered fine.&lt;/p&gt;

&lt;p&gt;Lets have a look at our "dist" folder.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6z4ak64coktsy0508zdw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6z4ak64coktsy0508zdw.png" alt=" " width="800" height="587"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This looks pretty good!&lt;/p&gt;

&lt;p&gt;Now lets serve our app.&lt;br&gt;
First run &lt;code&gt;npm i -g http-server&lt;/code&gt;, then navigate to &lt;code&gt;dist/blog/server&lt;/code&gt; and run &lt;code&gt;node server.mjs&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;When we navigate to our route and disable Javascript everything is rendered perfectly fine.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnwn5u513g0v80x5f4vm9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnwn5u513g0v80x5f4vm9.png" alt=" " width="800" height="680"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I hope you learned something from this article and feel free to leave feedback.&lt;/p&gt;

&lt;p&gt;Happy Coding!&lt;/p&gt;

</description>
      <category>angular</category>
      <category>ssr</category>
      <category>blog</category>
      <category>prerender</category>
    </item>
    <item>
      <title>Remove Angular SSR code when serving to the client</title>
      <dc:creator>Kerschbaumer Stefan</dc:creator>
      <pubDate>Wed, 24 Jul 2024 07:43:55 +0000</pubDate>
      <link>https://forem.com/xsip/remove-angular-ssr-code-when-serving-to-the-client-26ob</link>
      <guid>https://forem.com/xsip/remove-angular-ssr-code-when-serving-to-the-client-26ob</guid>
      <description>&lt;p&gt;Did you ever notice that when you are using Angular SSR the server side code also gets served to the client?&lt;/p&gt;

&lt;p&gt;To prevent that i made a small library called &lt;a href="https://github.com/xsip/ngx-ssr-code-remover" rel="noopener noreferrer"&gt;ngx-ssr-code-remover&lt;/a&gt; which removes SSR code post building by analysing the bundle files.&lt;/p&gt;

&lt;p&gt;As you can see, without using my library the code served will contain my "secrets".&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjj92r81vwvzrml2kts1m.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjj92r81vwvzrml2kts1m.png" alt=" " width="800" height="345"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After adding two lines of code on the server side, and a decorator within the component everything gets removed.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkuic9h9bg54qxakjw580.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkuic9h9bg54qxakjw580.png" alt=" " width="800" height="395"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Currently this lib is only tested with angular 18.1 using esbuild.&lt;br&gt;
Also i didn't change any production build configs.&lt;br&gt;
Lazy loading works fine and supporting providers is planned in the feature.&lt;br&gt;
Feel free to checkout my repo, and/or give me feedback.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/xsip/ngx-ssr-code-remover" rel="noopener noreferrer"&gt;https://github.com/xsip/ngx-ssr-code-remover&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Enjoy your day and happy coding!&lt;/p&gt;

</description>
      <category>angular</category>
      <category>ssr</category>
      <category>typescript</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Observe Typescript Classes</title>
      <dc:creator>Kerschbaumer Stefan</dc:creator>
      <pubDate>Thu, 30 Mar 2023 12:39:01 +0000</pubDate>
      <link>https://forem.com/xsip/observe-typescript-classes-3a61</link>
      <guid>https://forem.com/xsip/observe-typescript-classes-3a61</guid>
      <description>&lt;p&gt;Observe JS/TS/Node classes and get notified when functions get executed or properties changed&lt;br&gt;
Check out my github repo:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/xsip/observed" rel="noopener noreferrer"&gt;Github XSIP/Observed&lt;/a&gt;&lt;/p&gt;

</description>
      <category>typescript</category>
      <category>javascript</category>
      <category>node</category>
      <category>observe</category>
    </item>
    <item>
      <title>Async Constructors in TS</title>
      <dc:creator>Kerschbaumer Stefan</dc:creator>
      <pubDate>Thu, 30 Mar 2023 07:20:37 +0000</pubDate>
      <link>https://forem.com/xsip/async-constructors-in-ts-5h6f</link>
      <guid>https://forem.com/xsip/async-constructors-in-ts-5h6f</guid>
      <description>&lt;p&gt;Async Constructors in Typescript/NodeJS/Javascript are a thing!&lt;br&gt;
Checkout my GitHub repo:&lt;br&gt;
&lt;a href="https://github.com/xsip/acon" rel="noopener noreferrer"&gt;Github XSIP/ACON&lt;/a&gt;&lt;/p&gt;

</description>
      <category>typescript</category>
      <category>javascript</category>
      <category>constructor</category>
      <category>node</category>
    </item>
    <item>
      <title>Windows Game Hack with Javascript | Part 1</title>
      <dc:creator>Kerschbaumer Stefan</dc:creator>
      <pubDate>Mon, 27 Jan 2020 09:24:10 +0000</pubDate>
      <link>https://forem.com/xsip/windows-game-hack-with-javascript-4foi</link>
      <guid>https://forem.com/xsip/windows-game-hack-with-javascript-4foi</guid>
      <description>&lt;h2&gt;
  
  
  What did i use?
&lt;/h2&gt;

&lt;p&gt;nodeJs for reading processes memory and data processing &lt;/p&gt;

&lt;p&gt;electron, javascript, html and css for overlaying the game window&lt;/p&gt;

&lt;h2&gt;
  
  
  How does the result look like?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxj4v81mp1lzx456gs132.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxj4v81mp1lzx456gs132.png" alt="Alt Text" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why did i do that using Web technology?
&lt;/h2&gt;

&lt;p&gt;Since i started my life as a software developer by writing game hacks - or copy and pasting them at first - but lately moved further away from this topic i decided to start writing game hacks again by using the technology i am using nowadays.&lt;br&gt;
So here we are, me, javascript, nodejs and electron doing something different. &lt;/p&gt;

&lt;h2&gt;
  
  
  What do i need other then developing skills to get started?
&lt;/h2&gt;

&lt;p&gt;If you wanna recreate something like this you should have some knowledge about the game engine you are targeting and also know something about reverse engineering. &lt;/p&gt;

&lt;p&gt;I want to say at this point that i have been developing cheats for the source engine over years but not gonna cover the topic on how to reverse memory addresses within the engine since this hacks target is CS:GO, and the CS:GO community decided to release all needed memory locations which are containing useful data open sourced and share them at a github repo when they change after game updates &lt;/p&gt;

&lt;p&gt;You can find them here for example: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/frk1/hazedumper/blob/master/csgo.json" rel="noopener noreferrer"&gt;https://github.com/frk1/hazedumper/blob/master/csgo.json&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Please notice that those memory pointers could belong to some module. &lt;/p&gt;

&lt;p&gt;So you can't just read from the processes executable handle and the offset since that would be the wrong memory region.&lt;/p&gt;

&lt;p&gt;You still need to obtain the base adresses of a belonging module ( memory location of a module within the processes memory ) and add it to the offset to get the right address.  &lt;/p&gt;

&lt;p&gt;I am anyway not going to cover that in this topic either. &lt;/p&gt;

&lt;p&gt;If you wanna do some research have a look at &lt;a href="http://www.unknowncheats.me" rel="noopener noreferrer"&gt;www.unknowncheats.me&lt;/a&gt; - which is a great resource on gamehacking information - and its CS:GO section and you will find out about the games internals. &lt;/p&gt;

&lt;h2&gt;
  
  
  Let's get started
&lt;/h2&gt;

&lt;p&gt;To start writing our first game hack using typescript and nodejs you need to create a new nodejs project by creating a folder and using npm init. &lt;/p&gt;

&lt;p&gt;After that i installed the following modules: &lt;/p&gt;

&lt;p&gt;typescript, ws - for the overlay communication, tslint, and memoryjs. &lt;/p&gt;

&lt;p&gt;Now we should have everything ready to go and can create our src folder and its index.ts file for the hacks backend.&lt;/p&gt;

&lt;h2&gt;
  
  
  Main Data - Process Wrapper Class
&lt;/h2&gt;

&lt;p&gt;Since memoryJs the class we are using to read process memory from a executable which is  written by ROB--  needs to have a process handle provided on each read/writeprocessmemory we are going to wrap those methods by a custom written "Process" class to avoid that. &lt;/p&gt;

&lt;p&gt;This looks as the following and can be found on my hacks github repo linked in the end.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvcwkir2l1o3s0lvbx3c0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvcwkir2l1o3s0lvbx3c0.png" alt="Alt Text" width="800" height="1089"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;as you can see we initialize the process class by passing a executable name and from then on we can use readMemory or writeMemory i.e of the new class instance instead of passing the handle of the executable on each memory request. &lt;/p&gt;

&lt;h2&gt;
  
  
  Main Data - Global Process "Shortcuts"
&lt;/h2&gt;

&lt;p&gt;To make the ussage even easier i will create global variables called rpm, wpm and mT. &lt;/p&gt;

&lt;p&gt;Those will be ReadProcessMemory, WriteProcessMemory, and MemoryTypes. &lt;/p&gt;

&lt;p&gt;I expose them as in the following example: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2dq34ej49uixa59a42ek.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2dq34ej49uixa59a42ek.png" alt="Alt Text" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Main Data - Playerdata creating a class for it
&lt;/h2&gt;

&lt;p&gt;In CS:GO there is something called "EntityList" which can contain a maximum of 32 "Entitys" -which are actually players - and this list which can be retrieved on different ways, will be the base of our radarhack. &lt;/p&gt;

&lt;p&gt;At the current version of CS:GO this list containing playerdata is located at "client_panorama.dll" + 0x4D3D5DC. &lt;/p&gt;

&lt;p&gt;So to retrive all the player information we need to read "client_panorama.dll" + the offset from above and from there on we can retrieve data for each player connected to the game by adding the size of each player in memory * the players id to the pointer from before..  &lt;/p&gt;

&lt;p&gt;So to retrieve entity number 2 for example:  &lt;/p&gt;

&lt;p&gt;pointer = "client_panorama.dll" + 0x4D3D5DC. &lt;/p&gt;

&lt;p&gt;pointer + (0x10 ( = the size ) * 2) skips the first player and gives you the &lt;br&gt;
  pointer to the data of the second player. &lt;/p&gt;

&lt;p&gt;From there on we can retrive data using offsets of so called "netvars". &lt;/p&gt;

&lt;p&gt;Se that we don't need to add a function called "getHealth", one called "getTeam, another one called "getOrigin" i.e i wrote a resolver which makes use of a predefined offset list and generates read and write memory function for each memory offset.  &lt;/p&gt;

&lt;p&gt;The create resolver function looks like this: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fngw4ym2lp8ilcmwly9zm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fngw4ym2lp8ilcmwly9zm.png" alt="Alt Text" width="800" height="441"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;createResolver &lt;/p&gt;

&lt;p&gt;As you can see the createResolver function is also pretty forwarded. &lt;br&gt;
At this point please understand that not all of those offsets inside our offset list are actually offsets belonging to Entitys but because of lazyness i didn't create an extra class for offsets which belong to Entitys only which means that our entity resolver will contain read/ write functions which are basically pointing to some invalid memory.&lt;/p&gt;

&lt;p&gt;I just took the dumped offsets as they are from the hazeDumper repository on github - which i linked in the beginning. -   without making any customization&lt;/p&gt;

&lt;h2&gt;
  
  
  Topics of the next posts
&lt;/h2&gt;

&lt;p&gt;In the next episods will cover the following topics&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The entity class to read player data,&lt;/li&gt;
&lt;li&gt;The websocket server to be able to communicate data to the overlay&lt;/li&gt;
&lt;li&gt;The calculations to transform 3D World Data to 2D Radar data&lt;/li&gt;
&lt;li&gt;The electron frontend to create a overlay which will render the radar over 
the games screen&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;So, if you are interested in reading more, stay tuned :-)&lt;/p&gt;

&lt;p&gt;github repo to the finished proof of concept: &lt;br&gt;
&lt;a href="https://github.com/xsip/external-csgo-typescript" rel="noopener noreferrer"&gt;https://github.com/xsip/external-csgo-typescript&lt;/a&gt;&lt;/p&gt;

</description>
      <category>node</category>
      <category>reverseengineering</category>
      <category>electron</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Automated Sourcemap SourceContent Extraction by URL</title>
      <dc:creator>Kerschbaumer Stefan</dc:creator>
      <pubDate>Sun, 26 Jan 2020 12:56:14 +0000</pubDate>
      <link>https://forem.com/xsip/automated-sourcemap-sourcecontent-extraction-by-url-40pj</link>
      <guid>https://forem.com/xsip/automated-sourcemap-sourcecontent-extraction-by-url-40pj</guid>
      <description>&lt;p&gt;Today I wrote a nodeJs script called "pack-scraper".&lt;/p&gt;

&lt;p&gt;What it does is walking through all script tags within the HTML body fetched from a provided url by the parameter "page" to check if there is any sourceMapUrl provided within any of the loaded Javascript files.&lt;/p&gt;

&lt;p&gt;If pack-scraper finds any sourceMapUrls within the javascript files it will clone them to a local folder described by the parameter "outDir" and afterwards extracts the source files from this sourcemap files if available.&lt;/p&gt;

&lt;p&gt;so, i.e we could serve a local angular app and execute:&lt;br&gt;
"npm run cli outDir=example page=&lt;a href="http://localhost:4200" rel="noopener noreferrer"&gt;http://localhost:4200&lt;/a&gt;" to basically get the same sourcecode like the project contains if sourcemaps are enabled and the "sourceContent" array isn't empty.&lt;/p&gt;

&lt;p&gt;Please note that this is a tool developed for analyzing.&lt;/p&gt;

&lt;p&gt;You may wondering what happens with lazy loaded javascript files in Angular applications for example?&lt;/p&gt;

&lt;p&gt;Those files are currently not automatically added to extraction, so if you wanna unpack them also you need to click through all routes in a i.e Angular page and finally provide the obtained script list to "additionalScripts" parameter seperated by a comma.&lt;/p&gt;

&lt;p&gt;Since this scraper should basically be focused on Angular applications I am anyway planing on implementing a Class to analyze the mainbundle and finally its subbundles so it can extract paths and automate this process.&lt;/p&gt;

&lt;p&gt;To get a list of available commands execute "npm run cli help" after cloning and running "npm i"&lt;br&gt;
The sourcecode can be found here: &lt;a href="https://github.com/xsip/pack-scraper" rel="noopener noreferrer"&gt;https://github.com/xsip/pack-scraper&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsswwptwjd0tw82d6qrt1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsswwptwjd0tw82d6qrt1.png" alt="Alt Text" width="800" height="535"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webpack</category>
      <category>typescript</category>
      <category>sourcemaps</category>
      <category>angular</category>
    </item>
    <item>
      <title>Disabling Prod Mode in already Built Angular App in Chrome</title>
      <dc:creator>Kerschbaumer Stefan</dc:creator>
      <pubDate>Wed, 22 Jan 2020 06:07:58 +0000</pubDate>
      <link>https://forem.com/xsip/disabling-prod-mode-in-angular-app-in-chrome-23kj</link>
      <guid>https://forem.com/xsip/disabling-prod-mode-in-angular-app-in-chrome-23kj</guid>
      <description>&lt;p&gt;In this small post i am talking about chromes "Override" tab.&lt;/p&gt;

&lt;p&gt;Maybe this is well known and widely used  but I just found out about it today and wanted to push it for beginners or people which are not using this cool feature of the Chrome DevTools for debugging.&lt;/p&gt;

&lt;p&gt;Since chrome version 65 - any yeah I know that this version has been released back in the beginning of 2018 -  there is a tab called "Overrides" within its DevTools Sources section which can be used to replace files which are normaly requested from the server belonging to the frontend with local files. &lt;/p&gt;

&lt;p&gt;For this to work you just need to open your DevTools and go to Sources, from there you click on "Overrides" and select a folder for overrides.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvpyf3ugotxki2f6hun2k.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvpyf3ugotxki2f6hun2k.png" alt="Alt Text" width="800" height="44"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After that you can go back to sources and right mouse click on a file to save it for overrides.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy785l2vwraobhkkxa0p8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy785l2vwraobhkkxa0p8.png" alt="Alt Text" width="200" height="191"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Chrome will then create a folder within your selected override folder named like the page you saved the file from containing all files you saving for this domain. &lt;/p&gt;

&lt;p&gt;From here on you can make changes using the DevTools itself or any editor you'd like to use.&lt;/p&gt;

&lt;p&gt;I.e we can take any main Js file generated after angulars build process and search for "enableProdMod" to in the end remove that line of code and get "ng.probe" again even after reloads.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhgyeigsn6iibtwxenm7c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhgyeigsn6iibtwxenm7c.png" alt="Alt Text" width="403" height="77"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5ahow7rkzfi0gqh4t2dc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5ahow7rkzfi0gqh4t2dc.png" alt="Alt Text" width="800" height="22"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;happy debugging.&lt;/p&gt;

</description>
      <category>angular</category>
      <category>chrome</category>
      <category>javascript</category>
      <category>beginners</category>
    </item>
  </channel>
</rss>
