📄 consolidated_script.js
/home/palash/git/site-assets/consolidated_script.js
Language: js • Lines: 540
const staticMap = {
    cdn: "https://palash90.github.io/site-assets",
    path_var: "",
    raw_content_cdn: "https://raw.githubusercontent.com/Palash90",
    
    themeHeaderColor: "", // tomato -- dealt in app.css custom theme
    themePColor: "", // orange -- dealt in app.css custom theme
    projectCardHeaderColor: "", // -- dealt in app.css custom theme
    projectCardBodyColor: "" // -- dealt in app.css custom theme
}

const getCommon = (key) => staticMap[key]
function getLatestDate(date1, date2) {
    // Check if both dates are null or undefined
    if (!date1 && !date2) {
        return null;
    }

    // If only one date is null or undefined, return the other date
    if (!date1) {
        return date2;
    }

    if (!date2) {
        return date1;
    }

    // Compare the dates and return the latest one
    return date1 > date2 ? date1 : date2;
}

const getDateString = (date) => {
    if (!date) {
        return date
    }

    let year = new Intl.DateTimeFormat('en', { year: 'numeric' }).format(date);
    let month = new Intl.DateTimeFormat('en', { month: 'short' }).format(date);
    let day = new Intl.DateTimeFormat('en', { day: '2-digit' }).format(date);

    return `${month} ${day}, ${year}`;
}

const modifyArray = (arr) => {

    arr = arr.map(c => {
        c = { ...c }
        c.publishDate = c.publishDate ? new Date(c.publishDate) : undefined
        c.lastUpdated = c.lastUpdated ? new Date(c.lastUpdated) : undefined

        c.sortBy = getLatestDate(c.publishDate, c.lastUpdated)
        return c
    })

    arr.sort((a, b) => b.sortBy - a.sortBy)

    return arr.map(c => {
        return {
            ...c,
            publishDate: getDateString(c.publishDate),
            lastUpdated: getDateString(c.lastUpdated),
        }
    })
}


