How to continue variable data respectively?

I create a analog clock away from the traditional method.
It have 30 hours

12 seconds = 1 minute
12 minutes = 1 hour

‘Second-hand’ need to complete one circle by 12 steps.
when ‘Second-hand’ complete one circle then, ‘minute-hand’ need to move one step.
like that ‘minute-hand’ need to complete a circle by 12 steps too.
When ‘minute-hand’ complete one circle then, hour circle need to move one step.
In this way ‘hour-hand’ need to complete entire circle’by 30 steps.

But in this program its unable to move ‘minute-hand’ properly.

html code :

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <link href="styles.css" rel="stylesheet">
  <script defer src="script.js"></script>
  <title>Clock</title>
</head>
<body>
  <div class="clock">
    <div class="hand hour" data-hour-hand></div>
    <div class="hand minute" data-minute-hand></div>
    <div class="hand second" data-second-hand></div>

    <div class="number number1">1</div>
    <div class="number number2">2</div>
    <div class="number number3">3</div>
    <div class="number number4">4</div>
    <div class="number number5">5</div>
    <div class="number number6">6</div>
    <div class="number number7">7</div>
    <div class="number number8">8</div>
    <div class="number number9">9</div>
    <div class="number number10">10</div>
    <div class="number number11">11</div>
    <div class="number number12">12</div>
    <div class="number number13">13</div>
    <div class="number number14">14</div>
    <div class="number number15">15</div>
    <div class="number number16">16</div>
    <div class="number number17">17</div>
    <div class="number number18">18</div>
    <div class="number number19">19</div>
    <div class="number number20">20</div>
    <div class="number number21">21</div>
    <div class="number number22">22</div>
    <div class="number number23">23</div>
    <div class="number number24">24</div>
    <div class="number number25">25</div>
    <div class="number number26">26</div>
    <div class="number number27">27</div>
    <div class="number number28">28</div>
    <div class="number number29">29</div>
    <div class="number number30">30</div>
  </div>
</body>
</html>

css code:

*, *::after, *::before {
  box-sizing: border-box;
  font-family: Gotham Rounded, sans-serif;
}

body {
  background: linear-gradient(to right, hsl(200, 100%, 50%), hsl(175, 100%, 50%));
  display: flex;
  justify-content: center;
  align-items: center;
  min-height: 100vh;
  overflow: hidden;
}

.clock {
  width: 700px;
  height: 700px;
  background-color: rgba(255, 255, 255, .8);
  border-radius: 50%;
  border: 2px solid black;
  position: relative;
}

.clock .number {
  --rotation: 0;
  position: absolute;
  width: 100%;
  height: 100%;
  text-align: center;
  transform: rotate(var(--rotation));
  font-size: 1.5rem;
}

.clock .number1 { --rotation: 12deg; }
.clock .number2 { --rotation: 24deg; }
.clock .number3 { --rotation: 36deg; }
.clock .number4 { --rotation: 48deg; }
.clock .number5 { --rotation: 60deg; }
.clock .number6 { --rotation: 72deg; }
.clock .number7 { --rotation: 84deg; }
.clock .number8 { --rotation: 96deg; }
.clock .number9 { --rotation: 108deg; }
.clock .number10 { --rotation: 120deg; }
.clock .number11 { --rotation: 132deg; }
.clock .number12 { --rotation: 144deg; }
.clock .number13 { --rotation: 156deg; }
.clock .number14 { --rotation: 168deg; }
.clock .number15 { --rotation: 180deg; }
.clock .number16 { --rotation: 192deg; }
.clock .number17 { --rotation: 204deg; }
.clock .number18 { --rotation: 216deg; }
.clock .number19 { --rotation: 228deg; }
.clock .number20 { --rotation: 240deg; }
.clock .number21 { --rotation: 252deg; }
.clock .number22 { --rotation: 264deg; }
.clock .number23 { --rotation: 276deg; }
.clock .number24 { --rotation: 288deg; }
.clock .number25 { --rotation: 300deg; }
.clock .number26 { --rotation: 312deg; }
.clock .number27 { --rotation: 324deg; }
.clock .number28 { --rotation: 336deg; }
.clock .number29 { --rotation: 348deg; }
.clock .number30 { --rotation: 360deg; }

.clock .hand {
  --rotation: 0;
  position: absolute;
  bottom: 50%;
  left: 50%;
  border: 1px solid white;
  border-top-left-radius: 10px;
  border-top-right-radius: 10px;
  transform-origin: bottom;
  z-index: 10;
  transform: translateX(-50%) rotate(calc(var(--rotation) * 1deg));
}

.clock::after {
  content: '';
  position: absolute;
  background-color: black;
  z-index: 11;
  width: 15px;
  height: 15px;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  border-radius: 50%;
}

.clock .hand.second {
  width: 3px;
  height: 45%;
  background-color: red;
}

.clock .hand.minute {
  width: 7px;
  height: 40%;
  background-color: #443f3f;
}

.clock .hand.hour {
  width: 10px;
  height: 35%;
  background-color: black;
}

javascript code :

document.addEventListener("DOMContentLoaded", function () {
  const hourHand = document.querySelector("[data-hour-hand]");
  const minuteHand = document.querySelector("[data-minute-hand]");
  const secondHand = document.querySelector("[data-second-hand]");

  let totalMilliseconds = 0;
  let previousSecond = 0;
  let secondsCounter = 0;

  function updateClock() {
    // Calculate Sinhala time with 12 minutes per hour
    const sinhalaHours = Math.floor(totalMilliseconds / (30 * 60 * 12 * 1000));
    const remainingMilliseconds = totalMilliseconds % (30 * 60 * 12 * 1000);
    const sinhalaMinutes = Math.floor(remainingMilliseconds / (60 * 12 * 1000));
    const sinhalaSeconds = Math.floor((remainingMilliseconds % (60 * 12 * 1000)) / 1000);

    // Check if a new second circle has started
    if (sinhalaSeconds < previousSecond) {
      // Increment minute only when a new second circle starts
      sinhalaMinutes++;
      // Reset the seconds counter
      secondsCounter = 0;
    }

    // Calculate degrees for each hand
    const hourDeg = (sinhalaHours + sinhalaMinutes / 60) * 360 / 30;
    const minuteDeg = (sinhalaMinutes + sinhalaSeconds % 12) * 360 / 12; // Adjust for 12 steps
    const secondDeg = (sinhalaSeconds % 12) * 360 / 12; // Adjust for 12 steps

    // Apply rotations to the clock hands
    hourHand.style.transform = `rotate(${hourDeg}deg)`;
    minuteHand.style.transform = `rotate(${minuteDeg}deg)`;
    secondHand.style.transform = `rotate(${secondDeg}deg)`;

    // Update the previous second and seconds counter
    previousSecond = sinhalaSeconds;
    secondsCounter++;
  }

  // Update the total milliseconds and the clock every 1000 milliseconds (1 second)
  setInterval(function () {
    totalMilliseconds += 1000;
    updateClock();
  }, 1000);

  // Initial call to set the clock when the page loads
  updateClock();
});

