pivottable: drop down lists open in wrong position when we press the field button

pivot table: drop down lists open in wrong position when we press the field button but the position should be same place when we press the field button

msg-sum-pvt-report.component.ts

import { Component} from '@angular/core';
import { VgtBaseReportComponent } from '../../../vgt-base-report/vgt-base-report.component';
import { MessagesService, UrlObj } from 'src/app/_service/messages.service';
import { MessageSummaryResp } from 'src/app/material/SummaryReports';
import { TokenStorageService } from 'src/app/_service/token-storage.service';
import { MatTableDataSource } from '@angular/material/table';



@Component({
  selector: 'app-msg-summ-pvt-report',
  templateUrl: './msg-summ-pvt-report.component.html',
  styleUrl: './msg-summ-pvt-report.component.scss'
})
export class MsgSummPvtReportComponent extends VgtBaseReportComponent  {
  dateType: string = "";
  constructor(messagesService: MessagesService,
    public override tokenStorage: TokenStorageService) {
    super(messagesService, tokenStorage)
    console.log("MsgSummPvtReport:isAuthenticated: "+this.isAuthenticated);
    this.dataSource = new MatTableDataSource();

    
  }

  dataSource: MatTableDataSource<MessageSummaryResp>;
  summaryreport = {} as MessageSummaryResp;

  override assigneData(data1: any) {
    this.summaryreport = data1;
    this.iCommonData = data1;
    this.iCommonData.DataArr = this.summaryreport.message_summary;    

  } 
  dateSubmit() {
    this.dataSource = new MatTableDataSource<MessageSummaryResp>;
    console.log("datetype:" + this.dateType)
   // this.yearmonth
    //var reqDate = "";
    if (this.dateType == "year") {
      this.reqDate = (this.startDt1 % 100)+"";
      console.log("reqDate1 " + this.reqDate)
      this.readMessages();
    } else if (this.dateType == "yearmonth") {
      this.reqDate = this.YYMM+"" ;   //2023-09 ; 2024-01
      console.log("reqDate2 " + this.reqDate)
      this.reqDate=this.reqDate.replaceAll("-","")
      console.log("reqDate3 " + this.reqDate)
      this.reqDate=this.reqDate.substring(2,6)
      console.log("req: " + this.reqDate + " YEARMONTH: " + this.YYMM);
      this.readMessages();
    } else if (this.dateType == "yearmonthdate") {
      console.log("ymd: "+this.YYMMDD)
      var date = new Date(this.YYMMDD),
        mnth = ("0" + (date.getMonth() + 1)).slice(-2),
        day = ("0" + date.getDate()).slice(-2);
      var fullDate = [date.getFullYear().toString().substr(-2), mnth, day].join("")
      console.log("yymmdd: " + fullDate);
      this.reqDate = fullDate
      console.log("FullDate: " + this.reqDate + " reqDate: " + fullDate)
      this.readMessages();
    } else {
      console.log("reqDate4 error ")
      return
    }
  }
 
  override setUrlObj() {
    this.selectedConfig = {
      rows: ['agent_id'],
      cols: ['client_no'],
      vals: ['count'],
      aggregatorName: 'Integer Sum',
      rendererName: 'Table',
    };
    this.urlObj = UrlObj.MsgSumPivoteTableComponent;
  }
  
} 
msg-sum-pvt-report.component.html
=================================
<h1 class="text-primary" align="center">Campaign Summary Report</h1>
<div class="alert alert-danger" role="alert" *ngIf="!isAuthenticated">
    <h3> You are not Authorized </h3>
</div>
<div class="container" *ngIf="isAuthenticated">
    <form cForm class="row g-3">
        <!-- Year Radio Button and Dropdown -->
        <div class="col-md-4">
            <div class="row">
                <div class="col-md-12">
                    <c-form-check>
                        <input cFormCheckInput id="yy" [(ngModel)]="dateType" value="year" type="radio"
                            name="flexRadioDefault" />
                        <label cFormCheckLabel>Year</label>
                    </c-form-check>
                    <div>
                        <input type="number" min="2023" max="2050" [(ngModel)]="startDt1" value="startDt1"
                            [ngModelOptions]="{standalone: true}">
                    </div>
                </div>
            </div>
        </div>

        <!-- Year&Month Radio Button and Input -->
        <div class="col-md-4">
            <div class="row">
                <div class="col-md-12">
                    <c-form-check>
                        <input cFormCheckInput type="radio" name="flexRadioDefault" id="yymm" [(ngModel)]="dateType"
                            value="yearmonth" />
                        <label cFormCheckLabel>Year Month</label>
                    </c-form-check>
                    <!--label cLabel for="inputdate_time">date_time</label-->
                    <div>
                        <input type="month" min="2023-01" max="2050-12" [(ngModel)]="YYMM"
                            [ngModelOptions]="{standalone: true}" />
                    </div>
                </div>
            </div>
        </div>

        <!-- Year&Month&Date Radio Button and Input -->
        <div class="col-md-4">
            <div class="row">
                <div class="col-md-12">
                    <c-form-check>
                        <input cFormCheckInput type="radio" name="flexRadioDefault" id="ddmm" value="yearmonthdate"
                            [(ngModel)]="dateType" />
                        <label cFormCheckLabel>Year Month Date</label>
                    </c-form-check>
                    <!--label cLabel for="inputdate_time">date_time</label-->
                    <div>
                        <input type="date" [(ngModel)]="YYMMDD" [ngModelOptions]="{standalone: true}" />
                    </div>
                </div>
            </div>
        </div>

        <!-- Submit Button -->
        <div class="col-md-12">
            <button mat-icon-button class="btn btn-primary" color="primary" type="submit"
                (click)="dateSubmit()">Submit</button>
        </div>
    </form>