var sweContents = [
  {
    id: "static-file-hosting",
    title: "Simple Static File Hosting",
    mdUrl: getCommon("cdn") + "/target/blogs/static-file-hosting/README.md",
    publishDate: "Nov 08, 2024",
  },
  {
    id: "grafana-on-aws",
    title: "Configure Grafana on AWS",
    mdUrl: getCommon("cdn") + "/target//blogs/aws-grafana/README.md",
    publishDate: "Jun 11, 2024",
  },
  {
    id: "vi-essentials",
    title: "vi Essentials",
    publishDate: "Nov 01, 2020",
    mdUrl: getCommon("cdn") + "/target/blogs/vi/README.md",
  },
  {
    id: "go-essentials",
    title: "Go Essentials",
    publishDate: "Nov 01, 2020",
    mdUrl: getCommon("cdn") + "/target/blogs/go-tut/README.md",
  },
  {
    id: "setting-up-a-site-1",
    title: "Hosting a website on the cloud - The Design",
    publishDate: "Nov 14, 2024",
    mdUrl: getCommon("cdn") + "/target/blogs/setting-up-a-site/part-1.md",
    series: "Setting Up a Site",
    seriesOrder: 1
  },
  {
    id: "setting-up-a-site-2",
    title:
      "Hosting a website on the cloud - Low Level Design and Implementation",
    publishDate: "Nov 20, 2024",
    mdUrl: getCommon("cdn") + "/target/blogs/setting-up-a-site/part-2.md",
    series: "Setting Up a Site",
    seriesOrder: 2
  },
  {
    id: "setting-up-a-site-3",
    title: "Hosting a website on the cloud - The Database",
    publishDate: "Nov 24, 2024",
    mdUrl: getCommon("cdn") + "/target/blogs/setting-up-a-site/part-3.md",
    contentType: "swe",
    series: "Setting Up a Site",
    seriesOrder: 3
  },
  {
    id: "setting-up-a-site-4",
    title: "Hosting a website on the cloud: The User Experience",
    mdUrl: getCommon("cdn") + "/target/blogs/setting-up-a-site/part-4.md",
    publishDate: "Dec 19, 2024",
    contentType: "swe",
    series: "Setting Up a Site",
    seriesOrder: 4
  },
  {
    id: "fearless-rust-write-test",
    title: "Fearless Rust: Write Test",
    videoId: "ng5FK6wkR58",
    mdUrl: getCommon("cdn") + "/target/blogs/fearless-rust/write-test.md",
    publishDate: "Feb 08, 2025",
    contentType: "swe",
    series: "Fearless Rust",
    seriesOrder: 1
  },
  {
    id: "fearless-rust-non-blocking-1",
    title:
      "Fearless Rust: Write a Non Blocking TCP Server From Scratch - Part 1",
    mdUrl: getCommon("cdn") + "/target/blogs/fearless-rust/non-blocking-1.md",
    publishDate: "Feb 13, 2025",
    contentType: "swe",
    series: "Fearless Rust",
    seriesOrder: 2
  },
  {
    id: "iron-learn-1",
    title: " Resuming my journey on learning the basics of AI",
    mdUrl: getCommon("cdn") + "/target/blogs/iron-learn/iron-learn-1.md",
    publishDate: "Nov 18, 2025",
    contentType: "swe",
    series: "Building a Neural Network from Scratch in Rust",
    seriesOrder: 1
  },
  {
    id: "iron-learn-2",
    title:
      " Making my Machine Decide Based on Data",
    mdUrl: getCommon("cdn") + "/target/blogs/iron-learn/iron-learn-2.md",
    publishDate: "Nov 22, 2025",
    contentType: "swe",
    series: "Building a Neural Network from Scratch in Rust",
    seriesOrder: 2
  },
  {
    id: "iron-learn-3",
    title: " The Joy of Running Parallel",
    mdUrl: getCommon("cdn") + "/target/blogs/iron-learn/iron-learn-3.md",
    publishDate: "Nov 23, 2025",
    contentType: "swe",
    series: "Building a Neural Network from Scratch in Rust",
    seriesOrder: 3
  },
  {
    id: "iron-learn-4",
    title: " The Bubble Burst",
    mdUrl: getCommon("cdn") + "/target/blogs/iron-learn/iron-learn-4.md",
    publishDate: "Nov 27, 2025",
    contentType: "swe",
    series: "Building a Neural Network from Scratch in Rust",
    seriesOrder: 4
  },
  {
    id: "iron-learn-5",
    title: "The Comeback",
    mdUrl: getCommon("cdn") + "/target/blogs/iron-learn/iron-learn-5.md",
    publishDate: "Dec 03, 2025",
    contentType: "swe",
    series: "Building a Neural Network from Scratch in Rust",
    seriesOrder: 5
  }, {
    id: "iron-learn-6",
    title: "Building the First Neural Network",
    mdUrl: getCommon("cdn") + "/target/blogs/iron-learn/iron-learn-6.md",
    publishDate: "Dec 06, 2025",
    contentType: "swe",
    series: "Building a Neural Network from Scratch in Rust",
    seriesOrder: 6
  }, {
    id: "iron-learn-7",
    title: "CUDA Integration with Python",
    mdUrl: getCommon("cdn") + "/target/blogs/iron-learn/iron-learn-7.md",
    publishDate: "Dec 31, 2025",
    contentType: "swe",
    series: "Building a Neural Network from Scratch in Rust",
    seriesOrder: 7
  }, {
    id: "iron-learn-8",
    title: "Proving the Universal Approximation Theorem with Rust",
    mdUrl: getCommon("cdn") + "/target/blogs/iron-learn/iron-learn-8.md",
    publishDate: "Jan 01, 2026",
    contentType: "swe",
    series: "Building a Neural Network from Scratch in Rust",
    seriesOrder: 8
  }, {
    id: "iron-learn-9",
    title: "Generating Simba Network with Rust",
    mdUrl: getCommon("cdn") + "/target/blogs/iron-learn/iron-learn-9.md",
    publishDate: "Jan 06, 2026",
    contentType: "swe",
    series: "Building a Neural Network from Scratch in Rust",
    seriesOrder: 9
  }, {
    id: "iron-learn-10",
    title: "The Grand Finale: The Full Image Reconstruction Network from Scratch in Rust",
    mdUrl: getCommon("cdn") + "/target/blogs/iron-learn/iron-learn-10.md",
    publishDate: "Jan 07, 2026",
    contentType: "swe",
    series: "Building a Neural Network from Scratch in Rust",
    seriesOrder: 10
  }, {
    id: "terminal-plotter",
    title: "Writing a Minimal Terminal Plotter",
    mdUrl: getCommon("cdn") + "/target/blogs/writing-terminal-plotter/read.md",
    publishDate: "Jan 22, 2026",
    contentType: "swe"
  }, {
    id: "building-a-word-quiz",
    title: "Building a Real-Time Voice-Driven Word Quiz from Scratch",
    mdUrl: getCommon("cdn") + "/target/blogs/building-a-word-quiz/part-1.md",
    publishDate: "Jun 15, 2026",
    contentType: "swe"
  }, {
    id: "building-a-tab-viewer",
    title: "Building a Web Audio and SVG Synchronized Tab Reader/Writer from scratch",
    mdUrl: getCommon("cdn") + "/target/blogs/tab-viewer-journey/part-1.md",
    publishDate: "Jun 30, 2026",
    contentType: "swe"
  }, {
    id: "building-a-private-cloud",
    title: "Building a Private Cloud: WireGuard, Docker Desktop, and the Silent Linux Kernel Drops",
    mdUrl: getCommon("cdn") + "/target/blogs/private-cloud/part-1.md",
    publishDate: "Jul 17, 2026",
    contentType: "swe"
  },
  {
    id: "private-ai-on-a-budget-multi-functional-llm-on-a-4gb-rtx-3050",
    title: "Private AI on a Budget: Multi-Functional LLMs on a 4GB RTX 3050",
    mdUrl: getCommon("cdn") + "/target/blogs/local-ai/README.md",
    publishDate: "Aug 01, 2026",
    contentType: "swe"
  }
];