Codewars Madhav array js

A Madhav array has the following property:

a[0] = a[1] + a[2] = a[3] + a[4] + a[5] = a[6] + a[7] + a[8] + a[9] = …

Complete the function/method that returns true if the given array is a Madhav array, otherwise it returns false.

Edge cases: An array of length 0 or 1 should not be considered a Madhav array as there is nothing to compare.

function isMadhavArray(arr) {
  if (arr.length < 3) {
    return false;
  }
  
  let goal = arr[0];
  arr.shift();
  
  let n = 2;
  
  while (arr.length > 0) { 
    let remove_items = arr.splice(0, n);
    
    let sum = remove_items.reduce((a, c) => a + c, 0);
    
    if (goal == sum) {
      n++
    } else {
      return false;
    }
  }
  
  return true; 
}

According to my solution, it passes 111 out of 113 tests, what am I missing?

Issue with Overriding XMLHttpRequest.prototype.send in Chrome Extension

Hello StackOverflow community,

I am working on a Chrome extension where I need to intercept and manipulate XMLHttpRequests. To achieve this, I am overriding the send method of the XMLHttpRequest object. However, I’m facing an issue: the override does not seem to function as expected. When testing the extension, the requests are not being intercepted as they should be.

Here is a snippet of the relevant code:

javascript

var originalSend = XMLHttpRequest.prototype.send;

function main() {
    console.log("main function called");

    try {
        XMLHttpRequest.prototype.send = function () {
            console.log("XHR send override called");

            this.addEventListener(
                "readystatechange",
                function () {
                    console.log("XHR request state changed:", this.readyState);

                    if (this.responseURL.includes("/api/graphql/") && this.readyState === 4) {
                        console.log("API response received:", this.responseText);
                        // Call to response processing function
                        parseResponse(this.responseText);
                    }
                },
                false
            );
            originalSend.apply(this, arguments);
        };

        // Other functions and logic...
    } catch (error) {
        console.log('Error executing main:', error);
    }
}

// Other functions like parseResponse, etc.

The script is executed as a content script in the extension. When executed, the logs indicate that the main function is being called, but the XMLHttpRequests do not seem to be intercepted as I expect.

Here’s what I’ve already checked:

The override of the send method appears to be correct.
The logs in the event listeners show that the function is reached, but the conditions do not seem to match the expected requests.
I am using Manifest V3 for my Chrome extension.

I’m wondering if I’m missing something in the way I’m overriding the method or in how XMLHttpRequests are handled in Chrome extensions.

Any help or suggestions would be greatly appreciated. Thank you in advance!

v-if not updating with global function regarding cookies

In a .vue view I have the followign line of code:

<p v-if="this.$cookies.logged()">Some text</p>

and in main.js the function mentioned above is defined:

Vue.prototype.$cookies = Vue.observable({
  logged: function(){
    const value = `; ${document.cookie}`;
    const parts = value.split(`; ${'initSession'}=`);
    if (parts.length === 2 && parts.pop().split(';').shift() == 'true') return true;
    else return false;
  },
});

However, the v-if does not update with the function i.e. when the function returns true the paragraph is not shown.

How may I solve this?

Puppeteer depp diving

Im trying to scrape my school schedule from Visma Inschool. Since its hosted local on the school i have permission to do so.

Im trying to make a info screen and im completly lost when it comes to grab the schedule.

With this code:

async function getInfo(){
        //identify element
        const f = await page.$("[class='active Timetable-TimetableDays_day']")
        //obtain text
        const text = await (await f.getProperty('textContent')).jsonValue()
        console.log("The day is: " + text)
     }

I get the whole active day in one text, i want it to be like splitt up into different text’s so i can crab the next item on the schedule list, and also grab the teachers name and what classroom we’re goin to use.

I does not expect anything other than the output i am getting, because i don’t know what DOM to search for.

Here is the website as HTML