</div>
<br>
<button type="button" class="btn btn-primary" (click)="reload()">Reload</button>
<div class="spinner-border text-primary" role="status" id="loading">
    <span class="visually-hidden">Loading...</span>
</div>
<br><br><br><br>
<app-pivot-table [config]="selectedConfig" [show]="mode" (newConfig)="reportConfig($event)"
    [data]="iCommonData.DataArr">pivottable4</app-pivot-table>

enter image description here

from above file please see the difference of positions of two images originally when we press the field button popup should be displayed at same position but it is not working properly please fix the pivottable dropdown list position

how to concatenate multiple .webm files into one file

I am fetching audio chunks, with .webm extension, from S3 bucket and want to concatenate all audio chunks into a single audio file which I can download.

I have already tried concateBlob.js but couldn’t achieve what I want, it did combine all audio files and works fine when I play it in the browwer but when I download the audio file and play the audio, only the first audio chunk is played even though size of the concatenated file is correct.

I believe it has to do something with the header of final blob as explained in this thread
but it only talks about modifying headers of wav files. Kindly help me sort this out

P.S. I want to do this concatentaion in the browser, not on the backend

DYNAMIC CSS CLASS WITH JAVASCRIPT AND PHP

I created popup box using html and javascript its work properly but i want to make dynamic using php.