sweContents = modifyArray(sweContents);

var musicContents = [
    {
        id: "sliding-shape-guitalele",
        publishDate: "Oct 16, 2024",
        title: "Sliding Shape Guitalele",
        videoId: "hMBpAPGqX8k"
    },
    {
        id: "guitalele-tuning",
        publishDate: "Sep 19, 2021",
        title: "Guitalele Introduction and Tuning",
        videoId: "wBUBEBuk2Jo",
        mdUrl: getCommon("cdn") + "/target/blogs/guitalele-tuning/README.md",
        tab: getCommon("cdn") + "/target/blogs/guitalele-tuning/tab.txt",
        series: "Guitalele Basics",
        seriesOrder: 1
    },
    {
        id: "guitalele-tab-quick-view",
        publishDate: "May 29, 2026",
        title: "Guitalele Tab Reading Guide",
        mdUrl:
            getCommon("cdn") +
            "/target/blogs/tab-reading-quick-ref/GUITALELE_TAB_READING_GUIDE.md",
        tab:
            getCommon("cdn") +
            "/target/blogs/guitalele-tabs/maryHadALittleLamb.txt",
        series: "Guitalele Tabs & Melodies",
        seriesOrder: 2
    },
    {
        id: "all-open-chords",
        publishDate: "Aug 03, 2022",
        title: "Guitalele All Open Chords",
        videoId: "goFLzPdH7D4",
        tab: getCommon("cdn") + "/target/blogs/guitalele-tabs/all-open-chords.txt",
        series: "Guitalele Basics",
        seriesOrder: 2
    },
    {
        id: "ode-to-joy",
        publishDate: "Jun 13, 2026",
        title: "Ode to Joy - Chord Melody",
        tab:
            getCommon("cdn") +
            "/target/blogs/guitalele-tabs/ode-to-joy.txt",
        series: "Guitalele Tabs & Melodies",
        seriesOrder: 1
    }
];

musicContents = modifyArray(musicContents);