<div data-v-36c1dfe8="" role="gridcell" class="active Timetable-TimetableDays_day"><h3 data-v-36c1dfe8="" class="sr-only"> 7 Avtaler, torsdag 14 desember </h3><div data-v-36c1dfe8="" class="Timetable-Items"><div data-v-45669d56="" data-v-36c1dfe8="" class="popup-container" style="top: 40px; left: 0%;"><div data-v-36c1dfe8="" data-v-45669d56=""><h4 data-v-36c1dfe8="" data-v-45669d56="" class="sr-only"> Teknologiforståelse på rom E109. Undervisningstime. Starter 14. desember 2023 klokken 08:20 og slutter 09:05 </h4><div data-v-33d0fd5d="" data-v-36c1dfe8="" tabindex="0" aria-haspopup="dialog" test-id="vs-Timetable-item-4-0-135299254" class="Timetable-TimetableItem Timetable-TimetableItem-m" role="button" aria-label="Se detaljer om Teknologiforståelse på rom E109. Undervisningstime. Starter 14. desember 2023 klokken 08:20 og slutter 09:05" subjectcode="IKM1002" tttype="LESSON" starttimeanddateunix="1702538400" readonlyitems="[object Object],[object Object],[object Object],[object Object],[object Object]" actionitems="" teachername="Teacher" entityid="135299254" block="" teachinggroupid="12459877" data-v-45669d56="" style="border-left: 6px solid rgb(83, 237, 155); height: 90px; width: 100%;"><div data-v-33d0fd5d="" aria-hidden="true" class="Timetable-TimetableItem-wrapper"><div data-v-33d0fd5d="" class="Timetable-TimetableItem-header"><small data-v-33d0fd5d="" class="Timetable-TimetableItem-hours"><i data-v-33d0fd5d="" class="far fa-clock"></i> 08:20 - 09:05 </small><small data-v-33d0fd5d="" class="Timetable-TimetableItem-location"><i data-v-33d0fd5d="" class="far fa-map-marker"></i> E109 </small><!----></div><p data-v-33d0fd5d="" class="Timetable-TimetableItem-subject-name"> Teknologiforståelse </p><!----><small data-v-33d0fd5d="" class="Timetable-TimetableItem-type"> Undervisningstime </small><!----></div></div></div><!----></div><div data-v-45669d56="" data-v-36c1dfe8="" class="popup-container" style="top: 140px; left: 0%;"><div data-v-36c1dfe8="" data-v-45669d56=""><h4 data-v-36c1dfe8="" data-v-45669d56="" class="sr-only"> Teknologiforståelse på rom E109. Undervisningstime. Starter 14. desember 2023 klokken 09:10 og slutter 09:55 </h4><div data-v-33d0fd5d="" data-v-36c1dfe8="" tabindex="0" aria-haspopup="dialog" test-id="vs-Timetable-item-4-1-135299255" class="Timetable-TimetableItem Timetable-TimetableItem-m" role="button" aria-label="Se detaljer om Teknologiforståelse på rom E109. Undervisningstime. Starter 14. desember 2023 klokken 09:10 og slutter 09:55" subjectcode="IKM1002" tttype="LESSON" starttimeanddateunix="1702541400" readonlyitems="[object Object],[object Object],[object Object],[object Object],[object Object]" actionitems="" teachername="Teacher" entityid="135299255" block="" teachinggroupid="12459877" data-v-45669d56="" style="border-left: 6px solid rgb(83, 237, 155); height: 90px; width: 100%;"><div data-v-33d0fd5d="" aria-hidden="true" class="Timetable-TimetableItem-wrapper"><div data-v-33d0fd5d="" class="Timetable-TimetableItem-header"><small data-v-33d0fd5d="" class="Timetable-TimetableItem-hours"><i data-v-33d0fd5d="" class="far fa-clock"></i> 09:10 - 09:55 </small><small data-v-33d0fd5d="" class="Timetable-TimetableItem-location"><i data-v-33d0fd5d="" class="far fa-map-marker"></i> E109 </small><!----></div><p data-v-33d0fd5d="" class="Timetable-TimetableItem-subject-name"> Teknologiforståelse </p><!----><small data-v-33d0fd5d="" class="Timetable-TimetableItem-type"> Undervisningstime </small><!----></div></div></div><!----></div><div data-v-45669d56="" data-v-36c1dfe8="" class="popup-container" style="top: 260px; left: 0%;"><div data-v-36c1dfe8="" data-v-45669d56=""><h4 data-v-36c1dfe8="" data-v-45669d56="" class="sr-only"> Matematikk 1P-Y IM på rom E208. Undervisningstime. Starter 14. desember 2023 klokken 10:10 og slutter 10:55 </h4><div data-v-33d0fd5d="" data-v-36c1dfe8="" tabindex="0" aria-haspopup="dialog" test-id="vs-Timetable-item-4-2-135353441" class="Timetable-TimetableItem Timetable-TimetableItem-m" role="button" aria-label="Se detaljer om Matematikk 1P-Y IM på rom E208. Undervisningstime. Starter 14. desember 2023 klokken 10:10 og slutter 10:55" subjectcode="MAT1121" tttype="LESSON" starttimeanddateunix="1702545000" readonlyitems="[object Object],[object Object],[object Object],[object Object],[object Object]" actionitems="" teachername="Teacher" entityid="135353441" block="" teachinggroupid="12459866" data-v-45669d56="" style="border-left: 6px solid rgb(57, 57, 96); height: 90px; width: 100%;"><div data-v-33d0fd5d="" aria-hidden="true" class="Timetable-TimetableItem-wrapper"><div data-v-33d0fd5d="" class="Timetable-TimetableItem-header"><small data-v-33d0fd5d="" class="Timetable-TimetableItem-hours"><i data-v-33d0fd5d="" class="far fa-clock"></i> 10:10 - 10:55 </small><small data-v-33d0fd5d="" class="Timetable-TimetableItem-location"><i data-v-33d0fd5d="" class="far fa-map-marker"></i> E208 </small><!----></div><p data-v-33d0fd5d="" class="Timetable-TimetableItem-subject-name"> Matematikk 1P-Y IM </p><!----><small data-v-33d0fd5d="" class="Timetable-TimetableItem-type"> Undervisningstime </small><!----></div></div></div><!----></div><div data-v-45669d56="" data-v-36c1dfe8="" class="popup-container" style="top: 360px; left: 0%;"><div data-v-36c1dfe8="" data-v-45669d56=""><h4 data-v-36c1dfe8="" data-v-45669d56="" class="sr-only"> Yrkesfaglig fordypning vg1 på rom E109. Vikar. Starter 14. desember 2023 klokken 11:00 og slutter 11:45 </h4><div data-v-33d0fd5d="" data-v-36c1dfe8="" tabindex="0" aria-haspopup="dialog" test-id="vs-Timetable-item-4-3-135317780" class="Timetable-TimetableItem Timetable-TimetableItem-m" role="button" aria-label="Se detaljer om Yrkesfaglig fordypning vg1 på rom E109. Vikar. Starter 14. desember 2023 klokken 11:00 og slutter 11:45" tttype="SUBSTITUTION" originaltype="LESSON" starttimeanddateunix="1702548000" readonlyitems="[object Object],[object Object],[object Object],[object Object],[object Object]" actionitems="" teachername="Teacher" entityid="135317780" block="" teachinggroupid="12459773" data-v-45669d56="" style="border-left: 6px solid rgb(83, 237, 155); height: 90px; width: 100%;"><div data-v-33d0fd5d="" aria-hidden="true" class="Timetable-TimetableItem-wrapper"><div data-v-33d0fd5d="" class="Timetable-TimetableItem-header"><small data-v-33d0fd5d="" class="Timetable-TimetableItem-hours"><i data-v-33d0fd5d="" class="far fa-clock"></i> 11:00 - 11:45 </small><small data-v-33d0fd5d="" class="Timetable-TimetableItem-location"><i data-v-33d0fd5d="" class="far fa-map-marker"></i> E109 </small><!----></div><p data-v-33d0fd5d="" class="Timetable-TimetableItem-subject-name"> Yrkesfaglig fordypning vg1 </p><!----><small data-v-33d0fd5d="" class="Timetable-TimetableItem-type"> Vikar </small><!----></div></div></div><!----></div><div data-v-45669d56="" data-v-36c1dfe8="" class="popup-container" style="top: 510px; left: 0%;"><div data-v-36c1dfe8="" data-v-45669d56=""><h4 data-v-36c1dfe8="" data-v-45669d56="" class="sr-only"> Yrkesfaglig fordypning vg1 på rom E109. Vikar. Starter 14. desember 2023 klokken 12:15 og slutter 13:00 </h4><div data-v-33d0fd5d="" data-v-36c1dfe8="" tabindex="0" aria-haspopup="dialog" test-id="vs-Timetable-item-4-4-135317781" class="Timetable-TimetableItem Timetable-TimetableItem-m" role="button" aria-label="Se detaljer om Yrkesfaglig fordypning vg1 på rom E109. Vikar. Starter 14. desember 2023 klokken 12:15 og slutter 13:00" tttype="SUBSTITUTION" originaltype="LESSON" starttimeanddateunix="1702552500" readonlyitems="[object Object],[object Object],[object Object],[object Object],[object Object]" actionitems="" teachername="Teacher" entityid="135317781" block="" teachinggroupid="12459773" data-v-45669d56="" style="border-left: 6px solid rgb(83, 237, 155); height: 90px; width: 100%;"><div data-v-33d0fd5d="" aria-hidden="true" class="Timetable-TimetableItem-wrapper"><div data-v-33d0fd5d="" class="Timetable-TimetableItem-header"><small data-v-33d0fd5d="" class="Timetable-TimetableItem-hours"><i data-v-33d0fd5d="" class="far fa-clock"></i> 12:15 - 13:00 </small><small data-v-33d0fd5d="" class="Timetable-TimetableItem-location"><i data-v-33d0fd5d="" class="far fa-map-marker"></i> E109 </small><!----></div><p data-v-33d0fd5d="" class="Timetable-TimetableItem-subject-name"> Yrkesfaglig fordypning vg1 </p><!----><small data-v-33d0fd5d="" class="Timetable-TimetableItem-type"> Vikar </small><!----></div></div></div><!----></div><div data-v-45669d56="" data-v-36c1dfe8="" class="popup-container" style="top: 610px; left: 0%;"><div data-v-36c1dfe8="" data-v-45669d56=""><h4 data-v-36c1dfe8="" data-v-45669d56="" class="sr-only"> Yrkesfaglig fordypning vg1 på rom E109. Undervisningstime. Starter 14. desember 2023 klokken 13:05 og slutter 13:50 </h4><div data-v-33d0fd5d="" data-v-36c1dfe8="" tabindex="0" aria-haspopup="dialog" test-id="vs-Timetable-item-4-5-135321756" class="Timetable-TimetableItem Timetable-TimetableItem-m" role="button" aria-label="Se detaljer om Yrkesfaglig fordypning vg1 på rom E109. Undervisningstime. Starter 14. desember 2023 klokken 13:05 og slutter 13:50" subjectcode="YFF4106" tttype="LESSON" starttimeanddateunix="1702555500" readonlyitems="[object Object],[object Object],[object Object],[object Object],[object Object]" actionitems="[object Object]" teachername="Teacher" entityid="135321756" block="" teachinggroupid="12459773" data-v-45669d56="" style="border-left: 6px solid rgb(83, 237, 155); height: 90px; width: 100%;"><div data-v-33d0fd5d="" aria-hidden="true" class="Timetable-TimetableItem-wrapper"><div data-v-33d0fd5d="" class="Timetable-TimetableItem-header"><small data-v-33d0fd5d="" class="Timetable-TimetableItem-hours"><i data-v-33d0fd5d="" class="far fa-clock"></i> 13:05 - 13:50 </small><small data-v-33d0fd5d="" class="Timetable-TimetableItem-location"><i data-v-33d0fd5d="" class="far fa-map-marker"></i> E109 </small><!----></div><p data-v-33d0fd5d="" class="Timetable-TimetableItem-subject-name"> Yrkesfaglig fordypning vg1 </p><!----><small data-v-33d0fd5d="" class="Timetable-TimetableItem-type"> Undervisningstime </small><!----></div></div></div><!----></div><div data-v-45669d56="" data-v-36c1dfe8="" class="popup-container" style="top: 710px; left: 0%;"><div data-v-36c1dfe8="" data-v-45669d56=""><h4 data-v-36c1dfe8="" data-v-45669d56="" class="sr-only"> Yrkesfaglig fordypning vg1 på rom E109. Undervisningstime. Starter 14. desember 2023 klokken 13:55 og slutter 14:40 </h4><div data-v-33d0fd5d="" data-v-36c1dfe8="" tabindex="0" aria-haspopup="dialog" test-id="vs-Timetable-item-4-6-135321757" class="Timetable-TimetableItem Timetable-TimetableItem-m" role="button" aria-label="Se detaljer om Yrkesfaglig fordypning vg1 på rom E109. Undervisningstime. Starter 14. desember 2023 klokken 13:55 og slutter 14:40" subjectcode="YFF4106" tttype="LESSON" starttimeanddateunix="1702558500" readonlyitems="[object Object],[object Object],[object Object],[object Object],[object Object]" actionitems="[object Object]" teachername="Teacher" entityid="135321757" block="" teachinggroupid="12459773" data-v-45669d56="" style="border-left: 6px solid rgb(83, 237, 155); height: 90px; width: 100%;"><div data-v-33d0fd5d="" aria-hidden="true" class="Timetable-TimetableItem-wrapper"><div data-v-33d0fd5d="" class="Timetable-TimetableItem-header"><small data-v-33d0fd5d="" class="Timetable-TimetableItem-hours"><i data-v-33d0fd5d="" class="far fa-clock"></i> 13:55 - 14:40 </small><small data-v-33d0fd5d="" class="Timetable-TimetableItem-location"><i data-v-33d0fd5d="" class="far fa-map-marker"></i> E109 </small><!----></div><p data-v-33d0fd5d="" class="Timetable-TimetableItem-subject-name"> Yrkesfaglig fordypning vg1 </p><!----><small data-v-33d0fd5d="" class="Timetable-TimetableItem-type"> Undervisningstime </small><!----></div></div></div><!----></div></div><div data-v-3b0485ec="" data-v-36c1dfe8="" class="Timetable-TimetableNowLine" style="top: 546.633px;"></div></div>