I provide form to user then user fill data of popup as well as he can change some property of css so that can change background color etc.
i tried my code look`s oky but the popup box not shown

this popup before user changing

First mydatabase contain 2 column

| id  | css_class |
| 1   | .popup1   |
| 3   | .popup2   |

my javascript code is

<script type="text/javascript">
    var mycss = "none"
    var mychange = "block"

    window.addEventListener("load", function(){
        setTimeout(
          function open(event){
              document.querySelector("<?=$class?>").style.display = mychange;

          },
         1000 
          )
    });

    document.querySelector("#close").addEventListener("click", function(){
        document.querySelector("<?=$class?>").style.display = mycss;
        var mychange = mycss

    });
</script>

PHP SCRIPT

<?php
        //function of getAll
function getAll($tableName){
    global  $con;
    $table = sanitize($tableName);
    $query = "SELECT * FROM $table";
    $result = mysqli_query($con,$query);

    return $result;
}    


$popup = getAll('popup_message');

foreach ($popup as $popupData) {
    $class = $popupData['Ccss_class'];
}

?>

css style

.popupred{
    background-color: #f00;
    width: 100%;
    padding: 30px 40px;
    position: absolute;
    transform: translate(-50%,-50%);
    left: 50%;
    top: 50%;
    border-radius: 8px;
    font-family: "Poppins",sans-serif;
    display: none;
    text-align: center;
    color: white;
    z-index: 1111;
}
.popupblue{
    background-color: #00f;
    width: 100%;
    padding: 30px 40px;
    position: absolute;
    transform: translate(-50%,-50%);
    left: 50%;
    top: 50%;
    border-radius: 8px;
    font-family: "Poppins",sans-serif;
    display: none;
    text-align: center;
    color: white;
    z-index: 1111;
}

Apache superset opening two URLs with javascript in deck.gl

I need to open two URLs from Deck.gl. I am able to open with windows.open. But the thing is I need to pass dynamic paramters based on clicked point.

Below is my code and it opens first and second link, not the third. Any help would be greatly appreciated.

d => “https://latsuperset1.asia.abi.dyn.nesc.nokia.net/superset/dashboard/203/?sitename=” + d.object.extraProps.sitename + “&circle_name=” + d.object.extraProps.circle_name
window.open(“https://www.google.com/”);
e => “https://latsuperset1.asia.abi.dyn.nesc.nokia.net/superset/dashboard/199/,sitename=” + e.object.extraProps.sitename

One day difference in Converting Gregorian to Hijri date using Intl.DateTimeFormat

I am trying to convert Gregorian to Hijri date using Intl.DateTimeFormat, But every time it converts one day ahead. For example today is 11 Ramadan but every time it results in 12 Ramadan.

I have tried all calendar types “islamic, islamic-umalqura, islamic-civil, islamic-rgsa” I have also tried to change locale “PK, IN, AF, SA” but no difference. Is that a bug or I am doing something wrong.

console.log(new Intl.DateTimeFormat('en-PK-u-ca-islamic', {day: 'numeric', month: 'long',weekday: 'long',year : 'numeric'}).format(Date.now()))

struture HTML form to create a array of objects using form data

hello I have a HTML form that’s using the react form action using form data.

When extracting formData from my method its shows likes:

enter image description here

what im trying to achieve or my expectation is that I would get an array of objects:


  "completeSuccessIndicators": [
    {
    "si": 1,
    "actual_accomplishment": "this the acutal accomplishmentsasdfasdfas",
    "ql_qn": 1,
    "timeliness": 3,
    "average": 3,
    "remarks": "asdfasdf"
    },
    {
    "si": 2,
    "actual_accomplishment": "this the acutal 2222123123s",
    "ql_qn": 1,
    "timeliness": 3,
    "average": 3,
    "remarks": "another remarks"
    }
  ]

is there away for it to be automatic like PHP or Ruby on rails? or is there a package that I could use? as of right now I’m thinking of creating a logic to parse form data.

PS: I’m using nextjs for my react project.

Client Component Not re-rendered after pushed with a new query string

I am trying to create a ranking table that shows the fetched data with query string in url. The client component(Rankingtable.js) is not re-rendered by router.push. The client component shows the correct data on refreshing page.
How should I fix this issue?
I am trying to keep the page.js SSR.

page.js

export default async function Ranking({ params, searchParams }) {
  return (
    <>
      <RankingTable searchParams={searchParams} />
      <Pagination />
    </>
  );
}

RankingTable.js

"use client"
export default function RankingTable({ searchParams }) {
  const [rankingData, setRankingData] = useState(null);
  const [page, setPage] = useState(searchParams["page"]);
  const theme = useTheme();
  const isMobile = useMediaQuery(theme.breakpoints.down("sm"));

  let date = searchParams["date"];
  const world_name = searchParams["world_name"];
  const world_type = searchParams["world_type"];
  const className = searchParams["class"];
  const character_name = searchParams["character_name"];

  useEffect(() => {
    const fetchData = async () => {
      if (character_name) {
        const url = new URL(
          `${process.env.NEXT_PUBLIC_API_HOST}/api/getRanking/overall`
        );

        const queryParams = {
          date,
          world_name,
          world_type,
          class: className,
          character_name,
          page,
        };

        Object.keys(queryParams).forEach(
          (key) =>
            queryParams[key] !== null &&
            queryParams[key] !== undefined &&
            url.searchParams.append(key, queryParams[key])
        );

        const fetchByCharacterName = await fetch(url.toString());
        const characterRankingData = await fetchByCharacterName.json();
        const characterRanking = characterRankingData.ranking[0].ranking;
        const characterRankingPage = Math.floor(characterRanking / 200 + 1);
        setPage(characterRankingPage);
      }

      const url = new URL(
        `${process.env.NEXT_PUBLIC_API_HOST}/api/getRanking/overall`
      );

      const queryParams = {
        date,
        world_name,
        world_type,
        class: className,
        page,
      };

      Object.keys(queryParams).forEach(
        (key) =>
          queryParams[key] !== null &&
          queryParams[key] !== undefined &&
          url.searchParams.append(key, queryParams[key])
      );

      const response = await fetch(url.toString());
      const data = await response.json();
      setRankingData(data);
    };

    fetchData();
  }, [character_name, date, world_name, world_type, className, page]);

  if (!rankingData) {
    return <div>Loading..</div>;
  }

  return (
    <>
      {isMobile ? (
        <MobileTable rankingData={rankingData} characterName={character_name} />
      ) : (
        <PcTable rankingData={rankingData} characterName={character_name} />
      )}
    </>
  );
}

pagination.js

"use client"
export default function Pagination() {
  const router = useRouter();
  const pathname = usePathname();
  const searchParams = useSearchParams();

  const page = searchParams.get("page") || 1;

  const createQueryString = useCallback(
    (name, value) => {
      const params = new URLSearchParams(searchParams);
      params.set(name, value);

      return params.toString();
    },
    [searchParams]
  );

  return (
    <>
      <Button
        onClick={() =>
          router.push(
            pathname + "?" + createQueryString("page", parseInt(page) + 1)
          )
        }
      >
        Next
      </Button>
    </>
  );
}

Step indicator in React Native

I’m using react-native-step-indicator in my project and encountering a few difficulties. Firstly, I couldn’t find a way to add descriptions; currently, I can only add titles.

Secondly, why is only the first title positioned behind the indicator? I want all titles to be positioned behind the indicator, not just the first one.

enter image description here

Here’s the code I’m using:

    <View style={{ height: '60%' }}>
          <StepIndicator
            customStyles={styles.customStyles}
            currentPosition={activePosition}
            direction="vertical"
            labels={getStepsData?.getSteps?.map((step) => step.name?.en)}
            onPress={(position) => setActivePosition(position)}
          />

And here’s the style:

   customStyles: {
        stepIndicatorSize: 30,
        currentStepIndicatorSize: 40,
        separatorStrokeWidth: 3,
        currentStepStrokeWidth: 5,
        stepStrokeCurrentColor: Colors.DeepGreen,
        separatorFinishedColor: Colors.DeepGreen,
        separatorUnFinishedColor: Colors.gray,
        stepIndicatorFinishedColor: Colors.DeepGreen,
        stepIndicatorUnFinishedColor: Colors.gray,
        stepIndicatorCurrentColor: Colors.white,
        stepIndicatorLabelFontSize: 15,
        currentStepIndicatorLabelFontSize: 15,
        stepIndicatorLabelCurrentColor: '#000000',
        stepIndicatorLabelFinishedColor: Colors.white,
        stepIndicatorLabelUnFinishedColor: Colors.white,
        labelColor: Colors.DarkSlate,
        labelSize: 15,
        currentStepLabelColor: Colors.DeepGreen,
    },

How can I get the WindowClient id of the current window?

From inside a service worker, I can do await clients.matchAll({includeUncontrolled: true}) to get a list of the current windows that the service worker can control and communicate with. For example, when I do that and I have 2 windows opened, I get an array with 2 WindowClient objects that looks something like this:

WindowClient {visibilityState: 'visible', focused: true, url: 'http://localhost:3000/', id: 'f56e10ac-6a7c-44ca-8322-11165a45eb4b', type: 'window'}
WindowClient {visibilityState: 'hidden', focused: false, url: 'http://localhost:3000/', id: 'b1be5170-8e98-4927-a53b-48c4752a82f1', type: 'window'}

It is noteworthy that each window has an id there. Now, my question is, from code that runs inside a window, is it possible to somehow get hold of that id?

How to do I add my data to LocalStorage with createdElements and display them?

I’m fairly new to JS and I just finished creating a budget/finance tracker and I wanted to be able to save the data so it doesn’t disappear when I refresh the page using localStorage. How would I go about doing so? I’ve never used LocalStorage before so i wanted some help on how to add it to my code. I’ve tried to play around with localStorage but I just couldn’t understand how it works. All I know are localStorage.setItem(key, value) to save the key/value pair and localStorage.getItem(Key) to call it but I don’t fully understand how to really use them.

HTML

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script src="https://kit.fontawesome.com/0cd8470e78.js" crossorigin="anonymous"></script>
    <link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=NTR&display=swap" rel="stylesheet">
    <link rel="stylesheet" href="finance.css">
    <title>Document</title>
</head>
<body>
    
    <div id="container">
        <h1 class="title">Finance Tracker</h1>

        <!-- Finance Box -->
        <div class="finance_box">


            <!-- Income -->
            <div class="finance_div income_div">
                <div>
                    <input type="text" id="income" placeholder="Income...">
                    <input type="number" id="income_amount" placeholder="Amount...">
                </div>

                <button class="add_finance" id="add_income" data-add="income">Add</button>
            </div>


            <!-- Expense -->
            <div class="finance_div expense_div">
                <div>
                    <input type="text" id="expense" placeholder="Expense...">
                    <input type="number" id="expense_amount" placeholder="Amount...">
                </div>

                <button class="add_finance" id="add_expense" data-add="expense">Add</button>
            </div>


            <!-- Investment -->
            <div class="finance_div investment_div">
                <div>
                    <input type="text" id="investment" placeholder="Investment...">
                    <input type="number" id="investment_amount" placeholder="Amount...">
                </div>

                <button class="add_finance" id="add_investment" data-add="investment">Add</button>
            </div>
        </div>
        <!-- Finance Box -->


        <!-- Tracker Box -->
        <div class="tracker_box">
            <div class="headers">
               <h1 class="tracker_titles">Income</h1>
               <h1 class="tracker_titles">Expense</h1>
               <h1 class="tracker_titles">Investment</h1>
            </div>

            <div class="content_box">
                <!-- Box type = income -->
                <div class="tracked_div" id="inc" data-boxtype="income">
                    <!-- <div class="tracked">

                        <input type="text" placeholder="Testing" class="track_name">
                        <input type="number" placeholder="123" class="track_amount">

                        <div class="btn_div">
                            <button class="edit_item edit"><i class="fa-solid fa-pen-to-square"></i></button>

                            <button class="check_item check"><i class="fa-solid fa-check"></i></button>

                            <button class="delete_item delete"><i class="fa-solid fa-trash"></i></button>
                        </div>

                    </div> -->
                </div>

                <!-- Box type = expense -->
                <div class="tracked_div" id="exp" data-boxtype="expense">
                    
                </div>
                
                <!-- Box type = investments -->
                <div class="tracked_div" id="invest" data-boxtype="investment">

                </div>
            </div>

        </div>
        <!-- Tracker Box -->


        <!-- Total Box -->
        <div class="total_box">
            <div class="totals">
                <div class="income_total_div">
                    <h1 class="currency"></h1>
                    <h1 id="income_total"></h1>
                </div>
                <div class="expense_total_div">
                    <h1 class="currency"></h1>
                    <h1 id="expense_total"></h1>
                </div>
                <div class="investment_total_div">
                    <h1 class="currency"></h1>
                    <h1 id="investment_total"></h1>
                </div>
            </div>

            <div class="net_total_box">
                <h1>Net Total</h1>
                <h1 id="net_total"></h1>
            </div>
        </div>
        <!-- Total box -->
    </div>

    <script src="finance.js"></script>
    <!-- <script src="dummy.js"></script> -->
</body>
</html>

CSS

* {
    margin: 0;
    padding: 0;
    font-family: "NTR", sans-serif;
    font-family: "Madimi One", sans-serif;
}

body {
    background: #161A30;
    color: white;
}

#container {
    width: 100vw;
    height: 100vh;
    display: flex;
    flex-direction: column;
    justify-content: space-between;
}

#expense_tracker {
    border-left: 1px solid black;
    border-right: 1px solid black;
}

#net_total {
    color: #36abab;
}

#income_total {
    display: flex;
    justify-content: center;
    align-items: center;
    font-size: 28px;
    color: #00af75;
}

#expense_total {
    display: flex;
    justify-content: center;
    align-items: center;
    font-size: 28px;
    color: #e13056;
}

#investment_total {
    display: flex;
    justify-content: center;
    align-items: center;
    font-size: 28px;
    color: #F2F597;
}

body::-webkit-scrollbar {
    display: none;
}

.edit_item,
.delete_item,
.check_item {
    padding: 0.5rem;
}

.title {
    width: 100%;
    height: 8vh;
    font-size: 40px;
    display: flex;
    justify-content: center;
    align-items: center;
}

.finance_box {
    width: 100%;
    height: 10vh;
    display: flex;
    justify-content: space-around;
    align-items: center;
    margin-bottom: 1rem;
}

.finance_div {
    width: 100%;
    height: 100%;
    display: flex;
    flex-direction: column;
    justify-content: space-around;
    align-items: center;
}

.finance_div div {
    width: 100%;
    display: flex;
    justify-content: space-around;
    align-items: center;
}

.finance_div input {
    width: 40%;
    border: none;
    outline: none;
    border-radius: 1px;
    background-color: #B6BBC4;
    font-size: 16px;
    padding: 0.5rem 1rem;
    text-align: center;;
}

.finance_div input::placeholder {
    color: #0000002d;
}

.finance_div input:focus {
    background-color: #ebf1fc;
}

.add_finance { 
    border: none;
    outline: none;
    border-radius: 1rem;
    background: #F0ECE5;
    padding: 0.3rem 2rem;
    font-size: 22px;
    letter-spacing: 3px;
   transition: 0.1s ease-in-out;
}

.add_finance:hover {
    cursor: pointer;
    color: white;
    background-color: #57c270;
}

.tracker_box {
    height: 66vh;
    min-height: 60vh;
    max-height: 66vh;
    display: flex;
    flex-direction: column;
}

.headers {
    width: 100%;
    height: 5%;
    margin-bottom: 1rem;
    display: flex;
    justify-content: space-around;
    align-items: center;
}

.content_box {
    width: 100%;
    height: 90%;
    display: flex;
    justify-content: space-around;
}

.tracked_div {
    width: 100%;
    height: 100%;
    background-color: #B6BBC4;
    border-top: 1px solid black;
    overflow-y: scroll;
}

.tracked_div:nth-child(2) {
    border-left: 1px solid black;
    border-right: 1px solid black;
}

.tracked_div::-webkit-scrollbar {
    display: none;
  }

.tracked {
    width: 100%;
    height: 5vh;
    display: flex;
    justify-content: space-between;
    font-size: 18px;
   
}

.track_name {
   width: 40%;
   height: 100%;
   color: rgb(0, 0, 0);
   text-align: center;
   font-size: 18px;
   background: transparent;
   border: none;
   outline: none;
   padding: 0 0.3rem;
}

.track_amount {
    width: 35%;
    height: 100%;
    color: black;
    padding: 0 0.2rem;
    border: none;
    outline: none;
    text-align: center;
    font-size: 18px;
    background: transparent;
}

.edit_item,
.delete_item,
.check_item {
   border: none;
   cursor: pointer;
   background: transparent;
   font-size: 18px;
}

.check_item {
    display: none;
}

.active {
    display: block;
}

.non-active {
    display: none;
}


.edit_item:hover {
    color: rgb(3, 204, 3);
}

.check_item:hover {
    color: rgb(3, 204, 3);
}

.delete_item:hover {
    color: red;
}

.btn_div {
    width: 20%;
    height: 100%;
    display: flex;
    justify-content: space-around;
    align-items: center;
}

.total_box {
    width: 100%;
    height: 15vh;
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    align-items: center;
}

.totals {
    width: 100%;
    height: 25%;
    display: flex;
    justify-content: space-around;
    align-items: center;;
}

.income_total_div, 
.expense_total_div,
.investment_total_div {
    display: flex;
}

.net_total_box {
    width: 100%;
    height: 70%;
    display: flex;
    flex-direction: column;
    justify-content: center; 
    align-items: center;
}

.net_total_box h1:nth-child(1) {
    font-size: 28px;
}


input::-webkit-outer-spin-button,
input::-webkit-inner-spin-button {
  -webkit-appearance: none;
   margin: 0;
}

.currency {
    display: flex;
    justify-content: center;
    align-items: center;
    font-size: 25px;
    margin-right: 0.2rem;
}


JavaScript

const incomeName = document.querySelector("#income");
const incomeAmount = document.querySelector("#income_amount");

const expenseName = document.querySelector("#expense");
const expenseAmount = document.querySelector("#expense_amount");

const investName = document.querySelector("#investment");
const investAmount = document.querySelector("#investment_amount");

// Add buttons
const addInfo = document.querySelectorAll(".add_finance");

// parent div of each category
let incomeContainer = document.querySelector('#inc');
const expenseContainer = document.querySelector('#exp');
const investContainer = document.querySelector('#invest');


// Total Counter
let incomeTotal = document.querySelector('#income_total');
let incCounter = 0;

let expenseTotal = document.querySelector('#expense_total');
let expCounter = 0;

let investTotal = document.querySelector('#investment_total');
let investCounter = 0;

// Net Total
let netTotal = document.querySelector('#net_total');


function userInput() {
    addInfo.forEach(btn => {
        btn.addEventListener('click', (e) => {
            let data = e.currentTarget.dataset.add;

            if (data === "income") {
                addIncome();
                netWorth();
            };
            
            if (data === "expense") {
                addExpense();
                netWorth()
            };
            
            if (data === "investment") {
                addInvest();
            };
        })
    })

}



function addIncome() {
        if (incomeName.value !== "" && incomeAmount.value !== "") {
        let trackedDiv = document.createElement('div');
        let inputName = document.createElement('input');
        let inputAmount = document.createElement('input');
        let btnDiv = document.createElement('div');
        let editBtn = document.createElement('button');
        let checkBtn = document.createElement('button');
        let deleteBtn = document.createElement('button');

        trackedDiv.classList.add('tracked');
        inputName.classList.add('track_name');
        inputName.type = "text";
        inputAmount.classList.add('track_amount');
        inputAmount.type = "number";
        btnDiv.classList.add('btn_div');
        editBtn.classList.add('edit_item');
        checkBtn.classList.add('check_item');
        deleteBtn.classList.add('delete_item');

        editBtn.innerHTML = `<i class="fa-solid fa-pen-to-square"></i>`;
        checkBtn.innerHTML = `<i class="fa-solid fa-check"></i>`;
        deleteBtn.innerHTML = `<i class="fa-solid fa-trash"></i>`;

        inputName.disabled = "disabled";
        inputAmount.disabled = "disabled";

        inputName.value = incomeName.value;
        inputAmount.value = incomeAmount.value;

        incCounter += parseFloat(inputAmount.value);

        let convertedIncome = new Intl.NumberFormat('en-US', {style: "currency", currency: "USD", minimumFractionDigits: 0, maximumFractionDigits: 2}).format(incCounter);

        incomeTotal.innerText = convertedIncome;
        
        trackedDiv.appendChild(inputName);
        trackedDiv.appendChild(inputAmount);
        btnDiv.appendChild(editBtn);
        btnDiv.appendChild(checkBtn);
        btnDiv.appendChild(deleteBtn);
        trackedDiv.appendChild(btnDiv);
        incomeContainer.appendChild(trackedDiv); 

        incomeName.value = "";
        incomeAmount.value = "";  



        editBtn.addEventListener('click', () => {
            editBtn.style.display = "none";
            checkBtn.style.display = "inline-block";
            deleteBtn.style.display = "none";

            inputName.style.borderBottom = "thin solid black";
            inputAmount.style.borderBottom = "thin solid black";

            incCounter -= inputAmount.value;
            let convertedIncome = new Intl.NumberFormat('en-US', {style: "currency", currency: "USD", minimumFractionDigits: 0, maximumFractionDigits: 0}).format(incCounter);

            incomeTotal.innerText = convertedIncome;

            inputName.disabled = false;
            inputAmount.disabled = false;
        })

        checkBtn.addEventListener('click', () => {

            if (inputName.value === "" || inputAmount.value === "") {
                alert("Missing Information!");
            } else {
                checkBtn.style.display = "none";
                editBtn.style.display = "inline-block";
                deleteBtn.style.display = "inline-block";

                inputName.style.borderBottomStyle = "none";
                inputAmount.style.borderBottomStyle = "none";
    
                incCounter += parseInt(inputAmount.value);

                let convertedIncome = new Intl.NumberFormat('en-US', {style: "currency", currency: "USD", minimumFractionDigits: 0, maximumFractionDigits: 0}).format(incCounter);

                incomeTotal.innerText = convertedIncome;
    
                inputName.disabled = "disabled";
                inputAmount.disabled = "disabled";
            }
        })

        
        deleteBtn.addEventListener('click', (e) => {
            let targetParent = e.currentTarget.closest(".tracked");

            incCounter -= inputAmount.value;
            let convertedIncome = new Intl.NumberFormat('en-US', {style: "currency", currency: "USD", minimumFractionDigits: 0, maximumFractionDigits: 0}).format(incCounter);
            incomeTotal.innerText = convertedIncome;

            netWorth();
            incomeContainer.removeChild(targetParent);
        })

    } else {
        alert("Missing Income Info!");
    }
}   

function addExpense() {
    if (expenseName.value !== "" && expenseAmount.value !== "") {
    let trackedDiv = document.createElement('div');
    let inputName = document.createElement('input');
    let inputAmount = document.createElement('input');
    let btnDiv = document.createElement('div');
    let editBtn = document.createElement('button');
    let checkBtn = document.createElement('button');
    let deleteBtn = document.createElement('button');

    trackedDiv.classList.add('tracked');
    inputName.classList.add('track_name');
    inputName.type = "text";
    inputAmount.classList.add('track_amount');
    inputAmount.type = "number";
    btnDiv.classList.add('btn_div');
    editBtn.classList.add('edit_item');
    checkBtn.classList.add('check_item');
    deleteBtn.classList.add('delete_item');

    editBtn.innerHTML = `<i class="fa-solid fa-pen-to-square"></i>`;
    checkBtn.innerHTML = `<i class="fa-solid fa-check"></i>`;
    deleteBtn.innerHTML = `<i class="fa-solid fa-trash"></i>`;

    inputName.value = expenseName.value;
    inputAmount.value = expenseAmount.value;
    
    
    expCounter += parseInt(inputAmount.value);

    let convertedExpense = new Intl.NumberFormat('en-US', {style: "currency", currency: "USD", minimumFractionDigits: 0, maximumFractionDigits: 0}).format(expCounter);

    expenseTotal.innerText = convertedExpense;
    
    trackedDiv.appendChild(inputName);
    trackedDiv.appendChild(inputAmount);
    btnDiv.appendChild(editBtn);
    btnDiv.appendChild(checkBtn);
    btnDiv.appendChild(deleteBtn);
    trackedDiv.appendChild(btnDiv);
    expenseContainer.appendChild(trackedDiv);
    
    expenseName.value = "";
    expenseAmount.value = "";   
    
    
    editBtn.addEventListener('click', () => {
            editBtn.style.display = "none";
            checkBtn.style.display = "inline-block";
            deleteBtn.style.display = "none";
    
            inputName.style.borderBottomStyle = "solid";
            inputAmount.style.borderBottomStyle = "solid";
    
            expCounter -= inputAmount.value;
            
    let convertedExpense = new Intl.NumberFormat('en-US', {style: "currency", currency: "USD", minimumFractionDigits: 0, maximumFractionDigits: 0}).format(expCounter);

    expenseTotal.innerText = convertedExpense;
    
            inputName.disabled = false;
            inputAmount.disabled = false;
        })
    
    checkBtn.addEventListener('click', () => {
    
            if (inputName.value === "" || inputAmount.value === "") {
                alert("Missing Information!");
            } else {
                checkBtn.style.display = "none";
                editBtn.style.display = "inline-block";
                deleteBtn.style.display = "inline-block";
    
                inputName.style.borderBottomStyle = "none";
                inputAmount.style.borderBottomStyle = "none";
    
                expCounter += parseInt(inputAmount.value);
                
                let convertedExpense = new Intl.NumberFormat('en-US', {style: "currency", currency: "USD", minimumFractionDigits: 0, maximumFractionDigits: 0}).format(expCounter);

                expenseTotal.innerText = convertedExpense;
    
                inputName.disabled = "disabled";
                inputAmount.disabled = "disabled";
            }
        })
    
        
    deleteBtn.addEventListener('click', (e) => {
            let targetParent = e.currentTarget.closest(".tracked");
            expCounter -= inputAmount.value;
            
            let convertedExpense = new Intl.NumberFormat('en-US', {style: "currency", currency: "USD", minimumFractionDigits: 0, maximumFractionDigits: 0}).format(expCounter);

            expenseTotal.innerText = convertedExpense;
    
            netWorth();
            expenseContainer.removeChild(targetParent);
        }) 
    } else {
        alert("Missing Expense Info!");
    };
}

function addInvest() {
    if (investName.value !== "" && investAmount.value !== "") {
    let trackedDiv = document.createElement('div');
    let inputName = document.createElement('input');
    let inputAmount = document.createElement('input');
    let btnDiv = document.createElement('div');
    let editBtn = document.createElement('button');
    let checkBtn = document.createElement('button');
    let deleteBtn = document.createElement('button');

    trackedDiv.classList.add('tracked');
    inputName.classList.add('track_name');
    inputName.type = "text";
    inputAmount.classList.add('track_amount');
    inputAmount.type = "number";
    btnDiv.classList.add('btn_div');
    editBtn.classList.add('edit_item');
    checkBtn.classList.add('check_item');
    deleteBtn.classList.add('delete_item');

    editBtn.innerHTML = `<i class="fa-solid fa-pen-to-square"></i>`;
    checkBtn.innerHTML = `<i class="fa-solid fa-check"></i>`;
    deleteBtn.innerHTML = `<i class="fa-solid fa-trash"></i>`;

    inputName.value = investName.value;
    inputAmount.value = investAmount.value;

    investCounter += parseInt(inputAmount.value);

    let convertedInvestment = new Intl.NumberFormat('en-US', {style: "currency", currency: "USD", minimumFractionDigits: 0, maximumFractionDigits: 0}).format(investCounter);

    investTotal.innerText = convertedInvestment;



    trackedDiv.appendChild(inputName);
    trackedDiv.appendChild(inputAmount);
    btnDiv.appendChild(editBtn);
    btnDiv.appendChild(checkBtn);
    btnDiv.appendChild(deleteBtn);
    trackedDiv.appendChild(btnDiv);
    investContainer.appendChild(trackedDiv);

    investName.value = "";
    investAmount.value = "";

    editBtn.addEventListener('click', () => {
        editBtn.style.display = "none";
        checkBtn.style.display = "inline-block";
        deleteBtn.style.display = "none";

        inputName.style.borderBottomStyle = "solid";
        inputAmount.style.borderBottomStyle = "solid";

        investCounter -= inputAmount.value;
        let convertedInvestment = new Intl.NumberFormat('en-US', {style: "currency", currency: "USD", minimumFractionDigits: 0, maximumFractionDigits: 0}).format(investCounter);

    investTotal.innerText = convertedInvestment;

        inputName.disabled = false;
        inputAmount.disabled = false;
    })

    checkBtn.addEventListener('click', () => {

        if (inputName.value === "" && inputAmount.value === "") {
            alert("Missing investment Information!");
        } else {
            checkBtn.style.display = "none";
            editBtn.style.display = "inline-block";
            deleteBtn.style.display = "inline-block";

            inputName.style.borderBottomStyle = "none";
            inputAmount.style.borderBottomStyle = "none";

            investCounter += parseInt(inputAmount.value);
            let convertedInvestment = new Intl.NumberFormat('en-US', {style: "currency", currency: "USD", minimumFractionDigits: 0, maximumFractionDigits: 0}).format(investCounter);

    investTotal.innerText = convertedInvestment;

            inputName.disabled = "disabled";
            inputAmount.disabled = "disabled";
        }
    })

    
    deleteBtn.addEventListener('click', (e) => {
        let targetParent = e.currentTarget.closest(".tracked");
        investCounter -= inputAmount.value;

        let convertedInvestment = new Intl.NumberFormat('en-US', {style: "currency", currency: "USD", minimumFractionDigits: 0, maximumFractionDigits: 0}).format(investCounter);

        investTotal.innerText = convertedInvestment;
        investContainer.removeChild(targetParent);
    }) 
} else {
    alert("Missing Investment Info!");
}
}

function netWorth() {

    let sum = incCounter - expCounter;
  

    let newSum = new Intl.NumberFormat("en-US", {style: "currency", currency: "USD", minimumFractionDigits: 0, maximumFractionDigits: 0}).format(sum);

    netTotal.innerText = newSum;

}

netWorth();
userInput();

Payout start date, payout end date and payout date is incorrect

I am trying to get payout start date, payout end date and payout date from current date and time in Indian standard time (IST). If today is 22nd march in IST timezone then , my payout start date to be 17 March , payout end date to be 23 march and payout date to be 29 March. I wrote a function to get this done. But it gives me incorrect dates
my payout date comes as 22nd Mar, payout start date as 10 march, payout end date as 16 march

  dayIndex = 5;
  function nextDate(dayIndex) {
    var today = new Date();
    today.setDate(
      today.getDate() +
        ((dayIndex -
          1 -
          today.getDay() +
          7) %
          7) +
        1
    );
    return today;
  }
  console.log(
    nextDate(dayIndex).valueOf()
 );
  onHoldUntil =
    nextDate(dayIndex)
      .setHours(11 + 5, 30, 0, 0)
      .valueOf() / 1000;

  console.log(
    "Next Friday Pay date is : "
  );
  console.log(
    nextDate(dayIndex)
      .setHours(11 + 5, 30, 0, 0)
      .valueOf()
); //11 am + 5.30 for IST
//unix to date conversion
var date = new Date(onHoldUntil * 1000); // to datetime format so taht paycycle can be fetched and also pay date
console.log("date value is ", date);
payoutDate =  date.toISOString().substring(0,10) ;
console.log("Payout Date is : " , payoutDate);   

console.log(date);
payCycleStart = new Date(date.getFullYear(), date.getMonth(), date.getDate() - date.getDay() - 7).toISOString().slice(0,10);
payCycleEnd = new Date(date.getFullYear(), date.getMonth(), date.getDate() - date.getDay() - 1).toISOString().slice(0,10);

How to get a media stream of the speaker’s output to transfer it over the network to microsoft cognitive services for real time speech to text

The difficulty seems to be in accessing the speaker out, not in actual JS Speech SDK code.
If I can somehow wrangle the speaker out into a MediaStream, then I can then use the code AudioConfig.fromStreamInput(myMediaStream); to set up input for audio transcription.

I have found something related How to get a media stream of the speaker’s output to transfer it over the network or record it?

The accepted solution returns an error along the line of speaker.addTrack(stream.getAudioTracks()[0].clone());”Cannot read properties of undefined (reading ‘clone’)”

Below is my implementation

 const getAudioStream = async () => {
    const speaker = new MediaStream;
    if (navigator.getDisplayMedia) {
        navigator.getDisplayMedia({
            video: true ,
            audio: true
        }).then(stream => {
            speaker.addTrack(stream.getAudioTracks()[0].clone());
            // stopping and removing the video track to enhance the performance
            stream.getVideoTracks()[0].stop();
            stream.removeTrack(stream.getVideoTracks()[0]);
        }).catch((error) => {
            console.log(error);
        });
    } else if (navigator.mediaDevices.getDisplayMedia) {
        navigator.mediaDevices.getDisplayMedia({
            video: true ,
            audio: true
        }).then(stream => {
            speaker.addTrack(stream.getAudioTracks()[0].clone());
            // stopping and removing the video track to enhance the performance
            stream.getVideoTracks()[0].stop();
            stream.removeTrack(stream.getVideoTracks()[0]);
        }).catch((error) => {
            console.log(error);
        });
    }
   return speaker;
}

useEffect(() => { const startStreaming = async () => { const speaker = await getAudioStream(); const audioConfig = AudioConfig.fromStreamInput(speaker); speechrecognizer.audioConfig = audioConfig; } startStreaming(); }, []);

I have implemented a hook in past projects that records the streams from both speaker and mic

import { useEffect, useRef, useState } from 'react';

export const useAudioRecorder = () => { const [isRecording, setIsRecording] = useState(false); const [audioBlob, setAudioBlob] = useState(null); const mediaRecorder = useRef(null); const audioStream = useRef(null);

const startRecording = async () => { try { const microphoneStream = await navigator.mediaDevices.getUserMedia({ audio: true }); const speakerStream = await       navigator.mediaDevices.getUserMedia({ audio: { echoCancellation: false } });
  const audioContext = new AudioContext();
  const microphoneSource = audioContext.createMediaStreamSource(microphoneStream);
  const speakerSource = audioContext.createMediaStreamSource(speakerStream);
  const mixedOutput = audioContext.createMediaStreamDestination();

  microphoneSource.connect(mixedOutput);
  speakerSource.connect(mixedOutput);

  audioStream.current = mixedOutput.stream;
  mediaRecorder.current = new MediaRecorder(audioStream.current);
  
  mediaRecorder.current.ondataavailable = handleDataAvailable;
  mediaRecorder.current.start();
  
  setIsRecording(true);
} catch (error) {
  console.error('Error starting recording:', error);
}
};

const stopRecording = () => { if (mediaRecorder.current && isRecording) { mediaRecorder.current.stop(); setIsRecording(false); } };

const handleDataAvailable = (event) => { const audioBlob = new Blob([event.data], { type: 'audio/wav' }); setAudioBlob(audioBlob); };

useEffect(() => () => { // Clean up the streams when the component unmounts if (audioStream.current) { audioStream.current.getTracks().forEach(track => track.stop()); } }, []);

return { isRecording, audioBlob, startRecording, stopRecording }; };

Tried to use similar approach in my getAudioStream function, but it only gets mic’s but not speaker’s

Calling a url in chrome browser or in postman working fine but using axios it is giving 404 error

i have a url and when i called that url using browsers and postman it is working fine but using axios it is throwing 404 error,i will be grateful if someone help me out to clear this error

iam giving the snippet of code where iam facing problem

let response = await axios.get(`https://scholar.google.co.in/citations?user=sGJSZ1AAAAAJ&hl=en&cstart=0&pagesize=1000`, {
    headers: {
      "User-Agent":
        "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36",
    },
  });

i checked whether url is correct or not then i found that there is no mistake in url then i added the user-agent header but no use

How to get [^;]+ effect (performance) but with a sequence

I want to obtain the performant effect of [^;]+ but using an excluded sequence.
If you compare these two,

[^;]+

.*?;

string: tatshdicndatsbba;

the first one is faster(especially evident on bigger strings). That is the advantage. The former takes everything speedly except ; while the latter is progressive, so slower.

If we have this
string: tatshdi;cndatsbba;&djs

that first regex doesnt work.
I would like to know how I could obtain the same performant effect with an excluded sequence instead of a single character (;)
Something like [^(;&)]+ (I know it excludes ; AND &, but lets say it is a new invented syntax for the sake of the explaination)

So when it meets a ; it shoukd check if it is followed by &. If not, match it and continue. The trick is to obtain the same performant effect as the first regex I indicated