var drafts = [
    {
        id: "setting-up-a-site",
        title: "Simple Static File Hosting",
        mdUrl: getCommon("cdn") + "/target/blogs/setting-up-a-site/README.md",
        publishDate: "Nov 08, 2021",
        contentType: "swe",
        draft: true
    },
    {
        id: "distributed-systems",
        title: "Internet is Ubiquitos",
        mdUrl: getCommon("cdn") + "/target/blogs/distributed-systems/01.md",
        publishDate: "",
        contentType: "swe",
        draft: true
    },
    {
        id: "writing-process",
        title: "Add a new element in website",
        mdUrl: getCommon("cdn") + "/target/blogs/writing-process/README.md",
        publishDate: "",
        contentType: "swe",
        draft: true
    }
];
function hasDuplicateProperty(arr, prop) {
    const seen = new Set();
    for (const item of arr) {
        if (seen.has(item[prop])) {
            console.log(item[prop], "has duplicate entry")
            return true; // Duplicate found
        }
        seen.add(item[prop]);
    }
    return false; // No duplicates
}

var allContents = sweContents.concat(musicContents).concat(drafts)

if(hasDuplicateProperty(allContents, "id")){
    throw Error("Duplicate blog id found");
}

const contents = {
    swe: sweContents,
    music: musicContents,
    drafts: drafts
}
const projects = [
    {
        id: "iron-learn",
        name: "Iron Learn",
        desc: "A pure Rust Machine Learning Library",
        type: "rust",
        githubUrl: "https://github.com/Palash90/iron_learn",
        mdUrl: getCommon('raw_content_cdn') + "/iron_learn/refs/heads/main/README.md"
    },
    {
        id: "hdl-emulator",
        name: "HDL Emulator",
        desc: "An online Web Based HDL Emulator for Teaching Purpose",
        type: "javascript",
        playUrl: "https://emulator.palashkantikundu.in/",
        githubUrl: "https://github.com/Palash90/emulator",
        mdUrl: getCommon('raw_content_cdn') + "/emulator/refs/heads/main/README.md"
    },
    {
        id: "dist-fs",
        name: "Distributed File System",
        desc: "A simple distributed file system implementation",
        type: "java",
        githubUrl: "https://github.com/Palash90/dist-fs",
        mdUrl: getCommon('raw_content_cdn') + "/dist-fs/refs/heads/main/README.md"
    },
    {
        id: "tic-tac-slide",
        name: "Tic Tac Slide",
        desc: "An innovation over simple tic tac toe for added fun",
        type: "react",
        playUrl: getCommon('path_var') + "/component/tic-tac-slide",
        githubUrl: ""
    },
    {
        id: "study",
        name: "Quiz App",
        desc: "A simple quiz game for kids.",
        type: "react",
        playUrl: getCommon('path_var') + "/component/study",
        githubUrl: ""
    }
]
const data = {
    name: "Palash Kanti Kundu",
    shortName: "Palash",
    labels: {
        contents: "Blogs",
        projects: "Projects",
        swe: "Software Engineering",
        music: "Music",
        contentNotExists: "Content does not exist",
        publishedOn: "Published on: ",
        lastUpdated: "Last updated on: "
    },
    pages: {
        contents: {
            header: "Blogs",
            techHeader: "Tech Blogs",
            musicHeader: "Music Blogs",
            intro: "Software Engineering is what I do for a living, music is what I do to live. Here you can find both.",
            techIntro: "Code, Insights, and the Art of Problem-Solving.",
            musicIntro: "Exploring the World of Music, One Post at a Time.",
            itemsPerPage: 50,

            techBlogClass: "tech-blog-content markdown-color",
            musicBlogClass: "blog-content markdown-color",
            genericBlogClass: "blog-content markdown-color",

            sweHeadColor: getCommon('themeHeaderColor'),
            musicHeadColor: getCommon('themeHeaderColor'),
            h1Color: getCommon('themeHeaderColor'),
            pColor: getCommon('themePColor'),

            linkClass: ""
        },
        home: {
            tag: "Crafting code, creating harmony.",
            greeting: "Hi, I'm ",
            moto: "My moto: ",
            motos: ["Code", "Create", "Inspire"],
            desc: "I’m a software engineer with 14 years of experience, specializing in tech stacks like Java, Python, C#, React.js and Rust. Apart from my day-to-day office work, I’ve built a machine learning library, implemented parts of a distributed system, few react.js based games, and am passionate about system design. I also contribute to community through my blogs to share insights and learnings. \n \n  Outside of software engineering, I pursue music, specifically creating guitalele tutorials, which helps me stay creative and balanced.\n\n",
            profilePicUrl: getCommon("cdn") + "/assets/profile.jpg",

            mainStyle: "main-app-lora custom-theme",
            secondaryStyle: "content-body-opensans",
            class: "",

            techBlogHeader: "Recent Tech Blogs | ",
            techBlogTag: "Things I learned or implemented recently",
            techBlogShowAll: "Show All",

            musicBlogHeader: "Recent Music Blogs | ",
            musicBlogShowAll: "Show All",
            musicBlogTag: "Things I explored recently",

            h1Color: getCommon('themeHeaderColor'),
            pColor: getCommon('themePColor')
        },
        projects: {
            intro: "If any idea catches my attention, I try to implement the same.",
            techStack: "Technology: ",

            h1Color: getCommon('themeHeaderColor'),
            pColor: getCommon('themePColor'),
            titleColor: getCommon('projectCardHeaderColor'),
            bodyColor: getCommon('projectCardBodyColor')
        },
        about: {
            mdUrl: getCommon("cdn") + "/assets/ME.md",
            resume: getCommon("cdn") + "Palash_Kanti_Kundu_14YOE_BackEnd_AI.pdf",
            resumeName: "Palash_Kanti_Kundu_14YOE_BackEnd_AI.pdf",
            blogClass: "blog-content markdown-color"
        }
    },
    techStack: {
        iconColor: {
            rust: "#B7410E",
            java: "blue",
            javascript: "red",
            react: "teal"
        },
        title: {
            rust: "Rust",
            java: "Java",
            javascript: "JavaScript",
            react: "React.js"
        }
    },
    navLinks: [
        { label: "Home", link: getCommon("path_var") + "/" },
        { label: "Tech Blogs", link: getCommon("path_var") + "/contents/tech" },
        { label: "Music Blogs", link: getCommon("path_var") + "/contents/music" },
        { label: "Projects", link: getCommon("path_var") + "/projects" },
        { label: "About", link: getCommon("path_var") + "/about" }
        /*{ label: "Sitemap", link: "https://sitemap.palashkantikundu.in/" }*/
    ],
    contents: contents,
    projects: projects,
    about: {
        jobs: [
            { name: "Hewlett Packard Enterprise", start: "December 2022", end: "Present", location: "Bengaluru, India", role: "Cloud Deverloper III" },
            { name: "GE Renewable Energy", start: "December 2018", end: "November 2022", location: "Hyderabad, India", role: "Senior Software Engineer" },
            { name: "Oracle India Pvt. Ltd.", start: "January 2016", end: "December 2018", location: "Hyderabad, India", role: "Senior Applications Engineer" },
            { name: "HCL Technologies", start: "November 2014", end: "November 2015", location: "Kolkata, India", role: "Senior Software Engineer" },
            { name: "Cognizant Technology Solutions", start: "November 2011", end: "October 2014", location: "Kolkata, India", role: "Programmer Analyst" },
        ],
        education: [
            { institution: "College of Engineering and Management, Kolaghat", start: "July 2007", end: "Jun 2011", degree: "Bachelor of Technology" }
        ]
    },
    test:"Hello Main committed by github action flow",
    try:"try once again"
}


function findProp(prop) {
    var obj = data
    prop = prop.split('.');
    for (var i = 0; i < prop.length; i++) {
        if (typeof obj[prop[i]] == 'undefined')
            return null;
        obj = obj[prop[i]];
    }
    return obj;
}
const fs = require('fs');

// Write data.json — only contents key; common config + findProp are in the Firebase app
fs.writeFileSync("data.json", JSON.stringify({ contents: data.contents }, null, 2))
console.log("Writing data.json")