Chat application setting up

i am building a chat application for a website i am working on. their is a server that is already running and a database, there is also a restful API. i am supposed to set up the chat app to its functionality, i need help because i have not yet done anything this technical, i have been using rendered API like Twilio. i would really appreciate all the suggestions.

i have been trying to get data and have been successful. the thing is, i am not able to view the messages posted via thunder client or postman

Integrating Spotify OAuth on Android: in-app authentication for web browsers

I am working on integrating Spotify’s OAuth authentication into a web application for mobile users. The goal is to enable users to authenticate via the Spotify mobile app on Android devices, ensuring compatibility with popular browsers like Chrome Mobile and in-app browsers such as those in Instagram, Facebook, and TikTok.

OAuth 2.0 authorization framework

“MY APP” here is the client that requests access to the protected resources (i.e. my web app). I am following the Spotify Authorization Code Flow, and my current implementation is as follows:

const urlQueryParams = '?scope=user-read-email&response_type=code&redirect_uri=[ENCODED_REDIRECT_URI]&state=[STATE]&client_id=[CLIENT_ID]';
onclick: function () {
    let url = 'https://accounts.spotify.com/authorize';
    url += urlQueryParams;
    window.location.href = url;
}

This code works, but it always prompts users to authenticate through the Spotify Auth webpage, even if they have the Spotify app installed and are logged in. This process is inconvenient for mobile users. I saw in similar questions that a redirect from web to app should happen autonomously, provided the user has the app installed, but according to my own testing it doesn’t happen for /authorize page.

For the sake of clarity, let’s assume that the Spotify app for Android is always installed and End User is authenticated inside the app.

I’ve tried the following approach:

const urlQueryParams = '...';
onclick: function () {
    let url = 'https://accounts.spotify.com/inapp-authorize';
    url += urlQueryParams;
    window.location.href = url;
}

This method sometimes behaves like a deep link, opening the Spotify app for Android and redirecting users back to My App if they have previously granted access. It works in Chrome Mobile but not in Instagram’s webview. It asks user to login via webpage inside Instagram. Also it stucks on infinite “Loading…” inside Spotify app if users have NOT previously granted access to My App.

I also experimented with an intent:// schema:

const urlQueryParams = '...';
onclick: function () {
    let url = 'intent://accounts.spotify.com/inapp-authorize';
    url += urlQueryParams + '#Intent;package=com.spotify.music;scheme=spotify;end';
    window.location.href = url;
}

This approach always prompts users to continue in the Spotify app, but it leads them to the Home page instead of the Login page.

I am aware of the spotify:// schema for deep linking to albums, artists, and tracks in the Spotify app. However, I’m unsure how to use it to deep link directly to the Auth page in the Spotify app for Android.

I am seeking a reliable solution for authenticating users via the Spotify app across different mobile browsers and in-app webviews. Insights from Spotify engineers or anyone with relevant experience would be highly appreciated. Additional details, such as a jsFiddle or demo screenshots, can be provided upon request.

How to make the javascript only work on a mobile device with a max width of 600px

I have a javascript code that collapses all text with class “.divi-toggle-text”. This code creates a read more button styled with css code running on a Divi website. It works great but I want it to only run on mobile devices with a max width of 600px.

<script>
    jQuery(document).ready(function() {
        var divi_expand_text = "Show more...";
        var divi_collapse_text = "Show less...";
        var divi_expand_icon = "3";
        var divi_collapse_icon = "2";
        jQuery(".divi-toggle-text").each(function() {
            jQuery(this).append('<div class= "divi-text-expand-button"><span class= "divi-text-collapse-button">' + divi_expand_text + ' <span class= "divi-text-toggle-icon">' + divi_expand_icon + '</span></div>');
            jQuery(this).find(".divi-text-collapse-button").on("click", function() {
                jQuery(this).parent().siblings(".et_pb_text_inner").toggleClass("divi-text-toggle-expanded");
                if (jQuery(this).parent().siblings(".et_pb_text_inner").hasClass("divi-text-toggle-expanded")) {
                    jQuery(this).html(divi_collapse_text + "<span class= 'divi-text-toggle-icon'>" + divi_collapse_icon + "</span>");
                } else {
                    jQuery(this).html(divi_expand_text + "<span class= 'divi-text-toggle-icon'>" + divi_expand_icon + "</span>");
                }
            })
        })
    }) 
</script>
.divi-toggle-text .et_pb_text_inner {
  max-height: 200px; /*=define the height of your text module=*/
  transition: max-height 0.3s ease-out;
  overflow: hidden;
}
.divi-toggle-text .et_pb_text_inner:after {
  content: "";
  display: inline-block;
  position: absolute;
  pointer-events: none;
  height: 100px;
  width: 100%;
  left: 0;
  right: 0;
  bottom: 0;
  background-image: linear-gradient(0deg, #fff 10%, transparent);
}
.divi-toggle-text .divi-text-expand-button {
  padding: 0.5em;
  text-align: center;
  color: #000 !important;
  font-weight: bold;
}
.divi-toggle-text .divi-text-expand-button span {
  cursor: pointer;
}
.divi-toggle-text .divi-text-expand-button .divi-text-toggle-icon {
  font-family: ETMODULES, "sans-serif";
}
.divi-toggle-text .divi-text-toggle-expanded {
  max-height: 2000px;
  transition: max-height 0.3s ease-in;
}
.divi-toggle-text .divi-text-toggle-expanded.et_pb_text_inner:after {
  background: none;
}

I triead adding the following code, but it didn’t work:

if (window.innerWidth <= 600)

Cypress API: How to find specific property in objects without name in array

I have API which response looks like this (notice that it is objects without name in array):

{
 offers: [
  {
   sticker: null,
  },
  {
   sticker: null,
   score: "67",
  },
  {
   sticker: null,
  },
  {
   sticker: null,
  },
  {
   sticker: null,
   score: "70",
  }
 ]
}

How to check if property score exist in this API response? I tried using

expect(resp.body.offers.some((offer: any) => offer.score !== undefined && typeof offer.score === "string")).to.be.true;

and many other ideas I had but nothing works. It will allways throw error expected false to be true.

What is the best practice for translating data using a predefined json object

I have a nodejs backend and I get some data from a public API and that data can be in a specific language.

Now I want to translate that data to the language that the user has selected in the front-end.

So I am confused on what is the better approach between storing a big object or json object files on the server side and then accessing them and replacing the keywords inside the base data or should I store these translation objects in a DB and access them for the required fields once I retrieve my base data.

My current approach is storing the json files on the server side but I read that I will run out of memory on the server side if I do that.

In single click popup not opening?

enter image description here

Component file ->

<tr v-for="(row, index) in table" :key="index">
  <td class="dot_td">
    <img :src="row.cell1.imgSrc" />
  </td>
  <th v-html="row.cell2.content">
  </th>
  <td v-for="inputCell in row.inputCells" :key="inputCell.input" :class="inputCell.rectification === 1 ? 'border_td' : ''">
    <input v-bind="inputCell.input" :value="inputCell.inputData">
    <a style="cursor: pointer;" class="request_icon" @click="openPopup($event, inputCell)">
      <svg width="14" height="13" viewBox="0 0 14 13" fill="none" xmlns="http://www.w3.org/2000/svg">
        <path d="M13.5 6.5C13.5 9.77946 10.6254 12.5 7 12.5C3.37461 12.5 0.5 9.77946 0.5 6.5C0.5 3.22054 3.37461 0.5 7 0.5C10.6254 0.5 13.5 3.22054 13.5 6.5Z"
        stroke="#CDCDCD" />
        <path d="M6.46866 10V4.54545H7.53045V10H6.46866ZM7.00488 3.70384C6.82022 3.70384 6.66161 3.64228 6.52903 3.51918C6.39882 3.3937 6.33372 3.24455 6.33372 3.07173C6.33372 2.89654 6.39882 2.7474 6.52903 2.62429C6.66161 2.49882 6.82022 2.43608 7.00488 2.43608C7.18954 2.43608 7.34698 2.49882 7.47718 2.62429C7.60976 2.7474 7.67605 2.89654 7.67605 3.07173C7.67605 3.24455 7.60976 3.3937 7.47718 3.51918C7.34698 3.64228 7.18954 3.70384 7.00488 3.70384Z"
        fill="#CDCDCD" />
      </svg>
    </a>
  </td>
  <td>
    {{ row.totalCell.text }}
  </td>
</tr>

Script ->

<script setup>
const openPopup = (event, inputCell) => {
    const iconbtn = event.currentTarget;
    const popup = document.getElementById('request_popup');
    
    userComment.value = inputCell.commentData;
    UsercommentDate.value = inputCell.UsercommentDate;
    currentInputCell.value = inputCell;
    managerComment.value = inputCell.Managercomment;
    isPopupVisible.value = !isPopupVisible.value;
    const rect = iconbtn.getBoundingClientRect();

    if (isPopupVisible.value) {
        iconbtn.classList.add('requested');
        popupStyle.top = rect.bottom + window.scrollY + 'px';
        popupStyle.left = rect.left + window.scrollX + 'px';

        // Add an event listener to close the popup on outside click
        const closePopupOnOutsideClick = (event) => {
            const isClickInsidePopup = iconbtn.contains(event.target) || popup.contains(event.target);
            if (!isClickInsidePopup) {
                closePopup(iconbtn);
                document.removeEventListener('click', closePopupOnOutsideClick);
            }
        };

        document.addEventListener('click', closePopupOnOutsideClick);
        
    }else{
        isPopupVisible.value = false;
        iconbtn.classList.remove('requested');
    }
    
};

const closePopup = (iconbtn) => {
    isPopupVisible.value = false;
    if(iconbtn){
    iconbtn.classList.remove('requested');
    }
};
<script>

When clicking on the first input cell, the popup opens and closes correctly. However, closing the initial input and opening another results in the orange mark icon appearing, but the popup doesn’t open until the second click. This issue persists across all input cells. where the popup opens only after the single click, Any assistance on resolving this, would be appreciated.

when open popup close using outside click is working fine

ERROR: export ‘Auth’ (imported as ‘Auth’) was not found in ‘aws-amplify’ (possible exports: Amplify)

First of all, I am new to JS and AWS cloud, so this maybe something simple although I couldnt find any solution online. Could someone please help me fix the below error?
I tried to replace Auth with Amplify but keep getting the same errors.

*ERROR in ./src/pages/HomeFeedPage.js 44:4-33
export ‘Auth’ (imported as ‘Auth’) was not found in ‘aws-amplify’ (possible exports: Amplify)

ERROR in ./src/pages/HomeFeedPage.js 51:13-42
export ‘Auth’ (imported as ‘Auth’) was not found in ‘aws-amplify’ (possible exports: Amplify)*

import './HomeFeedPage.css';
import React from "react";

import { Auth } from 'aws-amplify';

import DesktopNavigation  from '../components/DesktopNavigation';
import DesktopSidebar     from '../components/DesktopSidebar';
import ActivityFeed from '../components/ActivityFeed';
import ActivityForm from '../components/ActivityForm';
import ReplyForm from '../components/ReplyForm';

// [TODO] Authenication
// import Cookies from 'js-cookie'

export default function HomeFeedPage() {
  const [activities, setActivities] = React.useState([]);
  const [popped, setPopped] = React.useState(false);
  const [poppedReply, setPoppedReply] = React.useState(false);
  const [replyActivity, setReplyActivity] = React.useState({});
  const [user, setUser] = React.useState(null);
  const dataFetchedRef = React.useRef(false);
  const loadData = async () => {
    try {
      const backend_url = `${process.env.REACT_APP_BACKEND_URL}/api/activities/home`
      const res = await fetch(backend_url, {
        method: "GET"
      });
      let resJson = await res.json();
      if (res.status === 200) {
        setActivities(resJson)
      } else {
        console.log(res)
      }
    } catch (err) {
      console.log(err);
    }
  };

// check if we are authenicated
  const checkAuth = async () => {
    Auth.currentAuthenticatedUser({
      // Optional, By default is false. 
      // If set to true, this call will send a 
      // request to Cognito to get the latest user data
      bypassCache: false 
    })
    .then((user) => {
      console.log('user',user);
      return Auth.currentAuthenticatedUser()
    }).then((cognito_user) => {
        setUser({
          display_name: cognito_user.attributes.name,
          handle: cognito_user.attributes.preferred_username
        })
    })
    .catch((err) => console.log(err));
  };

  React.useEffect(()=>{
    //prevents double call
    if (dataFetchedRef.current) return;
    dataFetchedRef.current = true;

    loadData();
    checkAuth();
  }, [])

  return (
    <article>
      <DesktopNavigation user={user} active={'home'} setPopped={setPopped} />
      <div className='content'>
        <ActivityForm  
          popped={popped}
          setPopped={setPopped} 
          setActivities={setActivities} 
        />
        <ReplyForm 
          activity={replyActivity} 
          popped={poppedReply} 
          setPopped={setPoppedReply} 
          setActivities={setActivities} 
          activities={activities} 
        />
        <ActivityFeed 
          title="Home" 
          setReplyActivity={setReplyActivity} 
          setPopped={setPoppedReply} 
          activities={activities} 
        />
      </div>
      <DesktopSidebar user={user} />
    </article>
  );
}

Positioning modal to left

I want to open datepicker modal on left of div element. As opening modal on right of element make it disappeared.

enter image description here

In this screen, I am clicking on datepicker field to open modal
enter image description here

It’s hiding the datepicker modal
enter image description here

This is how I want to achieved

As we can see in above images, modal is hiding on right side…..I want to align like shown in last image.

Modal-content

When modal is closed, this is how element is styled. Display none, left: 0px ,right: auto

top: 35px;
left: 0px;
right: auto;

When modal is opened, Display flex, left: 0px ,right: auto

top: 35px;
left: 0px;
right: auto;
display: flex;

I tried changing styles by placing left: auto ,right: 0px in css files to align modal as shown in last image. But it toggle to display block from display none, instead of display flex. So modal gets shrink

How can I change css in proper way that I can retain display flex on opening of modal and align modal like last image?

How can I getch information from the API to the input

On the main page of my project, clicking the edit icon in the customers’ data grid opens the editing screen based on the customer’s ID. I want the existing information of the customer to be displayed on this editing screen. However, I am unable to fetch the data into the input fields.

customers page

when I click the edit icon :

Customer edit page

Edit page codes :

const Edit = () => {
  const { id } = useParams();
  const [file, setFile] = useState("");
  const [successMessage, setSuccessMessage] = useState(null);
  const [errorMessage, setErrorMessage] = useState(null);
  const [snackbarOpen, setSnackbarOpen] = useState(false);
  const [customerData, setCustomerData] = useState(null);

  useEffect(() => {
    // Müşteri bilgilerini getirmek için API çağrısı
    axios
      .get(`my-api-link/api/customers/${id}`)
      .then((response) => {
        setCustomerData(response.data.customer);
      })
      .catch((error) => {
        console.error("Error fetching customer data:", error);
      });
  }, [id]);

  const formik = useFormik({
    initialValues: {
      file: "",
      no: customerData?.no || "",
      fullName: customerData?.fullName || "",
      TC: customerData?.TC || "",
      birthDate: customerData?.birthDate || "",
      phoneNumber: customerData?.phoneNumber || "",
      email: customerData?.email || "",
      address: customerData?.address || "",
      referance: customerData?.referance || "",
      resume: customerData?.resume || "",
      gender:
        customerData?.gender === 0
          ? "erkek"
          : customerData?.gender === 1
          ? "kadın"
          : "diğer" || "",
      note: customerData?.note || "",
    },
    validationSchema: Yup.object({
      no: Yup.number().required("Hasta No boş bırakılamaz"),
      fullName: Yup.string().required("Ad Soyad boş bırakılamaz"),
      TC: Yup.string().required("TC Kimlik No boş bırakılamaz"),
      birthDate: Yup.date().required("Doğum Tarihi boş bırakılamaz"),
      phoneNumber: Yup.string().required("Telefon numarası boş bırakılamaz"),
      email: Yup.string()
        .email("Geçerli bir e-posta adresi giriniz")
        .required("E-mail boş bırakılamaz"),
      gender: Yup.string().required("Cinsiyet seçiniz"),
    }),
    onSubmit: async (values, { setSubmitting }) => {
      // Düzenleme işlemi için API çağrısı
      const formData = new FormData();
      formData.append("profilePicture", file);
      formData.append("fullName", values.fullName);
      formData.append("TC", values.TC);
      formData.append("birthDate", values.birthDate);
      formData.append("phoneNumber", values.phoneNumber);
      formData.append("email", values.email);
      formData.append("address", values.address);
      formData.append("no", values.no);
      formData.append("note", values.note);
      formData.append("referance", values.referance);
      formData.append("resume", values.resume);
      formData.append(
        "gender",
        values.gender === "erkek"
          ? "0"
          : values.gender === "kadın"
          ? "1"
          : values.gender === "diğer"
          ? "2"
          : ""
      );

      try {
        const response = await axios.put(
          `my-api-link/api/customers/${id}`,
          formData,
          {
            headers: {
              "Content-Type": "multipart/form-data",
            },
          }
        );

        setSuccessMessage("Müşteri güncellendi!");
        setSubmitting(false);
      } catch (error) {
        setErrorMessage("Müşteri güncellenirken bir hata oluştu.");
        setTimeout(() => {
          window.location.reload();
        }, 5000);
      }
    },
  });

  const handleFileChange = (e) => {
    setFile(e.target.files[0]);
  };

    setSuccessMessage(null);
    setErrorMessage(null);
  };

  return (
    <div className="new">
      <div className="newContainer">
        <div className="top">
          <Link to="/" className="link">
            Geri Git
          </Link>
          <h1>Müşteri Düzenle</h1>
        </div>
        <div className="bottom">
          <div className="left">
            <img
              src={
                file
                  ? URL.createObjectURL(file)
                  : customerData?.profilePicture ||
                    "https://icon-library.com/images/no-image-icon/no-image-icon-0.jpg"
              }
              alt=""
              onClick={() => document.getElementById("file").click()}
            />
          </div>
          <div className="right">
            <form onSubmit={formik.handleSubmit}>
              <div className="formInput">
                <label htmlFor="file">
                  Image: <DriveFolderUploadOutlinedIcon className="icon" />
                </label>
                <input
                  type="file"
                  id="file"
                  accept="image/*"
                  onChange={(e) => {
                    handleFileChange(e);
                    formik.setFieldValue("file", e.target.files[0]);
                  }}
                  style={{ display: "none" }}
                />
              </div>

              <div className="formInput">
                <label htmlFor="no">Hasta No</label>
                <input type="number" id="no" {...formik.getFieldProps("no")} />
                {formik.touched.no && formik.errors.no ? (
                  <div className="error" style={{ color: "tomato" }}>
                    {formik.errors.no}
                  </div>
                ) : null}
              </div>

              <div className="formInput">
                <label htmlFor="fullName">Ad Soyad</label>
                <input
                  type="text"
                  id="fullName"
                  {...formik.getFieldProps("fullName")}
                />
                {formik.touched.fullName && formik.errors.fullName ? (
                  <div className="error" style={{ color: "tomato" }}>
                    {formik.errors.fullName}
                  </div>
                ) : null}
              </div>

              <div className="formInput">
                <label htmlFor="TC">TC Kimlik No</label>
                <InputMask
                  mask="99999999999"
                  placeholder="XXXXXXXXXXX"
                  id="TC"
                  {...formik.getFieldProps("TC")}
                />
                {formik.touched.TC && formik.errors.TC ? (
                  <div className="error" style={{ color: "tomato" }}>
                    {formik.errors.TC}
                  </div>
                ) : null}
              </div>

              <div className="formInput">
                <label htmlFor="birthDate">Doğum Tarihi</label>
                <input
                  type="date"
                  id="birthDate"
                  {...formik.getFieldProps("birthDate")}
                />
                {formik.touched.birthDate && formik.errors.birthDate ? (
                  <div className="error" style={{ color: "tomato" }}>
                    {formik.errors.birthDate}
                  </div>
                ) : null}
              </div>

              <div className="formInput">
                <label htmlFor="phoneNumber">Telefon Numarası</label>
                <InputMask
                  mask="(999) 999 99 99"
                  placeholder="(5XX) XXX XX XX"
                  id="phoneNumber"
                  {...formik.getFieldProps("phoneNumber")}
                />
                {formik.touched.phoneNumber && formik.errors.phoneNumber ? (
                  <div className="error" style={{ color: "tomato" }}>
                    {formik.errors.phoneNumber}
                  </div>
                ) : null}
              </div>

              <div className="formInput">
                <label htmlFor="email">E-mail</label>
                <InputMask
                  mask=""
                  placeholder="[email protected]"
                  type="email"
                  id="email"
                  {...formik.getFieldProps("email")}
                />
                {formik.touched.email && formik.errors.email ? (
                  <div className="error" style={{ color: "tomato" }}>
                    {formik.errors.email}
                  </div>
                ) : null}
              </div>

              <div className="formInput">
                <label htmlFor="address">Adres</label>
                <textarea
                  style={{ width: "100%", height: "70%" }}
                  type="text"
                  id="address"
                  {...formik.getFieldProps("address")}
                />
              </div>

              <div className="formInput">
                <label htmlFor="referance">Referans</label>
                <input
                  type="text"
                  id="referance"
                  {...formik.getFieldProps("referance")}
                />
              </div>

              <div className="formInput">
                <label htmlFor="resume">Özgeçmiş</label>
                <textarea
                  style={{ width: "100%", height: "70%" }}
                  type="text"
                  id="resume"
                  {...formik.getFieldProps("resume")}
                />
              </div>

              <div className="formInput">
                <label htmlFor="gender">Cinsiyet</label>
                <select
                  id="gender"
                  {...formik.getFieldProps("gender")}
                  style={{ width: "50%", height: "60%", cursor: "pointer" }}
                >
                  <option value="" disabled hidden>
                    Cinsiyet Seçiniz
                  </option>
                  <option value="erkek">Erkek</option>
                  <option value="kadın">Kadın</option>
                  <option value="diğer">Diğer</option>
                </select>
                {formik.touched.gender && formik.errors.gender ? (
                  <div className="error" style={{ color: "tomato" }}>
                    {formik.errors.gender}
                  </div>
                ) : null}
              </div>

              <div className="formInput">
                <label htmlFor="note">Not</label>
                <textarea
                  style={{ width: "100%", height: "70%" }}
                  type="text"
                  id="note"
                  {...formik.getFieldProps("note")}
                />
              </div>

              <Button variant="contained" type="submit">
                Güncelle
              </Button>
            </form>
          </div>
        </div>
      </div>
    </div>
  );
};

export default Edit;

Line Control wont move, Before-After image slider comparison

I’m new with coding but i want to add some change in my website

I want to compare like render passes like breakdown of several same image but people will be able to slide and drag the vertical line to then get them to see the realtime different of the image ( like before and after slider ) but will more than one slider comparison ( in this case there is 4 )

I have tried but the vertical line wont even move or draggable, is there anything i lack knowledge of or need to know ? if someone got experience in this or could solve this would be really helpful, thanks.

 <!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <style>
    html, body {
      margin: 0;
      padding: 0;
      height: 100%;
    }

    .main-container {
      position: relative;
      width: 100%;
      height: 100vh;
      border: 2px solid #333;
      background-image: url('https://via.placeholder.com/1920x1080');
      background-size: cover;
      background-position: center;
    }

    .image-layer {
      position: absolute;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
      object-fit: cover;
    }

    .image-layer:nth-child(1) {
      clip-path: inset(0 80% 0 0);
    }

    .image-layer:nth-child(2) {
      clip-path: inset(0 60% 0 20%);
    }

    .image-layer:nth-child(3) {
      clip-path: inset(0 40% 0 40%);
    }

    .image-layer:nth-child(4) {
      clip-path: inset(0 20% 0 60%);
    }

    .image-layer:nth-child(5) {
      clip-path: inset(0 80% 0 0%);
    }

    .vertical-line {
      position: absolute;
      width: 2px;
      height: 100%;
      background-color: red; /* Change color as needed */
      cursor: ew-resize;
    }
  </style>
  <title>Main Container of Image</title>
</head>
<body>
  <div class="main-container">
    <img class="image-layer" src="https://via.placeholder.com/1920x1080/FF0000" alt="Image Layer 1">
    <img class="image-layer" src="https://via.placeholder.com/1920x1080/00FF00" alt="Image Layer 2">
    <img class="image-layer" src="https://via.placeholder.com/1920x1080/0000FF" alt="Image Layer 3">
    <img class="image-layer" src="https://via.placeholder.com/1920x1080/FFD700" alt="Image Layer 4">
    <img class="image-layer" src="https://via.placeholder.com/1920x1080/9400D3" alt="Image Layer 5">
    
    <!-- Add vertical lines as controllers -->
    <div class="vertical-line" style="left: 20%;" data-target="1"></div>
    <div class="vertical-line" style="left: 40%;" data-target="2"></div>
    <div class="vertical-line" style="left: 60%;" data-target="3"></div>
    <div class="vertical-line" style="left: 80%;" data-target="4"></div>
  </div>

  <!-- ... Your existing HTML code ... -->

  <!-- ... Your existing HTML code ... -->

  <script>
    document.addEventListener('DOMContentLoaded', function () {
      // Get references to the vertical lines
      const verticalLines = document.querySelectorAll('.vertical-line');

      // Add event listeners for each vertical line
      verticalLines.forEach((line, index) => {
        let isDragging = false;
        let initialX = 0;

        // Set initial clip path values based on the left and right properties of adjacent images
        const updateClipPath = () => {
          const leftIndex = index;
          const rightIndex = index + 1;

          const leftImage = document.querySelector(`.image-layer:nth-child(${leftIndex + 1})`);
          const rightImage = document.querySelector(`.image-layer:nth-child(${rightIndex + 1})`);

          const leftClipPathValue = line.style.left;
          const rightClipPathValue = 100 - parseFloat(leftClipPathValue);

          leftImage.style.clipPath = `inset(0 ${rightClipPathValue}% 0 0)`;
          rightImage.style.clipPath = `inset(0 0 0 ${leftClipPathValue}%)`;
        };

        // Mouse down event to start dragging
        line.addEventListener('mousedown', (e) => {
          isDragging = true;
          initialX = e.clientX;
        });

        // Mouse move event to update position while dragging
        document.addEventListener('mousemove', (e) => {
          if (isDragging) {
            // Calculate the new position
            const deltaX = e.clientX - initialX;
            const newPosition = parseFloat(line.style.left) + deltaX / window.innerWidth * 100;

            // Limit the position within 0% to 100%
            const clampedPosition = Math.min(100, Math.max(0, newPosition));

            // Update the position of the line
            line.style.left = `${clampedPosition}%`;

            // Update clip path values based on the new position
            updateClipPath();

            // Update the initial X for the next movement
            initialX = e.clientX;
          }
        });

        // Mouse up event to stop dragging
        document.addEventListener('mouseup', () => {
          isDragging = false;
        });
      });
    });
  </script>
</body>
</html>



I expect the code where i could drag each line slider freely left and right

i’m trying to breakdown how it could work and the note each of the concept like this :

start fresh new code from scratch (trying to use z-index and clip-path square)

Main Container of image :

  1. I have this main container filled with image, no padding, no gap, just border
  2. this image on main container as background called beauty-image
  3. beauty image placed as the background of the main container
  4. use placeholder image with 16:9 ratio

Inside Main Container of image :

  1. inside the main container there are images that stacked like layers
  2. use z-index as the layer ( images 1 will have lower z-index than image 2 )
  3. use placeholder image with 16:9 ratio and different color for each image

Make Image Slider Control :

  1. inside the main container there are vertical line that positioned evenly across the width of the main container percentage
  2. the number of vertical line will be the number of images layer – 1
  3. this vertical line could be dragged to change their position
  4. this vertical line placed above all the image ( more z-index than images)
  5. this vertical line position will control clip-path square left and right (get the position value of the vertical line to change the attributes of clip path of each of the image)

**Rule of the Slider Control :
**

  1. each vertical line have hirerarcy and connection based on each images
    example :

image 1 clip path square left percentage value will be the same as the position of the vertical line 1 and the clip path square right percentage value will be the same as the position of the vertical line 1+1 (vertical line 2)
image 2 clip path square left percentage value will be the same as the position of the vertical line 2 and the clip path square right percentage value will be the same as the position of the vertical line 2+1 (vertical line 3)

  1. each time vertical line dragged and meet (have the same position value) as the other vertical line it will push the other vertical line to the direction of the hirerarchy
    example :

when vertical line 1 dragged to the right untill the position same like vertical line 2 vertical line 2 position will also started to move with different offset of 1%
case :
vertical line 2 positioned at 75%, vertical line 1 dragged from 32% to 80% (line move to the right) , when the vertical line 1 at the same position as vertical line 2 (at position 75%) this will make vertical line 2 to move based on vertical line 1 position when their position the same +1% so with that when vertical line 1 at 78% position vertical line 2 will be at 79% and when vertical line 1 reach 80% vertical line 2 will bea t 81%

this will applies when you move vertical line x to increased position ( move to the right ) this happen to hall of the hierarchy so when vertical line 2 meet vertical line 3 this will also applies the same rule

the opposite

when you move the vertical line to decreased position ( move to the left ), vertical line 1 positioned at 32%, vertical line 2 dragged from 75% to 20% (line move to the left) , when the vertical line 2 at the same position as vertical line 1 (at position 32%) this will make vertical line 1 to move based on vertical line 2 position when their position the same -1% so with that when vertical line 2 at 35% position vertical line 2 will be at 34% and when vertical line 1 reach 20% vertical line 2 will bea t 19%

this will applies when you move vertical line x to decreased position ( move to the right ) this happen to hall of the hierarchy so when vertical line 3 meet vertical line 2 this will also applies the same rule

try to use clip-path inset to get overlapping value then add controller on the position of the overlap

add 5 image on over the beauty image and add clip-path : inset style on them with this setting

image1  = clip-path: inset(0 80% 0 0)
image2 = clip-path: inset(0 60% 0 20%)
image3 = clip-path: inset(0 40% 0 40%)
image4 = clip-path: inset(0 20% 0 60%)
image5 = clip-path: inset(0 80% 0 0%)